Allow zero width replications only in a concatenation.

1364-2001 does not allow a replication count of zero, but
1364-2005 allows them when the replication is enclosed in
a concatenation with other valid bits. This patch adds
code to perform these checks for procedural expressions.
Because of the NetNet object must have a width greater
than zero a replication used in a continuous assignment
can never have a count of zero.
This commit is contained in:
Cary R 2008-04-30 18:48:36 -07:00 committed by Stephen Williams
parent cb5260b2ce
commit 9db9aa4ccb
2 changed files with 22 additions and 2 deletions

View File

@ -680,10 +680,13 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
// Keep track of the concatenation/repeat depth.
static int concat_depth = 0;
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
int expr_wid, bool) const
{
concat_depth += 1;
NetExpr* repeat = 0;
if (debug_elaborate) {
@ -712,6 +715,15 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
<< "may not be negative (" << rep->value().as_long()
<< ")." << endl;
des->errors += 1;
concat_depth -= 1;
return 0;
}
if (rep->value().is_zero() && concat_depth < 2) {
cerr << get_fileline() << ": error: Concatenation repeat "
<< "may not be zero in this context." << endl;
des->errors += 1;
concat_depth -= 1;
return 0;
}
@ -752,6 +764,15 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
tmp->set_width(wid_sum * tmp->repeat());
if (wid_sum == 0 && concat_depth < 2) {
cerr << get_fileline() << ": error: Concatenation may not "
<< "have zero width in this context." << endl;
des->errors += 1;
concat_depth -= 1;
return 0;
}
concat_depth -= 1;
return tmp;
}

View File

@ -1591,7 +1591,7 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope,
if (repeat == 0) {
cerr << get_fileline() << ": error: Concatenation repeat "
"may not be 0."
"may not be zero."
<< endl;
des->errors += 1;
return 0;
@ -1689,7 +1689,6 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope,
}
}
osig->local_flag(true);
return osig;
}