diff --git a/Changes b/Changes index 5ad6ae118..43fd4728e 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix DPI open array handling issues. +**** Fix showing reference locations for BLKANDNBLK (#2170). [Yuri Victorovich] + * Verilator 4.106 2020-12-02 diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 60888600e..47bee05ee 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -71,9 +71,10 @@ private: // AstVarScope::user2p() -> AstActive*. Points to activity block of signal // (valid when AstVarScope::user1p is valid) // AstVarScope::user4p() -> AstAlwaysPost*. Post block for this variable - // AstVarScope::user5() -> VarUsage. Tracks delayed vs non-delayed usage + // AstVarScope::user5p() -> AstVarRef*. Last blocking or non-blocking reference // AstVar::user2() -> bool. Set true if already made warning // AstVarRef::user2() -> bool. Set true if already processed + // AstVarRef::user5() -> bool. Set true if was blocking reference // AstAlwaysPost::user2() -> ActActive*. Points to activity block of signal // (valid when AstAlwaysPost::user4p is valid) // AstAlwaysPost::user4() -> AstIf*. Last IF (__Vdlyvset__) created under this AlwaysPost @@ -86,8 +87,6 @@ private: AstUser4InUse m_inuser4; AstUser5InUse m_inuser5; - enum VarUsage : uint8_t { VU_NONE = 0, VU_DLY = 1, VU_NONDLY = 2 }; - // STATE AstActive* m_activep = nullptr; // Current activate AstCFunc* m_cfuncp = nullptr; // Current public C Function @@ -104,13 +103,28 @@ private: // METHODS VL_DEBUG_FUNC; // Declare debug() - void markVarUsage(AstVarScope* nodep, uint32_t flags) { - // UINFO(4, " MVU " << flags << " " << nodep << endl); - nodep->user5(nodep->user5() | flags); - if ((nodep->user5() & VU_DLY) && (nodep->user5() & VU_NONDLY)) { - nodep->v3warn(BLKANDNBLK, - "Unsupported: Blocked and non-blocking assignments to same variable: " - << nodep->varp()->prettyNameQ()); + void markVarUsage(AstNodeVarRef* nodep, bool blocking) { + if (blocking) nodep->user5(true); + AstVarScope* vscp = nodep->varScopep(); + // UINFO(4, " MVU " << blocking << " " << nodep << endl); + if (!vscp->user5p()) { + vscp->user5p(nodep); + } else { + AstNode* lastrefp = vscp->user5p(); + bool last_was_blocking = lastrefp->user5(); + if (last_was_blocking != blocking) { + AstNode* nonblockingp = blocking ? nodep : lastrefp; + AstNode* blockingp = blocking ? lastrefp : nodep; + vscp->v3warn( + BLKANDNBLK, + "Unsupported: Blocked and non-blocking assignments to same variable: " + << vscp->varp()->prettyNameQ() << '\n' + << vscp->warnContextPrimary() << '\n' + << blockingp->warnOther() << "... Location of blocking assignment\n" + << blockingp->warnContextSecondary() << '\n' + << nonblockingp->warnOther() << "... Location of nonblocking assignment\n" + << nonblockingp->warnContextSecondary()); + } } } AstVarScope* createVarSc(AstVarScope* oldvarscp, const string& name, @@ -412,7 +426,7 @@ private: if (!nodep->user2Inc()) { // Not done yet if (m_inDly && nodep->access().isWriteOrRW()) { UINFO(4, "AssignDlyVar: " << nodep << endl); - markVarUsage(nodep->varScopep(), VU_DLY); + markVarUsage(nodep, true); UASSERT_OBJ(m_activep, nodep, "<= not under sensitivity block"); UASSERT_OBJ(!nodep->access().isRW(), nodep, "<= on read+write method"); if (!m_activep->hasClocked()) { @@ -463,7 +477,7 @@ private: // UINFO(9, "NBA " << nodep << endl); if (!m_inInitial) { UINFO(4, "AssignNDlyVar: " << nodep << endl); - markVarUsage(nodep->varScopep(), VU_NONDLY); + markVarUsage(nodep, false); } } } diff --git a/test_regress/t/t_order_blkandnblk_bad.out b/test_regress/t/t_order_blkandnblk_bad.out index 22738a0a4..67d333e77 100644 --- a/test_regress/t/t_order_blkandnblk_bad.out +++ b/test_regress/t/t_order_blkandnblk_bad.out @@ -1,4 +1,10 @@ %Error-BLKANDNBLK: t/t_order_blkandnblk_bad.v:17:21: Unsupported: Blocked and non-blocking assignments to same variable: 't.array' 17 | logic [1:0][3:0] array; | ^~~~~ + t/t_order_blkandnblk_bad.v:19:16: ... Location of blocking assignment + 19 | always_comb array[0] = i; + | ^~~~~ + t/t_order_blkandnblk_bad.v:22:6: ... Location of nonblocking assignment + 22 | array[1] <= array[0]; + | ^~~~~ %Error: Exiting due to