diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 544f60201..238c68593 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -660,9 +660,9 @@ private: iterate(nodep->lhsp()); } iterate(nodep->rhsp()); - if (nodep->timingControlp()) { - iterate(nodep->timingControlp()); - } else if (m_inSynchDrive) { + if (nodep->timingControlp()) iterate(nodep->timingControlp()); + // A drive without a cycle delay, also after removing '##0', updates the clockvar now + if (m_inSynchDrive && !nodep->timingControlp()) { AstAssign* const assignp = new AstAssign{ nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()}; assignp->user1(true); diff --git a/test_regress/t/t_clocking_zero_delay.v b/test_regress/t/t_clocking_zero_delay.v index 18fc0be3e..5919b050a 100644 --- a/test_regress/t/t_clocking_zero_delay.v +++ b/test_regress/t/t_clocking_zero_delay.v @@ -15,10 +15,14 @@ module t; logic [7:0] data_ref; logic [7:0] data_test; + logic [7:0] data_last; + logic [7:0] data_last_cb; default clocking cb @(posedge clk); output #0 data_ref; output #0 data_test; + output #0 data_last; + output #0 data_last_cb; endclocking // ========================================================= @@ -74,6 +78,25 @@ module t; wait (0); end + // As ##0 has no effect, a later drive in the same cycle overrides the drive with ##0 + // (IEEE 1800-2023 14.11, 14.16.2), also before the clocking block event occurs + always begin + @(posedge clk); + cb.data_last <= ##0 8'h12; + cb.data_last <= 8'h34; + @(posedge clk); + `checkd(data_last, 8'h34) + wait (0); + end + always begin + @(cb); + cb.data_last_cb <= ##0 8'h56; + cb.data_last_cb <= 8'h78; + @(cb); + `checkd(data_last_cb, 8'h78) + wait (0); + end + // ========================================================= // Branch 3: ##0 in property/sequence context // a ##0 b = both a and b hold at the same clock tick