Regularize padding of signed constants
Factor common code for processing signed constants to be padded. In the process, fix some minor bugs in the padding decisions. Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
parent
7bba276a79
commit
27b704b054
22
elab_net.cc
22
elab_net.cc
|
|
@ -2620,25 +2620,9 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope,
|
||||||
net->local_flag(true);
|
net->local_flag(true);
|
||||||
net->set_signed(value_->has_sign());
|
net->set_signed(value_->has_sign());
|
||||||
|
|
||||||
/* when expanding a constant to fit into the net, extend
|
verinum num = pad_to_width(*value_, lwidth);
|
||||||
the Vx or Vz values if they are in the sign position,
|
if (num.len() > lwidth)
|
||||||
otherwise extend the number with 0 bits. */
|
num = verinum(num, lwidth);
|
||||||
verinum::V top_v = verinum::V0;
|
|
||||||
switch (value_->get(value_->len()-1)) {
|
|
||||||
case verinum::Vx:
|
|
||||||
top_v = verinum::Vx;
|
|
||||||
break;
|
|
||||||
case verinum::Vz:
|
|
||||||
top_v = verinum::Vz;
|
|
||||||
break;
|
|
||||||
default: /* V0 and V1, do nothing */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
verinum num(top_v, net->vector_width());
|
|
||||||
unsigned idx;
|
|
||||||
for (idx = 0 ; idx < num.len() && idx < value_->len(); idx += 1)
|
|
||||||
num.set(idx, value_->get(idx));
|
|
||||||
|
|
||||||
NetConst*tmp = new NetConst(scope, scope->local_symbol(), num);
|
NetConst*tmp = new NetConst(scope, scope->local_symbol(), num);
|
||||||
tmp->pin(0).drive0(drive0);
|
tmp->pin(0).drive0(drive0);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function transforms an expression by padding the high bits
|
* This function transforms an expression by padding the high bits
|
||||||
* with V0 until the expression has the desired width. This may mean
|
* with V0 until the expression has the desired width. This may mean
|
||||||
|
|
@ -39,18 +40,7 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
|
||||||
/* If the expression is a const, then replace it with a wider
|
/* If the expression is a const, then replace it with a wider
|
||||||
const. This is a more efficient result. */
|
const. This is a more efficient result. */
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
|
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
|
||||||
verinum eval = tmp->value();
|
verinum oval = pad_to_width(tmp->value(), wid);
|
||||||
bool signed_flag = eval.has_sign();
|
|
||||||
|
|
||||||
verinum::V pad = verinum::V0;
|
|
||||||
if (signed_flag)
|
|
||||||
pad = eval.get(eval.len()-1);
|
|
||||||
verinum oval (pad, wid, eval.has_len());
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < eval.len() ; idx += 1)
|
|
||||||
oval.set(idx, eval.get(idx));
|
|
||||||
|
|
||||||
oval.has_sign(signed_flag);
|
|
||||||
tmp = new NetEConst(oval);
|
tmp = new NetEConst(oval);
|
||||||
delete expr;
|
delete expr;
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue