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.
This commit is contained in:
Stephen Williams 2008-03-18 20:50:40 -07:00
parent 8e6c2652ab
commit d26ae866f8
6 changed files with 86 additions and 51 deletions

View File

@ -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 File

@ -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;

View File

@ -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_;

View File

@ -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,20 +2522,11 @@ 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;
}
}
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);
}
/*

View File

@ -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

View File

@ -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;