Fix initialization order of initial static after function/task (#4159)
This commit is contained in:
parent
128186ea68
commit
49d2eb9a08
|
|
@ -40,6 +40,39 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
|||
|
||||
//######################################################################
|
||||
|
||||
class RenameStaticVisitor final : public VNVisitor {
|
||||
private:
|
||||
// STATE
|
||||
const std::set<AstVar*>& m_staticFuncVarsr; // Static variables from m_ftaskp
|
||||
AstNodeFTask* const m_ftaskp; // Current function/task
|
||||
|
||||
// VISITORS
|
||||
void visit(AstVarRef* nodep) override {
|
||||
const auto it = m_staticFuncVarsr.find(nodep->varp());
|
||||
if (it != m_staticFuncVarsr.end()) nodep->name((*it)->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstInitialStatic* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->unlinkFrBack();
|
||||
m_ftaskp->addHereThisAsNext(nodep);
|
||||
}
|
||||
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
RenameStaticVisitor(std::set<AstVar*>& staticFuncVars, AstNodeFTask* ftaskp, AstNode* nodep)
|
||||
: m_staticFuncVarsr(staticFuncVars)
|
||||
, m_ftaskp(ftaskp) {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
~RenameStaticVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
class BeginState final {
|
||||
private:
|
||||
// NODE STATE
|
||||
|
|
@ -123,25 +156,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void renameAndStaticsRecurse(AstNode* const nodep) {
|
||||
// Rename references and move InitialStatic items
|
||||
if (AstVarRef* const varrefp = VN_CAST(nodep, VarRef)) {
|
||||
const auto it = m_staticFuncVars.find(varrefp->varp());
|
||||
if (it != m_staticFuncVars.end()) varrefp->name((*it)->name());
|
||||
}
|
||||
|
||||
if (nodep->op1p()) renameAndStaticsRecurse(nodep->op1p());
|
||||
if (nodep->op2p()) renameAndStaticsRecurse(nodep->op2p());
|
||||
if (nodep->op3p()) renameAndStaticsRecurse(nodep->op3p());
|
||||
if (nodep->op4p()) renameAndStaticsRecurse(nodep->op4p());
|
||||
if (nodep->nextp()) renameAndStaticsRecurse(nodep->nextp());
|
||||
|
||||
if (VN_IS(nodep, InitialStatic)) {
|
||||
nodep->unlinkFrBack();
|
||||
m_ftaskp->addHereThisAsNext(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstFork* nodep) override {
|
||||
// Keep begins in forks to group their statements together
|
||||
|
|
@ -197,7 +211,7 @@ private:
|
|||
m_ftaskp = nodep;
|
||||
m_liftedp = nullptr;
|
||||
iterateChildren(nodep);
|
||||
renameAndStaticsRecurse(nodep);
|
||||
RenameStaticVisitor{m_staticFuncVars, m_ftaskp, nodep};
|
||||
if (m_liftedp) {
|
||||
// Place lifted nodes at beginning of stmtsp, so Var nodes appear before referenced
|
||||
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ compile(
|
|||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
all_run_flags => ['+plusarg=value'],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
|
|
|||
|
|
@ -52,10 +52,17 @@ module t (/*AUTOARG*/
|
|||
function automatic int f_au_au ();
|
||||
automatic int au = 2; au++; return au;
|
||||
endfunction
|
||||
string plusarg = "";
|
||||
bit has_plusarg = |($value$plusargs("plusarg=%s", plusarg));
|
||||
|
||||
int v;
|
||||
|
||||
initial begin
|
||||
if (has_plusarg) begin
|
||||
if (plusarg == "") begin
|
||||
$fatal(1, "%m: +plusarg must not be empty");
|
||||
end
|
||||
end
|
||||
v = f_no_no(); `checkh(v, 3);
|
||||
v = f_no_no(); `checkh(v, 4);
|
||||
v = f_no_st(); `checkh(v, 3);
|
||||
|
|
|
|||
Loading…
Reference in New Issue