Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move implicit net creation from elaboration to elaborate_sig

If implicit nets are declared during elaboration, then the success
of binding during elaboration will depend on the order of the code
in the source file.
  • Loading branch information...
commit d26ae866f87ec4355b6607205f1082b42b45f2a9 1 parent 8e6c265
Stephen Williams authored
2  PExpr.cc
View
@@ -43,7 +43,7 @@ bool PExpr::is_constant(Module*) const
return false;
}
-NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
+NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_fileline() << ": error: expression not valid in assign l-value: "
<< *this << endl;
18 PExpr.h
View
@@ -74,6 +74,10 @@ class PExpr : public LineInfo {
unsigned min, unsigned lval,
bool&unsized_flag) const;
+ // During the elaborate_sig phase, we may need to scan
+ // expressions to find implicit net declarations.
+ virtual bool elaborate_sig(Design*des, NetScope*scope) const;
+
// Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the
// l-value width of an assignment),
@@ -107,8 +111,7 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
- virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
- bool implicit_net_ok =false) const;
+ virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
// This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is
@@ -157,8 +160,8 @@ class PEConcat : public PExpr {
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
- virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
- bool implicit_net_ok =false) const;
+ virtual bool elaborate_sig(Design*des, NetScope*scope) const;
+ virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
@@ -177,7 +180,6 @@ class PEConcat : public PExpr {
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
- bool implicit_net_ok,
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
@@ -264,9 +266,10 @@ class PEIdent : public PExpr {
unsigned min, unsigned lval,
bool&unsized_flag) const;
+ virtual bool elaborate_sig(Design*des, NetScope*scope) const;
+
// Identifiers are allowed (with restrictions) is assign l-values.
- virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
- bool implicit_net_ok =false) const;
+ virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
@@ -379,7 +382,6 @@ class PEIdent : public PExpr {
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
- bool implicit_net_ok,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
2  PGate.h
View
@@ -129,6 +129,7 @@ class PGAssign : public PGate {
void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const;
+ virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
};
@@ -166,6 +167,7 @@ class PGBuiltin : public PGate {
virtual void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const;
+ virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
Type type_;
36 elab_net.cc
View
@@ -2188,7 +2188,6 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
* make the l-value connections.
*/
NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
- bool implicit_net_ok,
bool bidirectional_flag) const
{
assert(scope);
@@ -2222,8 +2221,7 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
if (bidirectional_flag) {
nets[idx] = parms_[idx]->elaborate_bi_net(des, scope);
} else {
- nets[idx] = parms_[idx]->elaborate_lnet(des, scope,
- implicit_net_ok);
+ nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
}
if (nets[idx] == 0)
errors += 1;
@@ -2284,15 +2282,14 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
return osig;
}
-NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope,
- bool implicit_net_ok) const
+NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
{
- return elaborate_lnet_common_(des, scope, implicit_net_ok, false);
+ return elaborate_lnet_common_(des, scope, false);
}
NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
{
- return elaborate_lnet_common_(des, scope, true, true);
+ return elaborate_lnet_common_(des, scope, true);
}
/*
@@ -2506,7 +2503,6 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
* so most of the work for both is done here.
*/
NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
- bool implicit_net_ok,
bool bidirectional_flag) const
{
assert(scope);
@@ -2526,19 +2522,10 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
}
if (sig == 0) {
-
- if (implicit_net_ok) {
-
- sig = make_implicit_net_(des, scope);
- if (sig == 0)
- return 0;
-
- } else {
- cerr << get_fileline() << ": error: Net " << path_
- << " is not defined in this context." << endl;
- des->errors += 1;
- return 0;
- }
+ cerr << get_fileline() << ": error: Net " << path_
+ << " is not defined in this context." << endl;
+ des->errors += 1;
+ return 0;
}
assert(sig);
@@ -2671,15 +2658,14 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
* Identifiers in continuous assignment l-values are limited to wires
* and that ilk. Detect registers and memories here and report errors.
*/
-NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
- bool implicit_net_ok) const
+NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
{
- return elaborate_lnet_common_(des, scope, implicit_net_ok, false);
+ return elaborate_lnet_common_(des, scope, false);
}
NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
{
- return elaborate_lnet_common_(des, scope, true, true);
+ return elaborate_lnet_common_(des, scope, true);
}
/*
63 elab_sig.cc
View
@@ -230,6 +230,64 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
return flag;
}
+bool PExpr::elaborate_sig(Design*des, NetScope*scope) const
+{
+ return true;
+}
+
+bool PEConcat::elaborate_sig(Design*des, NetScope*scope) const
+{
+ bool flag = true;
+ for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
+ flag = parms_[idx]->elaborate_sig(des, scope) && flag;
+
+ return flag;
+}
+
+bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const
+{
+ NetNet* sig = 0;
+ const NetExpr*par = 0;
+ NetEvent* eve = 0;
+
+ symbol_search(des, scope, path_, sig, par, eve);
+
+ if (eve != 0)
+ return false;
+
+ if (sig == 0)
+ sig = make_implicit_net_(des, scope);
+
+ return sig != 0;
+}
+
+bool PGate::elaborate_sig(Design*des, NetScope*scope) const
+{
+ return true;
+}
+
+bool PGBuiltin::elaborate_sig(Design*des, NetScope*scope) const
+{
+ bool flag = true;
+
+ for (unsigned idx = 0 ; idx < pin_count() ; idx += 1)
+ flag = pin(idx)->elaborate_sig(des, scope) && flag;
+
+ return flag;
+}
+
+bool PGAssign::elaborate_sig(Design*des, NetScope*scope) const
+{
+ /* Normally, l-values to continuous assignments are NOT allowed
+ to implicitly declare nets. However, so many tools do allow
+ it that Icarus Verilog will allow it, at least if extensions
+ are enabled. */
+ if (generation_flag == GN_VER2001X)
+ return pin(0)->elaborate_sig(des, scope);
+
+ return true;
+}
+
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
Module*rmod) const
{
@@ -598,11 +656,6 @@ void PForStatement::elaborate_sig(Design*des, NetScope*scope) const
statement_->elaborate_sig(des, scope);
}
-bool PGate::elaborate_sig(Design*des, NetScope*scope) const
-{
- return true;
-}
-
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
16 elaborate.cc
View
@@ -85,16 +85,8 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
assert(pin(0));
assert(pin(1));
- /* Normally, l-values to continuous assignments are NOT allowed
- to implicitly declare nets. However, so many tools do allow
- it that Icarus Verilog will allow it, at least if extensions
- are enabled. */
- bool implicit_lval_ok = false;
- if (generation_flag == GN_VER2001X)
- implicit_lval_ok = true;
-
/* Elaborate the l-value. */
- NetNet*lval = pin(0)->elaborate_lnet(des, scope, implicit_lval_ok);
+ NetNet*lval = pin(0)->elaborate_lnet(des, scope);
if (lval == 0) {
return;
}
@@ -410,7 +402,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
}
- NetNet*lval_sig = pin(0)->elaborate_lnet(des, scope, true);
+ NetNet*lval_sig = pin(0)->elaborate_lnet(des, scope);
assert(lval_sig);
/* Detect the special case that the l-value width exactly
@@ -1140,7 +1132,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
assignment, as the port will continuous assign
into the port. */
- sig = pins[idx]->elaborate_lnet(des, scope, true);
+ sig = pins[idx]->elaborate_lnet(des, scope);
if (sig == 0) {
cerr << pins[idx]->get_fileline() << ": error: "
<< "Output port expression must support "
@@ -1475,7 +1467,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
<< endl;
} else {
- NetNet*sig = pins[0]->elaborate_lnet(des, scope, true);
+ NetNet*sig = pins[0]->elaborate_lnet(des, scope);
if (sig == 0) {
cerr << get_fileline() << ": error: "
<< "Output port expression is not valid." << endl;
Please sign in to comment.
Something went wrong with that request. Please try again.