From ec75c1aa74081d81e43c2a954a0f3c0db9e1fdf9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 3 Jun 2022 16:47:52 +0200 Subject: [PATCH] Handle non-blocking event control to lvalue concatenation A non-blocking event controlled assignment consists of 3 steps. * Setup event * Perform assignment * Clear event This works fine if the lvalue is a singular value. If the lvalue is a concatenation multiple assignments are generated and the event is cleared after each assignment. As a result only the first assignment is event controlled. All other assignments will be regular non-blocking assignments. E.g. ``` reg x, y; event e; {x,y} <= @e 2'b11; $display(x, y); // x will be 1'b1, y will be 1'bx ``` To resolve this the event needs to be cleared after all assignments have been done. This requires changes to both tgt-vvp and the vvp runtime. tgt-vvp is updated to only insert a single `%evctl/c` instruction for each event controlled non-blocking assignment. The vvp runtime is not updated to implicitly clear the event in the `%assign/vec4/e` instruction and instead rely on the explicit `%evctl/c`. Signed-off-by: Lars-Peter Clausen --- tgt-vvp/vvp_process.c | 9 +++------ vvp/vthread.cc | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index c93de0d44..db5e06fdd 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -205,8 +205,6 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, clr_word(delay_index); } - if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n"); - clr_flag(error_flag); if (part_off_reg) clr_word(part_off_reg); @@ -281,7 +279,6 @@ static void assign_to_lvector(ivl_lval_t lval, draw_eval_expr_into_integer(part_off_ex, offset_index); fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n", assign_op, sig, use_word, offset_index); - fprintf(vvp_out, " %%evctl/c;\n"); clr_word(offset_index); @@ -314,7 +311,6 @@ static void assign_to_lvector(ivl_lval_t lval, fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n", assign_op, sig, use_word, offset_index); - fprintf(vvp_out, " %%evctl/c;\n"); clr_word(offset_index); } else { @@ -348,8 +344,6 @@ static void assign_to_lvector(ivl_lval_t lval, /* Event control delay... */ fprintf(vvp_out, " %s/vec4/e v%p_%lu;\n", assign_op, sig, use_word); - fprintf(vvp_out, " %%evctl/c;\n"); - } else { /* * The %assign can only take a 32 bit delay. For a larger @@ -595,6 +589,9 @@ static int show_stmt_assign_nb(ivl_statement_t net) } } + if (nevents) + fprintf(vvp_out, " %%evctl/c;\n"); + return 0; } diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 7cb68568a..a1963b5cd 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1349,8 +1349,6 @@ bool of_ASSIGN_VEC4E(vthread_t thr, vvp_code_t cp) schedule_evctl(ptr, value, 0, sig->value_size(), thr->event, thr->ecount); } - thr->event = 0; - thr->ecount = 0; return true; }