diff --git a/compiler.h b/compiler.h index 962c2f531..1cd14d360 100644 --- a/compiler.h +++ b/compiler.h @@ -151,6 +151,16 @@ extern bool gn_io_range_error_flag; re-evaluated. */ extern bool gn_strict_ca_eval_flag; +/* If variables can be converted to uwires by a continuous assignment + (assuming no procedural assign, then return true. This will be true + for SystemVerilog */ +static inline bool gn_var_can_be_uwire(void) +{ + if (generation_flag == GN_VER2009) + return true; + return false; +} + /* The bits of these GN_KEYWORDS_* constants define non-intersecting sets of keywords. The compiler enables groups of keywords by setting lexor_keyword_mask with the OR of the bits for the keywords to be diff --git a/elab_net.cc b/elab_net.cc index 06ef24b51..a9cdb25fa 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -414,6 +414,22 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, assert(sig); + /* If this is SystemVerilog and the variable is not yet + assigned by anything, then convert it to an unresolved + wire. */ + if (gn_var_can_be_uwire() + && (sig->type() == NetNet::REG) + && (sig->peek_eref() == 0) ) { + sig->type(NetNet::UNRESOLVED_WIRE); + } + + if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->pin(0).is_linked()) { + cerr << get_fileline() << ": error: Unresolved net " << sig->name() + << " cannot have multiple drivers." << endl; + des->errors += 1; + return 0; + } + /* Don't allow registers as assign l-values. */ if (sig->type() == NetNet::REG) { cerr << get_fileline() << ": error: reg " << sig->name() diff --git a/netlist.cc b/netlist.cc index 12d776f58..5727b6a81 100644 --- a/netlist.cc +++ b/netlist.cc @@ -78,7 +78,7 @@ ostream& operator<< (ostream&o, NetNet::Type t) case NetNet::WIRE: o << "wire"; break; - case NetNet::UWIRE: + case NetNet::UNRESOLVED_WIRE: o << "uwire"; } return o; diff --git a/netlist.h b/netlist.h index e2c165d92..fe07d9dfc 100644 --- a/netlist.h +++ b/netlist.h @@ -553,7 +553,7 @@ class NetNet : public NetObj { public: enum Type { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1, SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, - UWIRE }; + UNRESOLVED_WIRE }; enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT }; diff --git a/parse.y b/parse.y index 502f6ac0a..7f7ba18d0 100644 --- a/parse.y +++ b/parse.y @@ -2708,12 +2708,12 @@ net_type | K_supply1 { $$ = NetNet::SUPPLY1; } | K_wor { $$ = NetNet::WOR; } | K_trior { $$ = NetNet::TRIOR; } - | K_wone { $$ = NetNet::UWIRE; + | K_wone { $$ = NetNet::UNRESOLVED_WIRE; cerr << @1.text << ":" << @1.first_line << ": warning: " "'wone' is deprecated, please use 'uwire' " "instead." << endl; } - | K_uwire { $$ = NetNet::UWIRE; } + | K_uwire { $$ = NetNet::UNRESOLVED_WIRE; } ; var_type diff --git a/t-dll.cc b/t-dll.cc index f5d2771e9..a80bacb3e 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2386,7 +2386,7 @@ void dll_target::signal(const NetNet*net) /* We will convert this to a TRI after we check that there is only one driver. */ - case NetNet::UWIRE: + case NetNet::UNRESOLVED_WIRE: obj->type_ = IVL_SIT_UWIRE; break;