diff --git a/PWire.cc b/PWire.cc index e50e29f80..79db562eb 100644 --- a/PWire.cc +++ b/PWire.cc @@ -67,6 +67,7 @@ bool PWire::set_wire_type(NetNet::Type t) isint_ = true; return true; } + if (t == NetNet::IMPLICIT_REG) return true; return false; case NetNet::REG: if (t == NetNet::INTEGER) { diff --git a/elab_expr.cc b/elab_expr.cc index cb9a88158..224b7da6a 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -5397,12 +5397,11 @@ NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope, return tmp; } -/* - * This method should never actually be called. - */ -NetExpr* PENewArray::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const +NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const { - ivl_assert(*this, 0); + cerr << get_fileline() << ": error: The new array constructor may " + "only be used in an assignment to a dynamic array." << endl; + des->errors += 1; return 0; } diff --git a/elaborate.cc b/elaborate.cc index 409b90f42..1feb9e62c 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2318,8 +2318,17 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope, NetExpr*rv = rval_->elaborate_expr(des, scope, net_type, 0); - ivl_assert(*this, !is_constant_); - return rv; + if (!is_constant_ || !rv) return rv; + + if (dynamic_cast(rv)) return rv; + + cerr << get_fileline() << ": error: " + "The RHS expression must be constant." << endl; + cerr << get_fileline() << " : " + "This expression violates the rule: " << *rv << endl; + des->errors += 1; + delete rv; + return 0; } NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope, diff --git a/parse.y b/parse.y index 4ca0c34e1..fb5177873 100644 --- a/parse.y +++ b/parse.y @@ -1563,6 +1563,15 @@ variable_decl_assignment /* IEEE1800-2005 A.2.3 */ delete[]$1; $$ = tmp; } + | IDENTIFIER dimensions '=' dynamic_array_new + { decl_assignment_t*tmp = new decl_assignment_t; + tmp->name = lex_strings.make($1); + tmp->index = *$2; + tmp->expr .reset($4); + delete $2; + delete[]$1; + $$ = tmp; + } ; @@ -5692,6 +5701,20 @@ register_variable pform_make_var_init(@1, name, $4); $$ = $1; } + | IDENTIFIER dimensions_opt '=' dynamic_array_new + { if (pform_peek_scope()->var_init_needs_explicit_lifetime() + && (var_lifetime == LexicalScope::INHERITED)) { + cerr << @3 << ": warning: Static variable initialization requires " + "explicit lifetime in this context." << endl; + warn_count += 1; + } + perm_string name = lex_strings.make($1); + pform_makewire(@1, name, NetNet::REG, + NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0); + pform_set_reg_idx(name, $2); + pform_make_var_init(@1, name, $4); + $$ = $1; + } ; register_variable_list diff --git a/pform.cc b/pform.cc index 5940616ed..000cfd1c7 100644 --- a/pform.cc +++ b/pform.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -2710,6 +2710,8 @@ void pform_makewire(const struct vlltype&li, for (list::iterator cur = assign_list->begin() ; cur != assign_list->end() ; ++ cur) { decl_assignment_t* curp = *cur; + pform_makewire(li, curp->name, type, NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0); + pform_set_reg_idx(curp->name, &curp->index); names->push_back(curp->name); } @@ -2722,8 +2724,6 @@ void pform_makewire(const struct vlltype&li, if (type == NetNet::REG || type == NetNet::IMPLICIT_REG) { pform_make_var_init(li, first->name, expr); } else { - PWire*cur = pform_get_wire_in_scope(first->name); - assert(cur); PEIdent*lval = new PEIdent(first->name); FILE_NAME(lval, li.text, li.first_line); PGAssign*ass = pform_make_pgassign(lval, expr, delay, str);