mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Fix initiation of function variables (#3815).
This commit is contained in:
@@ -2092,6 +2092,7 @@ void AstVar::dump(std::ostream& str) const {
|
||||
if (isSigPublic()) str << " [P]";
|
||||
if (isLatched()) str << " [LATCHED]";
|
||||
if (isUsedLoopIdx()) str << " [LOOP]";
|
||||
if (noReset()) str << " [!RST]";
|
||||
if (attrIsolateAssign()) str << " [aISO]";
|
||||
if (attrFileDescr()) str << " [aFD]";
|
||||
if (isFuncReturn()) {
|
||||
|
||||
+12
-4
@@ -138,6 +138,7 @@ private:
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstCFunc* m_cfuncp = nullptr; // Current function
|
||||
V3CCtorsBuilder* m_varResetp = nullptr; // Builder of _ctor_var_reset
|
||||
|
||||
// VISITs
|
||||
@@ -172,16 +173,23 @@ private:
|
||||
|
||||
void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_varResetp);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
m_varResetp = nullptr;
|
||||
m_cfuncp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstVar* nodep) override {
|
||||
if (m_varResetp && !nodep->isIfaceParent() && !nodep->isIfaceRef() && !nodep->noReset()
|
||||
&& !nodep->isParam()
|
||||
if (!nodep->isIfaceParent() && !nodep->isIfaceRef() && !nodep->noReset()
|
||||
&& !nodep->isParam() && !nodep->isStatementTemp()
|
||||
&& !(nodep->basicp()
|
||||
&& (nodep->basicp()->isEvent() || nodep->basicp()->isTriggerVec()))) {
|
||||
const auto vrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::WRITE};
|
||||
m_varResetp->add(new AstCReset{nodep->fileline(), vrefp});
|
||||
if (m_varResetp) {
|
||||
const auto vrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::WRITE};
|
||||
m_varResetp->add(new AstCReset{nodep->fileline(), vrefp});
|
||||
} else if (m_cfuncp) {
|
||||
const auto vrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::WRITE};
|
||||
nodep->addNextHere(new AstCReset{nodep->fileline(), vrefp});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -578,8 +578,9 @@ void EmitCFunc::emitSetVarConstant(const string& assignString, AstConst* constp)
|
||||
|
||||
void EmitCFunc::emitVarReset(AstVar* varp) {
|
||||
AstNodeDType* const dtypep = varp->dtypep()->skipRefp();
|
||||
const string varNameProtected
|
||||
= VN_IS(m_modp, Class) ? varp->nameProtect() : "vlSelf->" + varp->nameProtect();
|
||||
const string varNameProtected = (VN_IS(m_modp, Class) || varp->isFuncLocal())
|
||||
? varp->nameProtect()
|
||||
: "vlSelf->" + varp->nameProtect();
|
||||
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
|
||||
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
|
||||
} else if (varp->isParam()) {
|
||||
@@ -697,9 +698,11 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
|
||||
} else if (basicp) {
|
||||
const bool zeroit
|
||||
= (varp->attrFileDescr() // Zero so we don't do file IO if never $fopen
|
||||
|| varp->isFuncLocal() // Randomization too slow
|
||||
|| (basicp && basicp->isZeroInit())
|
||||
|| (v3Global.opt.underlineZero() && !varp->name().empty() && varp->name()[0] == '_')
|
||||
|| (v3Global.opt.xInitial() == "fast" || v3Global.opt.xInitial() == "0"));
|
||||
const bool slow = !varp->isFuncLocal() && !varp->isClassMember();
|
||||
splitSizeInc(1);
|
||||
if (dtypep->isWide()) { // Handle unpacked; not basicp->isWide
|
||||
string out;
|
||||
@@ -711,7 +714,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
|
||||
out += cvtToStr(constp->num().edataWord(w)) + "U;\n";
|
||||
}
|
||||
} else {
|
||||
out += zeroit ? "VL_ZERO_RESET_W(" : "VL_RAND_RESET_W(";
|
||||
out += zeroit ? (slow ? "VL_ZERO_RESET_W(" : "VL_ZERO_W(") : "VL_RAND_RESET_W(";
|
||||
out += cvtToStr(dtypep->widthMin());
|
||||
out += ", " + varNameProtected + suffix + ");\n";
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ private:
|
||||
AstVar* const newVarp
|
||||
= new AstVar{oldVarp->fileline(), oldVarp->varType(), newName, oldVarp};
|
||||
newVarp->funcLocal(true);
|
||||
newVarp->noReset(oldVarp->noReset());
|
||||
funcp->addInitsp(newVarp);
|
||||
|
||||
// Fix up all the references within this function
|
||||
|
||||
@@ -554,6 +554,7 @@ AstNodeStmt* buildLoop(AstNetlist* netlistp, const string& name,
|
||||
FileLine* const flp = scopeTopp->fileline();
|
||||
// Create the loop condition variable
|
||||
AstVarScope* const condp = scopeTopp->createTemp("__V" + name + "Continue", 1);
|
||||
condp->varp()->noReset(true);
|
||||
// Initialize the loop condition variable to true
|
||||
AstNodeStmt* const resp = setVar(condp, 1);
|
||||
// Add the loop
|
||||
@@ -578,6 +579,7 @@ std::pair<AstVarScope*, AstNodeStmt*> makeEvalLoop(AstNetlist* netlistp, const s
|
||||
FileLine* const flp = scopeTopp->fileline();
|
||||
|
||||
AstVarScope* const counterp = scopeTopp->createTemp("__V" + tag + "IterCount", 32);
|
||||
counterp->varp()->noReset(true);
|
||||
|
||||
AstNodeStmt* nodep = setVar(counterp, 0);
|
||||
nodep->addNext(buildLoop(netlistp, tag, [&](AstVarScope* continuep, AstWhile* loopp) {
|
||||
|
||||
Reference in New Issue
Block a user