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 <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-06-03 16:47:52 +02:00
parent ab95d1d903
commit ec75c1aa74
2 changed files with 3 additions and 8 deletions

View File

@ -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;
}

View File

@ -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;
}