mirror of
https://github.com/verilator/verilator.git
synced 2025-04-16 01:26:54 +00:00
Suppress creating change_request if not needed.
This commit is contained in:
parent
fc25721e55
commit
13933743ad
@ -9155,6 +9155,7 @@ private:
|
||||
AstExecGraph* m_execGraphp = nullptr; // Execution MTask graph for threads>1 mode
|
||||
VTimescale m_timeunit; // Global time unit
|
||||
VTimescale m_timeprecision; // Global time precision
|
||||
bool m_changeRequest = false; // Have _change_request method
|
||||
bool m_timescaleSpecified = false; // Input HDL specified timescale
|
||||
public:
|
||||
AstNetlist();
|
||||
@ -9178,6 +9179,8 @@ public:
|
||||
AstNode* miscsp() const { return op3p(); } // op3 = List of dtypes etc
|
||||
void addMiscsp(AstNode* nodep) { addOp3p(nodep); }
|
||||
AstTypeTable* typeTablep() { return m_typeTablep; }
|
||||
void changeRequest(bool specified) { m_changeRequest = specified; }
|
||||
bool changeRequest() const { return m_changeRequest; }
|
||||
AstConstPool* constPoolp() { return m_constPoolp; }
|
||||
AstPackage* dollarUnitPkgp() const { return m_dollarUnitPkgp; }
|
||||
AstPackage* dollarUnitPkgAddp() {
|
||||
|
@ -47,11 +47,33 @@ public:
|
||||
AstCFunc* m_tlChgFuncp = nullptr; // Top level change function we're building
|
||||
int m_numStmts = 0; // Number of statements added to m_chgFuncp
|
||||
int m_funcNum = 0; // Number of change functions emitted
|
||||
bool m_madeTopChg = false;
|
||||
|
||||
ChangedState() = default;
|
||||
~ChangedState() = default;
|
||||
|
||||
void maybeCreateChgFuncp() {
|
||||
maybeCreateTopChg();
|
||||
maybeCreateMidChg();
|
||||
}
|
||||
void maybeCreateTopChg() {
|
||||
if (m_madeTopChg) return;
|
||||
m_madeTopChg = true;
|
||||
v3Global.rootp()->changeRequest(true);
|
||||
|
||||
// Create a wrapper change detection function that calls each change detection function
|
||||
m_tlChgFuncp
|
||||
= new AstCFunc{m_scopetopp->fileline(), "_change_request", m_scopetopp, "QData"};
|
||||
m_tlChgFuncp->isStatic(false);
|
||||
m_tlChgFuncp->isLoose(true);
|
||||
m_tlChgFuncp->declPrivate(true);
|
||||
m_scopetopp->addActivep(m_tlChgFuncp);
|
||||
// Each change detection function needs at least one AstChangeDet
|
||||
// to ensure that V3EmitC outputs the necessary code.
|
||||
maybeCreateMidChg();
|
||||
m_chgFuncp->addStmtsp(new AstChangeDet{m_scopetopp->fileline(), nullptr, nullptr, false});
|
||||
}
|
||||
void maybeCreateMidChg() {
|
||||
// Don't create an extra function call if splitting is disabled
|
||||
if (!v3Global.opt.outputSplitCFuncs()) {
|
||||
m_chgFuncp = m_tlChgFuncp;
|
||||
@ -242,24 +264,11 @@ private:
|
||||
UINFO(4, " TS " << nodep << endl);
|
||||
// Clearing
|
||||
AstNode::user1ClearTree();
|
||||
// Create the change detection function
|
||||
// Prep for if make change detection function
|
||||
AstScope* const scopep = nodep->scopep();
|
||||
UASSERT_OBJ(scopep, nodep, "No scope found on top level, perhaps you have no statements?");
|
||||
m_statep->m_scopetopp = scopep;
|
||||
|
||||
// Create a wrapper change detection function that calls each change detection function
|
||||
m_statep->m_tlChgFuncp
|
||||
= new AstCFunc{nodep->fileline(), "_change_request", scopep, "QData"};
|
||||
m_statep->m_tlChgFuncp->isStatic(false);
|
||||
m_statep->m_tlChgFuncp->isLoose(true);
|
||||
m_statep->m_tlChgFuncp->declPrivate(true);
|
||||
m_statep->m_scopetopp->addActivep(m_statep->m_tlChgFuncp);
|
||||
// Each change detection function needs at least one AstChangeDet
|
||||
// to ensure that V3EmitC outputs the necessary code.
|
||||
m_statep->maybeCreateChgFuncp();
|
||||
m_statep->m_chgFuncp->addStmtsp(
|
||||
new AstChangeDet{nodep->fileline(), nullptr, nullptr, false});
|
||||
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
|
@ -772,7 +772,7 @@ void EmitCFunc::emitChangeDet() {
|
||||
puts("QData __req = false; // Logically a bool\n"); // But not because it results in
|
||||
// faster code
|
||||
bool gotOne = false;
|
||||
for (AstChangeDet* changep : m_blkChangeDetVec) {
|
||||
for (AstChangeDet* const changep : m_blkChangeDetVec) {
|
||||
if (changep->lhsp()) {
|
||||
if (!gotOne) { // Not a clocked block
|
||||
puts("__req |= (");
|
||||
|
@ -312,8 +312,10 @@ class EmitCModel final : public EmitCFunc {
|
||||
const string topModNameProtected = prefixNameProtect(modp);
|
||||
|
||||
putsDecoration("// Evaluate till stable\n");
|
||||
puts("int __VclockLoop = 0;\n");
|
||||
puts("QData __Vchange = 1;\n");
|
||||
if (v3Global.rootp()->changeRequest()) {
|
||||
puts("int __VclockLoop = 0;\n");
|
||||
puts("QData __Vchange = 1;\n");
|
||||
}
|
||||
if (v3Global.opt.trace()) puts("vlSymsp->__Vm_activity = true;\n");
|
||||
puts("do {\n");
|
||||
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ ");
|
||||
@ -322,29 +324,34 @@ class EmitCModel final : public EmitCFunc {
|
||||
if (initial)
|
||||
puts(topModNameProtected + "__" + protect("_eval_settle") + "(&(vlSymsp->TOP));\n");
|
||||
puts(topModNameProtected + "__" + protect("_eval") + "(&(vlSymsp->TOP));\n");
|
||||
puts("if (VL_UNLIKELY(++__VclockLoop > " + cvtToStr(v3Global.opt.convergeLimit())
|
||||
+ ")) {\n");
|
||||
puts("// About to fail, so enable debug to see what's not settling.\n");
|
||||
puts("// Note you must run make with OPT=-DVL_DEBUG for debug prints.\n");
|
||||
puts("int __Vsaved_debug = Verilated::debug();\n");
|
||||
puts("Verilated::debug(1);\n");
|
||||
puts("__Vchange = " + topModNameProtected + "__" + protect("_change_request")
|
||||
+ "(&(vlSymsp->TOP));\n");
|
||||
puts("Verilated::debug(__Vsaved_debug);\n");
|
||||
puts("VL_FATAL_MT(");
|
||||
putsQuoted(protect(modp->fileline()->filename()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(modp->fileline()->lineno()));
|
||||
puts(", \"\",\n");
|
||||
puts("\"Verilated model didn't ");
|
||||
if (initial) puts("DC ");
|
||||
puts("converge\\n\"\n");
|
||||
puts("\"- See https://verilator.org/warn/DIDNOTCONVERGE\");\n");
|
||||
puts("} else {\n");
|
||||
puts("__Vchange = " + topModNameProtected + "__" + protect("_change_request")
|
||||
+ "(&(vlSymsp->TOP));\n");
|
||||
puts("}\n");
|
||||
puts("} while (VL_UNLIKELY(__Vchange));\n");
|
||||
if (v3Global.rootp()->changeRequest()) {
|
||||
puts("if (VL_UNLIKELY(++__VclockLoop > " + cvtToStr(v3Global.opt.convergeLimit())
|
||||
+ ")) {\n");
|
||||
puts("// About to fail, so enable debug to see what's not settling.\n");
|
||||
puts("// Note you must run make with OPT=-DVL_DEBUG for debug prints.\n");
|
||||
puts("int __Vsaved_debug = Verilated::debug();\n");
|
||||
puts("Verilated::debug(1);\n");
|
||||
puts("__Vchange = " + topModNameProtected + "__" + protect("_change_request")
|
||||
+ "(&(vlSymsp->TOP));\n");
|
||||
puts("Verilated::debug(__Vsaved_debug);\n");
|
||||
puts("VL_FATAL_MT(");
|
||||
putsQuoted(protect(modp->fileline()->filename()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(modp->fileline()->lineno()));
|
||||
puts(", \"\",\n");
|
||||
puts("\"Verilated model didn't ");
|
||||
if (initial) puts("DC ");
|
||||
puts("converge\\n\"\n");
|
||||
puts("\"- See https://verilator.org/warn/DIDNOTCONVERGE\");\n");
|
||||
puts("} else {\n");
|
||||
puts("__Vchange = " + topModNameProtected + "__" + protect("_change_request")
|
||||
+ "(&(vlSymsp->TOP));\n");
|
||||
puts("}\n");
|
||||
}
|
||||
puts("} while ("
|
||||
+ (v3Global.rootp()->changeRequest() ? std::string{"VL_UNLIKELY(__Vchange)"}
|
||||
: std::string{"0"})
|
||||
+ ");\n");
|
||||
}
|
||||
|
||||
void emitStandardMethods(AstNodeModule* modp) {
|
||||
@ -360,8 +367,10 @@ class EmitCModel final : public EmitCFunc {
|
||||
puts("void " + topModNameProtected + "__" + protect("_eval_initial") + selfDecl + ";\n");
|
||||
puts("void " + topModNameProtected + "__" + protect("_eval_settle") + selfDecl + ";\n");
|
||||
puts("void " + topModNameProtected + "__" + protect("_eval") + selfDecl + ";\n");
|
||||
puts("QData " + topModNameProtected + "__" + protect("_change_request") + selfDecl
|
||||
+ ";\n");
|
||||
if (v3Global.rootp()->changeRequest()) {
|
||||
puts("QData " + topModNameProtected + "__" + protect("_change_request") + selfDecl
|
||||
+ ";\n");
|
||||
}
|
||||
puts("#ifdef VL_DEBUG\n");
|
||||
puts("void " + topModNameProtected + "__" + protect("_eval_debug_assertions") + selfDecl
|
||||
+ ";\n");
|
||||
|
@ -22,8 +22,6 @@
|
||||
<map from="PS76My" to="__Vfunc_dpii_a_func__0__Vfuncout"/>
|
||||
<map from="PSEGxK" to="__Vscope_t__secret_inst"/>
|
||||
<map from="PS25fg" to="__Vtask_dpix_a_task__1__i"/>
|
||||
<map from="PSHuZZ" to="_change_request"/>
|
||||
<map from="PS75kd" to="_change_request_1"/>
|
||||
<map from="PSyTg5" to="_ctor_var_reset"/>
|
||||
<map from="PS8lsQ" to="_eval"/>
|
||||
<map from="PSKZ7c" to="_eval_debug_assertions"/>
|
||||
|
@ -13,18 +13,12 @@ internalsDump:
|
||||
-V{t#,#}+ Initial loop
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___eval_settle
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___eval
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request_1
|
||||
-V{t#,#}+ Clock loop
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___eval
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request_1
|
||||
-V{t#,#}+++++TOP Evaluate Vt_verilated_debug::eval_step
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___eval_debug_assertions
|
||||
-V{t#,#}+ Clock loop
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___eval
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___sequent__TOP__2
|
||||
*-* All Finished *-*
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___change_request_1
|
||||
-V{t#,#}+ Vt_verilated_debug___024root___final
|
||||
|
Loading…
Reference in New Issue
Block a user