diff --git a/PExpr.h b/PExpr.h index 13aa0e22f..29945701a 100644 --- a/PExpr.h +++ b/PExpr.h @@ -245,6 +245,10 @@ class PEConcat : public PExpr { virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; + + virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, + ivl_type_t type, unsigned flags) const; + virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; diff --git a/elab_expr.cc b/elab_expr.cc index 41ea2219f..638867133 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2497,6 +2497,24 @@ unsigned PEConcat::test_width(Design*des, NetScope*scope, width_mode_t&) // Keep track of the concatenation/repeat depth. static int concat_depth = 0; +NetExpr* PEConcat::elaborate_expr(Design*, NetScope*, + ivl_type_t type, unsigned /*flags*/) const +{ + switch (type->base_type()) { + case IVL_VT_QUEUE: + if (parms_.size() == 0) { + NetENull*tmp = new NetENull; + tmp->set_line(*this); + return tmp; + } + default: + cerr << get_fileline() << ": internal error: " + << "I don't know how to elaborate(ivl_type_t)" + << " this expression: " << *this << endl; + return 0; + } +} + NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { diff --git a/parse.y b/parse.y index 42010d232..5701011a8 100644 --- a/parse.y +++ b/parse.y @@ -3456,11 +3456,14 @@ expr_primary | '{' '}' { // This is the empty queue syntax. if (gn_system_verilog()) { - yyerror(@1, "sorry: Expty queue expressions not supported."); + list empty_list; + PEConcat*tmp = new PEConcat(empty_list); + FILE_NAME(tmp, @1); + $$ = tmp; } else { yyerror(@1, "error: Concatenations are not allowed to be empty."); + $$ = 0; } - $$ = 0; } /* Cast expressions are primaries */ diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index 74ffde30c..17d59694c 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -976,6 +976,30 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net) return errors; } +static int show_stmt_assign_sig_queue(ivl_statement_t net) +{ + int errors = 0; + ivl_lval_t lval = ivl_stmt_lval(net, 0); + ivl_expr_t rval = ivl_stmt_rval(net); + ivl_signal_t var= ivl_lval_sig(lval); + ivl_type_t var_type= ivl_signal_net_type(var); + assert(ivl_type_base(var_type) == IVL_VT_QUEUE); + + switch (ivl_expr_type(rval)) { + case IVL_EX_NULL: + errors += draw_eval_object(rval); + break; + default: + fprintf(stderr, "XXXX: I don't know how to handle expr_type=%d here\n", ivl_expr_type(rval)); + fprintf(vvp_out, " ; XXXX expr_type=%d\n", ivl_expr_type(rval)); + errors += 1; + break; + } + + fprintf(vvp_out, " %%store/obj v%p_0;\n", var); + return errors; +} + static int show_stmt_assign_sig_cobject(ivl_statement_t net) { int errors = 0; @@ -1106,6 +1130,10 @@ int show_stmt_assign(ivl_statement_t net) return show_stmt_assign_sig_darray(net); } + if (sig && (ivl_signal_data_type(sig) == IVL_VT_QUEUE)) { + return show_stmt_assign_sig_queue(net); + } + if (sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) { return show_stmt_assign_sig_cobject(net); }