Merge branch 'implicit-sig'

This commit is contained in:
Stephen Williams 2008-03-18 21:44:34 -07:00
commit a2ea980a7a
6 changed files with 121 additions and 68 deletions

View File

@ -43,7 +43,7 @@ bool PExpr::is_constant(Module*) const
return false; 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: " cerr << get_fileline() << ": error: expression not valid in assign l-value: "
<< *this << endl; << *this << endl;

18
PExpr.h
View File

@ -74,6 +74,10 @@ class PExpr : public LineInfo {
unsigned min, unsigned lval, unsigned min, unsigned lval,
bool&unsized_flag) const; 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 // Procedural elaboration of the expression. The expr_width is
// the width of the context of the expression (i.e. the // the width of the context of the expression (i.e. the
// l-value width of an assignment), // l-value width of an assignment),
@ -107,8 +111,7 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but // This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments. // restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
bool implicit_net_ok =false) const;
// This is similar to elaborate_lnet, except that the // This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is // 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 verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, virtual bool elaborate_sig(Design*des, NetScope*scope) const;
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; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope, virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width, unsigned width,
@ -177,7 +180,6 @@ class PEConcat : public PExpr {
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const; bool bidirectional_flag) const;
private: private:
svector<PExpr*>parms_; svector<PExpr*>parms_;
@ -264,9 +266,10 @@ class PEIdent : public PExpr {
unsigned min, unsigned lval, unsigned min, unsigned lval,
bool&unsized_flag) const; bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values. // Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
bool implicit_net_ok =false) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
@ -379,7 +382,6 @@ class PEIdent : public PExpr {
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const; bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) 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; void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const; virtual void elaborate(Design*des, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: private:
}; };
@ -166,6 +167,7 @@ class PGBuiltin : public PGate {
virtual void dump(ostream&out, unsigned ind =4) const; virtual void dump(ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const; virtual void elaborate(Design*, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: private:
Type type_; Type type_;

View File

@ -2188,7 +2188,6 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope,
* make the l-value connections. * make the l-value connections.
*/ */
NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const bool bidirectional_flag) const
{ {
assert(scope); assert(scope);
@ -2222,8 +2221,7 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
if (bidirectional_flag) { if (bidirectional_flag) {
nets[idx] = parms_[idx]->elaborate_bi_net(des, scope); nets[idx] = parms_[idx]->elaborate_bi_net(des, scope);
} else { } else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope, nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
implicit_net_ok);
} }
if (nets[idx] == 0) if (nets[idx] == 0)
errors += 1; errors += 1;
@ -2284,15 +2282,14 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
return osig; return osig;
} }
NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope, NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
bool implicit_net_ok) 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 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);
} }
/* /*
@ -2337,11 +2334,11 @@ NetNet* PEFNumber::elaborate_net(Design*des, NetScope*scope,
NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
{ {
NetNet::Type nettype = scope->default_nettype(); NetNet::Type nettype = scope->default_nettype();
NetNet*sig = 0; assert(nettype != NetNet::NONE);
if (!error_implicit && nettype!=NetNet::NONE) { NetNet*sig = new NetNet(scope, peek_tail_name(path_),
sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1); NetNet::IMPLICIT, 1);
sig->set_line(*this);
/* Implicit nets are always scalar logic. */ /* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC); sig->data_type(IVL_VT_LOGIC);
@ -2351,13 +2348,6 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
<< "." << peek_tail_name(path_) << "." << endl; << "." << peek_tail_name(path_) << "." << endl;
} }
} else {
cerr << get_fileline() << ": error: Net " << path_
<< " is not defined in this context." << endl;
des->errors += 1;
return 0;
}
return sig; return sig;
} }
@ -2506,7 +2496,6 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
* so most of the work for both is done here. * so most of the work for both is done here.
*/ */
NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
bool implicit_net_ok,
bool bidirectional_flag) const bool bidirectional_flag) const
{ {
assert(scope); assert(scope);
@ -2526,20 +2515,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
} }
if (sig == 0) { 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_ cerr << get_fileline() << ": error: Net " << path_
<< " is not defined in this context." << endl; << " is not defined in this context." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
}
assert(sig); assert(sig);
@ -2671,15 +2651,14 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
* Identifiers in continuous assignment l-values are limited to wires * Identifiers in continuous assignment l-values are limited to wires
* and that ilk. Detect registers and memories here and report errors. * and that ilk. Detect registers and memories here and report errors.
*/ */
NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope, NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
bool implicit_net_ok) 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 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,11 +230,94 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
return flag; 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;
// If implicit net creation is turned off, then stop now.
if (scope->default_nettype() == NetNet::NONE)
return true;
if (error_implicit)
return true;
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, bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
Module*rmod) const Module*rmod) const
{ {
bool flag = true; bool flag = true;
// First, elaborate the signals that may be created implicitly
// by ports to this module instantiation. Handle the case that
// the ports are passed by name (pins_ != 0) or position.
if (pins_)
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
const PExpr*tmp = pins_[idx].parm;
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
else
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*tmp = pin(idx);
if (tmp == 0)
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()]; NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) { for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
@ -598,11 +681,6 @@ void PForStatement::elaborate_sig(Design*des, NetScope*scope) const
statement_->elaborate_sig(des, scope); 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, * Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the * 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(0));
assert(pin(1)); 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. */ /* 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) { if (lval == 0) {
return; return;
} }
@ -410,7 +402,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1; des->errors += 1;
return; return;
} }
NetNet*lval_sig = pin(0)->elaborate_lnet(des, scope, true); NetNet*lval_sig = pin(0)->elaborate_lnet(des, scope);
assert(lval_sig); assert(lval_sig);
/* Detect the special case that the l-value width exactly /* 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 assignment, as the port will continuous assign
into the port. */ into the port. */
sig = pins[idx]->elaborate_lnet(des, scope, true); sig = pins[idx]->elaborate_lnet(des, scope);
if (sig == 0) { if (sig == 0) {
cerr << pins[idx]->get_fileline() << ": error: " cerr << pins[idx]->get_fileline() << ": error: "
<< "Output port expression must support " << "Output port expression must support "
@ -1475,7 +1467,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
<< endl; << endl;
} else { } else {
NetNet*sig = pins[0]->elaborate_lnet(des, scope, true); NetNet*sig = pins[0]->elaborate_lnet(des, scope);
if (sig == 0) { if (sig == 0) {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "Output port expression is not valid." << endl; << "Output port expression is not valid." << endl;