diff --git a/Changes b/Changes index f4ca620a8..263c68d37 100644 --- a/Changes +++ b/Changes @@ -36,9 +36,10 @@ Verilator 5.001 devel * Support linting for top module interfaces (#3635). [Kanad Kanhere] * Add --dump-tree-dot to enable dumping Ast Tree .dot files (#3636). [Marcel Chang] * Add error on real edge event control. +* Fix LSB error on --hierarchical submodules (#3539). [danbone] +* Fix foreach and pre/post increment in functions (#3613). [Nandu Raj] * Fix linker errors in user-facing timing functions (#3657). [Krzysztof Bieganski, Antmicro Ltd] * Fix null access on optimized-out fork statements (#3658). [Krzysztof Bieganski, Antmicro Ltd] -* Fix LSB error on --hierarchical submodules (#3539). [danbone] Verilator 4.228 2022-10-01 diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index 7b16f8722..7c12c4e28 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -60,6 +60,7 @@ private: }; // STATE + AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside int m_modIncrementsNum = 0; // Var name counter InsertMode m_insMode = IM_BEFORE; // How to insert AstNode* m_insStmtp = nullptr; // Where to insert statement @@ -94,6 +95,11 @@ private: m_modIncrementsNum = 0; iterateChildren(nodep); } + void visit(AstNodeFTask* nodep) override { + VL_RESTORER(m_ftaskp); + m_ftaskp = nodep; + iterateChildren(nodep); + } void visit(AstWhile* nodep) override { // Special, as statements need to be put in different places // Preconditions insert first just before themselves (the normal @@ -241,6 +247,7 @@ private: const string name = string("__Vincrement") + cvtToStr(++m_modIncrementsNum); AstVar* const varp = new AstVar(fl, VVarType::BLOCKTEMP, name, VFlagChildDType(), varrefp->varp()->subDTypep()->cloneTree(true)); + if (m_ftaskp) varp->funcLocal(true); // Declare the variable insertBeforeStmt(nodep, varp); diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index b58b6f476..903f0a90c 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -301,9 +301,9 @@ private: } } void visit(AstNodeFTask* nodep) override { + VL_RESTORER(m_ftaskp); m_ftaskp = nodep; iterateChildren(nodep); - m_ftaskp = nullptr; } void visit(AstNodeFTaskRef* nodep) override { AstNode* pinp = nodep->pinsp(); diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 9a2bd2b53..528d7a32b 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -175,7 +175,7 @@ private: // Find all var->varscope mappings, for later cleanup for (AstNode* stmtp = nodep->varsp(); stmtp; stmtp = stmtp->nextp()) { if (AstVarScope* const vscp = VN_CAST(stmtp, VarScope)) { - if (vscp->varp()->isFuncLocal()) { + if (vscp->varp()->isFuncLocal() || vscp->varp()->isUsedLoopIdx()) { UINFO(9, " funcvsc " << vscp << endl); m_varToScopeMap.insert( std::make_pair(std::make_pair(nodep, vscp->varp()), vscp)); diff --git a/test_regress/t/t_assoc2.v b/test_regress/t/t_assoc2.v index 8cea07e6b..5b94ca3b9 100644 --- a/test_regress/t/t_assoc2.v +++ b/test_regress/t/t_assoc2.v @@ -16,18 +16,30 @@ module t (/*AUTOARG*/ integer cyc = 0; + int imap[int]; + // associative array of an associative array logic [31:0] a [logic [31:0]][logic [63:0]]; + task disp(); + int i = 60; + imap[i++] = 600; + imap[i++] = 601; + foreach (imap[k]) $display("imap[%0d] = %0d", k, imap[k]); + endtask + always @ (posedge clk) begin cyc <= cyc + 1; if (cyc == 1) begin a[5][8] = 8; a[5][9] = 9; + imap[10] = 100; + imap[11] = 101; end else if (cyc == 2) begin `checkh(a[5][8], 8); `checkh(a[5][9], 9); + disp(); $write("*-* All Finished *-*\n"); $finish; end