From c3c7f6d9eedac222f6fbd3c1cd3836c7cac3d31a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 5 Jun 2022 11:04:44 +0200 Subject: [PATCH 1/2] tgt-vvp: Fix syntax when using multiple events for non-blocking event control When multiple events are used in a non-blocking event control they need to be combined into a single event using `event/or`. The generated `event/or` statement is missing the trailing semicolon and newline, which results in parser error when vvp tries to run. E.g. ``` event e, f; integer x; x <= @(e or f) 10; ``` Add the missing semicolon and newline to fix this. Signed-off-by: Lars-Peter Clausen --- tgt-vvp/vvp_process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index db5e06fdd..385e54fba 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -505,6 +505,8 @@ static int show_stmt_assign_nb(ivl_statement_t net) ev = ivl_stmt_events(net, idx); fprintf(vvp_out, ", E_%p", ev); } + + fprintf(vvp_out, ";\n"); snprintf(name, sizeof(name), "Eassign_%u", cascade_counter); cascade_counter += 1; } From 2bc1385a59a96c84251c10b781449f43ffcd4743 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 5 Jun 2022 11:32:42 +0200 Subject: [PATCH 2/2] Add regression test for multiple events in non-blocking event control Check that multiple events can be used in a non-blocking event control assignment. The assignment should happen if either of the events trigger. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/nb_ec_multi_ev.v | 54 ++++++++++++++++++++++++++++++++ ivtest/regress-vlg.list | 1 + 2 files changed, 55 insertions(+) create mode 100644 ivtest/ivltests/nb_ec_multi_ev.v diff --git a/ivtest/ivltests/nb_ec_multi_ev.v b/ivtest/ivltests/nb_ec_multi_ev.v new file mode 100644 index 000000000..1bf5a49dd --- /dev/null +++ b/ivtest/ivltests/nb_ec_multi_ev.v @@ -0,0 +1,54 @@ +// Check that non-blocking event control assignments with multiple events in the +// event control expression are supported. + +module test; + reg failed = 1'b0; + + `define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED. Expected %d, got %d.", exp, val); \ + failed = 1'b1; \ + end + + integer x = 0; + + event e1, e2, e3; + + initial begin + // Any of them should trigger the event + x <= @(e1 or e2 or e3) x + 1; + #1 + `check(x, 0); + ->e1; + `check(x, 1); + + x <= @(e1 or e2 or e3) x + 1; + #1 + `check(x, 1); + ->e2; + `check(x, 2); + + // Alternative syntax, but still the same behavior + x <= @(e1, e2, e3) x + 1; + #1 + `check(x, 2); + ->e3; + `check(x, 3); + + // In combination with repeat + x <= repeat(3) @(e1, e2, e3) x + 1; + #1 + `check(x, 3); + ->e1; + `check(x, 3); + ->e2; + `check(x, 3); + ->e3; + `check(x, 4); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 74b1c5ed1..5300f4d2b 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -677,6 +677,7 @@ named_event_no_edges CE ivltests nb_assign normal ivltests nb_delay normal ivltests nb_ec_concat normal ivltests +nb_ec_multi_ev normal ivltests nblkorder normal ivltests # Validates Non-blocking order determinism negative_genvar normal ivltests negvalue normal ivltests gold=negvalue.gold