Only pad parameter constants out to their defined width.

This patch fixes the elaboration of parameters in a continuous
assignment to only pad the constants to their defined width.
Previously they were padded to the l-value width which resulted
in a vvp runtime error. This appears to be because the width
for padding is the defined width, but the constant is printed
using its internal width which previously could be larger than
its defined width.

These constants are local nets so I added that flag as well.
This commit is contained in:
Cary R 2008-04-15 16:55:29 -07:00 committed by Stephen Williams
parent 6ca53c6810
commit d41f8fe52b
1 changed files with 13 additions and 11 deletions

View File

@ -1784,17 +1784,6 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
assert(pc); assert(pc);
verinum pvalue = pc->value(); verinum pvalue = pc->value();
/* If the desired lwidth is more than the width of the
constant value, extend the value to fit the desired
output. */
if (lwidth > pvalue.len()) {
verinum tmp ((uint64_t)0, lwidth);
for (unsigned idx = 0 ; idx < pvalue.len() ; idx += 1)
tmp.set(idx, pvalue.get(idx));
pvalue = tmp;
}
/* If the parameter has declared dimensions, then apply /* If the parameter has declared dimensions, then apply
those to the dimensions of the net that we create. */ those to the dimensions of the net that we create. */
long msb = pvalue.len()-1; long msb = pvalue.len()-1;
@ -1810,10 +1799,23 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope,
lsb = tmp->value().as_long(); lsb = tmp->value().as_long();
} }
/* If the constant is smaller than its defined width extend
the value. If needed this will be padded later to fit
the real signal width. */
unsigned pwidth = msb > lsb ? msb - lsb : lsb - msb;
if (pwidth > pvalue.len()) {
verinum tmp ((uint64_t)0, pwidth);
for (unsigned idx = 0 ; idx < pvalue.len() ; idx += 1)
tmp.set(idx, pvalue.get(idx));
pvalue = tmp;
}
sig = new NetNet(scope, scope->local_symbol(), sig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, msb, lsb); NetNet::IMPLICIT, msb, lsb);
sig->set_line(*this); sig->set_line(*this);
sig->data_type(IVL_VT_LOGIC); sig->data_type(IVL_VT_LOGIC);
sig->local_flag(true);
NetConst*cp = new NetConst(scope, scope->local_symbol(), NetConst*cp = new NetConst(scope, scope->local_symbol(),
pvalue); pvalue);
cp->set_line(*this); cp->set_line(*this);