Add support for assign array patterns to a queue

This commit is contained in:
Cary R 2020-07-30 19:51:40 -07:00
parent a2ba8a16b1
commit 2530041a38
2 changed files with 61 additions and 17 deletions

View File

@ -202,16 +202,18 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
ivl_type_t ntype, unsigned flags) const
{
// Special case: If this is an empty pattern (i.e. '{}) and
// the expected type is a DARRAY, then convert this to a null
// handle. Internally, Icarus Verilog uses this to represent
// nil dynamic arrays.
if (parms_.size() == 0 && ntype->base_type()==IVL_VT_DARRAY) {
// the expected type is a DARRAY or QUEUE, then convert this
// to a null handle. Internally, Icarus Verilog uses this to
// represent nil dynamic arrays.
if (parms_.size() == 0 && (ntype->base_type()==IVL_VT_DARRAY ||
ntype->base_type()==IVL_VT_QUEUE)) {
NetENull*tmp = new NetENull;
tmp->set_line(*this);
return tmp;
}
if (ntype->base_type()==IVL_VT_DARRAY)
if (ntype->base_type()==IVL_VT_DARRAY ||
ntype->base_type()==IVL_VT_QUEUE)
return elaborate_expr_darray_(des, scope, ntype, flags);
cerr << get_fileline() << ": sorry: I don't know how to elaborate "

View File

@ -1045,6 +1045,50 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net)
return errors;
}
/*
* This function handles the special case that we assign an array
* pattern to a queue. Handle this by assigning each element.
* The array pattern will have a fixed size.
*/
static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval,
ivl_type_t element_type, int max_idx)
{
int errors = 0;
unsigned idx;
assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN);
for (idx = 0 ; idx < ivl_expr_parms(rval) ; idx += 1) {
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
draw_eval_vec4(ivl_expr_parm(rval,idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %d, %u;\n", var, max_idx,
width_of_packed_type(element_type));
break;
case IVL_VT_REAL:
draw_eval_real(ivl_expr_parm(rval,idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, max_idx);
break;
case IVL_VT_STRING:
draw_eval_string(ivl_expr_parm(rval,idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, max_idx);
break;
default:
fprintf(vvp_out, "; ERROR: show_stmt_assign_queue_pattern: "
"type_base=%d not implemented\n", ivl_type_base(element_type));
errors += 1;
break;
}
}
return errors;
}
static int show_stmt_assign_sig_queue(ivl_statement_t net)
{
int errors = 0;
@ -1076,21 +1120,27 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net)
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/qdar/r v%p_0, %u;\n", var, idx);
fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, idx);
} else if (mux && ivl_type_base(element_type)==IVL_VT_STRING) {
draw_eval_string(rval);
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/qdar/str v%p_0, %u;\n", var, idx);
fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, idx);
} else if (mux) { // What is left must be some form of vector
draw_eval_vec4(rval);
resize_vec4_wid(rval, ivl_stmt_lwidth(net));
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %u, %u;\n", var, idx,
fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %d, %u;\n", var, idx,
width_of_packed_type(element_type));
} else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
/* There is no l-value mux, but the r-value is an array
pattern. This is a special case of an assignment to
elements of the l-value. */
fprintf(vvp_out, " %%delete/obj v%p_0;\n", var);
errors += show_stmt_assign_queue_pattern(var, rval, element_type, idx);
} else {
fprintf(stderr, "Sorry: I don't know how to handle expr_type=%d "
"being assigned to a queue.\n", ivl_expr_type(rval));
@ -1099,18 +1149,10 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net)
errors += 1;
}
clr_word(idx);
// FIXME
// FIXME: This is probably needed to assign from an actual array.
#if 0
static int show_stmt_assign_sig_darray(ivl_statement_t net)
{
} else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
/* There is no l-value mux, but the r-value is an array
pattern. This is a special case of an assignment to
elements of the l-value. */
errors += show_stmt_assign_darray_pattern(net);
} else {
/* There is no l-value mux, so this must be an
assignment to the array as a whole. Evaluate the