Always process specparams since they can be used outside a specify block.

The -gno-specify flag should only control the delay and timing checks.
It should not also remove the specparams since they can be used outside
of a specify block.
This commit is contained in:
Cary R 2011-06-01 13:53:43 -07:00 committed by Stephen Williams
parent a45fa00479
commit 3362fbc0db
2 changed files with 74 additions and 83 deletions

View File

@ -1872,11 +1872,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
// (as evaluated earlier). Note that specparams aren't fully // (as evaluated earlier). Note that specparams aren't fully
// supported yet, so this code is likely to need rework when // supported yet, so this code is likely to need rework when
// they are. // they are.
if (gn_specify_blocks_flag) {
map<perm_string,NetScope::spec_val_t>::const_iterator specp; map<perm_string,NetScope::spec_val_t>::const_iterator specp;
perm_string key = peek_tail_name(path_); perm_string key = peek_tail_name(path_);
if (path_.size() == 1 if (path_.size() == 1 &&
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) { ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
NetScope::spec_val_t value = (*specp).second; NetScope::spec_val_t value = (*specp).second;
if (value.type == IVL_VT_REAL) { if (value.type == IVL_VT_REAL) {
expr_type_ = IVL_VT_REAL; expr_type_ = IVL_VT_REAL;
@ -1890,13 +1889,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
min_width_ = expr_width_; min_width_ = expr_width_;
signed_flag_ = true; signed_flag_ = true;
if (mode < LOSSLESS) if (mode < LOSSLESS) mode = LOSSLESS;
mode = LOSSLESS;
} }
return expr_width_; return expr_width_;
} }
}
// Not a net, and not a parameter? Give up on the type, but // Not a net, and not a parameter? Give up on the type, but
// set the width to 0. // set the width to 0.
@ -2042,14 +2038,11 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
// A specparam? Look up the name to see if it is a // A specparam? Look up the name to see if it is a
// specparam. If we find it, then turn it into a NetEConst // specparam. If we find it, then turn it into a NetEConst
// value and return that. Of course, this does not apply if // value and return that.
// specify blocks are disabled.
if (gn_specify_blocks_flag) {
map<perm_string,NetScope::spec_val_t>::const_iterator specp; map<perm_string,NetScope::spec_val_t>::const_iterator specp;
perm_string key = peek_tail_name(path_); perm_string key = peek_tail_name(path_);
if (path_.size() == 1 if (path_.size() == 1 &&
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) { ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
NetScope::spec_val_t value = (*specp).second; NetScope::spec_val_t value = (*specp).second;
NetExpr*tmp = 0; NetExpr*tmp = 0;
switch (value.type) { switch (value.type) {
@ -2070,7 +2063,6 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
<< " is a specparam" << endl; << " is a specparam" << endl;
return tmp; return tmp;
} }
}
// Maybe this is a method attached to an enumeration name? If // Maybe this is a method attached to an enumeration name? If
// this is system verilog, then test to see if the name is // this is system verilog, then test to see if the name is

View File

@ -4278,14 +4278,12 @@ bool Module::elaborate(Design*des, NetScope*scope) const
{ {
bool result_flag = true; bool result_flag = true;
if (gn_specify_blocks_flag) {
// Elaborate specparams // Elaborate specparams
typedef map<perm_string,PExpr*>::const_iterator specparam_it_t; typedef map<perm_string,PExpr*>::const_iterator specparam_it_t;
for (specparam_it_t cur = specparams.begin() for (specparam_it_t cur = specparams.begin() ;
; cur != specparams.end() ; ++ cur ) { cur != specparams.end() ; ++ cur ) {
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1, NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1, true);
true);
NetScope::spec_val_t value; NetScope::spec_val_t value;
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) { if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
@ -4293,26 +4291,28 @@ bool Module::elaborate(Design*des, NetScope*scope) const
value.type = IVL_VT_REAL; value.type = IVL_VT_REAL;
value.real_val = val_cr->value().as_double(); value.real_val = val_cr->value().as_double();
if (debug_elaborate) if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate " cerr << get_fileline() << ": debug: Elaborate "
<< "specparam " << (*cur).first << "specparam " << (*cur).first
<< " value=" << value.real_val << endl; << " value=" << value.real_val << endl;
}
} else if (NetEConst*val_c = dynamic_cast<NetEConst*> (val)) { } else if (NetEConst*val_c = dynamic_cast<NetEConst*> (val)) {
value.type = IVL_VT_BOOL; value.type = IVL_VT_BOOL;
value.integer = val_c->value().as_long(); value.integer = val_c->value().as_long();
if (debug_elaborate) if (debug_elaborate) {
cerr << get_fileline() << ": debug: Elaborate " cerr << get_fileline() << ": debug: Elaborate "
<< "specparam " << (*cur).first << "specparam " << (*cur).first
<< " value=" << value.integer << endl; << " value=" << value.integer << endl;
}
} else { } else {
value.type = IVL_VT_NO_TYPE; value.type = IVL_VT_NO_TYPE;
cerr << (*cur).second->get_fileline() << ": error: " cerr << (*cur).second->get_fileline() << ": error: "
<< "specparam " << (*cur).first << " value" << "specparam " << (*cur).first
<< " is not constant: " << *val << endl; << " value is not constant: " << *val << endl;
des->errors += 1; des->errors += 1;
} }
@ -4320,7 +4320,6 @@ bool Module::elaborate(Design*des, NetScope*scope) const
delete val; delete val;
scope->specparams[(*cur).first] = value; scope->specparams[(*cur).first] = value;
} }
}
// Elaborate within the generate blocks. // Elaborate within the generate blocks.
typedef list<PGenerate*>::const_iterator generate_it_t; typedef list<PGenerate*>::const_iterator generate_it_t;