From be298d1cca451e037af99523097b99593671b0b2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 2 Oct 2022 13:27:44 +0200 Subject: [PATCH 1/2] Allow repeat expression in event control to contain automatic terms The repeat expression of an event controlled non-blocking assignment is evaluated once when the assignment is scheduled. This means there is no risk of it being referenced when its scope has already been freed. And hence there is no need to require the repeat expression to only contain static terms. Signed-off-by: Lars-Peter Clausen --- elaborate.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index e4894fd6e..584745249 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3251,15 +3251,6 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const NetEvWait*event = 0; if (count_ != 0 || event_ != 0) { if (count_ != 0) { - if (scope->is_auto() && count_->has_aa_term(des, scope)) { - cerr << get_fileline() << ": error: automatically " - "allocated variables may not be referenced " - "in intra-assignment event controls of " - "non-blocking assignments." << endl; - des->errors += 1; - return 0; - } - ivl_assert(*this, event_ != 0); count = elab_and_eval(des, scope, count_, -1); if (count == 0) { From f358b3fa8f2be079d6f822581ae1d2896bc09736 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 30 Jun 2026 16:31:44 -0700 Subject: [PATCH 2/2] Add regression test for automatic event control repeat counts Check that the repeat count expression of a non-blocking intra-assignment event control can reference an automatic task argument. The repeat count is evaluated when the assignment is scheduled, so the automatic variable is not referenced after the task scope is freed. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/nb_ec_repeat_auto.v | 46 +++++++++++++++++++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/nb_ec_repeat_auto.json | 8 +++++ 3 files changed, 55 insertions(+) create mode 100644 ivtest/ivltests/nb_ec_repeat_auto.v create mode 100644 ivtest/vvp_tests/nb_ec_repeat_auto.json diff --git a/ivtest/ivltests/nb_ec_repeat_auto.v b/ivtest/ivltests/nb_ec_repeat_auto.v new file mode 100644 index 000000000..c9e7dff87 --- /dev/null +++ b/ivtest/ivltests/nb_ec_repeat_auto.v @@ -0,0 +1,46 @@ +// Check that non-blocking event control repeat counts can use automatic terms. + +module test; + + reg clk; + reg failed; + reg [3:0] result; + + `define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \ + `"val`", exp, val); \ + failed = 1'b1; \ + end + + task automatic schedule_update; + input integer count; + begin + result <= repeat(count) @(posedge clk) 4'ha; + end + endtask + + always #5 clk = ~clk; + + initial begin + clk = 1'b0; + failed = 1'b0; + result = 4'h0; + + schedule_update(2); + + @(posedge clk); + #1; + `check(result, 4'h0); + + @(posedge clk); + #1; + `check(result, 4'ha); + + if (!failed) begin + $display("PASSED"); + end + $finish; + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 424ce1cc6..353a668c7 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -174,6 +174,7 @@ module_port_array1 vvp_tests/module_port_array1.json module_port_array_fail1 vvp_tests/module_port_array_fail1.json module_port_array_init1 vvp_tests/module_port_array_init1.json monitor4 vvp_tests/monitor4.json +nb_ec_repeat_auto vvp_tests/nb_ec_repeat_auto.json named_event_edge_fail vvp_tests/named_event_edge_fail.json named_event_negedge_fail vvp_tests/named_event_negedge_fail.json named_event_posedge_fail vvp_tests/named_event_posedge_fail.json diff --git a/ivtest/vvp_tests/nb_ec_repeat_auto.json b/ivtest/vvp_tests/nb_ec_repeat_auto.json new file mode 100644 index 000000000..382425f56 --- /dev/null +++ b/ivtest/vvp_tests/nb_ec_repeat_auto.json @@ -0,0 +1,8 @@ +{ + "type" : "normal", + "source" : "nb_ec_repeat_auto.v", + "vlog95" : { + "__comment" : "Automatic tasks are not supported", + "type" : "CE" + } +}