Suppress creating change_request if not needed.

This commit is contained in:
Wilson Snyder 2021-07-22 20:50:03 -04:00
parent fc25721e55
commit 13933743ad
6 changed files with 63 additions and 50 deletions

View File

@ -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() {

View File

@ -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 {

View File

@ -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 |= (");

View File

@ -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");

View File

@ -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"/>

View File

@ -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