Clean up $clog2() measurement of unsized numbers.
If the argument to $clog2() is unsized constant, then trim it to the smallest representation that doesn't lose the sign, then do the $clog2 on that. Also, use integer_width instead of 32 for the minimum $clog2() result for a negative value.
This commit is contained in:
parent
ed929a37bb
commit
e322cce650
17
eval_tree.cc
17
eval_tree.cc
|
|
@ -1614,7 +1614,6 @@ NetExpr* evaluate_clog2(NetExpr*arg)
|
|||
{
|
||||
NetEConst*tmpi = dynamic_cast<NetEConst *>(arg);
|
||||
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg);
|
||||
bool is_neg = false;
|
||||
if (tmpi || tmpr) {
|
||||
verinum arg;
|
||||
if (tmpi) {
|
||||
|
|
@ -1631,9 +1630,17 @@ NetExpr* evaluate_clog2(NetExpr*arg)
|
|||
return rtn;
|
||||
}
|
||||
|
||||
bool is_neg = false;
|
||||
uint64_t res = 0;
|
||||
if (arg.is_negative()) is_neg = true;
|
||||
if (arg.is_negative()) {
|
||||
is_neg = true;
|
||||
// If the length is not defined, then work with
|
||||
// the trimmed version of the number.
|
||||
if (! arg.has_len())
|
||||
arg = trim_vnum(arg);
|
||||
}
|
||||
arg.has_sign(false); // $unsigned()
|
||||
|
||||
if (!arg.is_zero()) {
|
||||
arg = arg - verinum((uint64_t)1, 1);
|
||||
while (!arg.is_zero()) {
|
||||
|
|
@ -1641,9 +1648,11 @@ NetExpr* evaluate_clog2(NetExpr*arg)
|
|||
arg = arg >> 1;
|
||||
}
|
||||
}
|
||||
if (is_neg && res < 32) res = 32;
|
||||
|
||||
if (is_neg && res < integer_width)
|
||||
res = integer_width;
|
||||
|
||||
verinum tmp (res, 32);
|
||||
tmp.has_sign(true);
|
||||
NetEConst*rtn = new NetEConst(tmp);
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue