From 568ee4436f9fee0673a5a36989baa4d5b9bf2c97 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 7 Oct 2010 20:13:11 -0700 Subject: [PATCH] Allow variables to implicitly convert to unresolved nets. SystemVerilog allows variables to be either variables or unresolved nets, depending on how they are used. If they are assigned by procedural code, then they are variables. If they are assigned by a continuous assignment, they are unresolved nets. Note that they cannot be both, and when they are unresolved nets they can only be assigned once. --- compiler.h | 10 ++++++++++ elab_net.cc | 16 ++++++++++++++++ netlist.cc | 2 +- netlist.h | 2 +- parse.y | 4 ++-- t-dll.cc | 2 +- 6 files changed, 31 insertions(+), 5 deletions(-) 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;