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);
|
NetEConst*tmpi = dynamic_cast<NetEConst *>(arg);
|
||||||
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg);
|
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg);
|
||||||
bool is_neg = false;
|
|
||||||
if (tmpi || tmpr) {
|
if (tmpi || tmpr) {
|
||||||
verinum arg;
|
verinum arg;
|
||||||
if (tmpi) {
|
if (tmpi) {
|
||||||
|
|
@ -1631,9 +1630,17 @@ NetExpr* evaluate_clog2(NetExpr*arg)
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_neg = false;
|
||||||
uint64_t res = 0;
|
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()
|
arg.has_sign(false); // $unsigned()
|
||||||
|
|
||||||
if (!arg.is_zero()) {
|
if (!arg.is_zero()) {
|
||||||
arg = arg - verinum((uint64_t)1, 1);
|
arg = arg - verinum((uint64_t)1, 1);
|
||||||
while (!arg.is_zero()) {
|
while (!arg.is_zero()) {
|
||||||
|
|
@ -1641,9 +1648,11 @@ NetExpr* evaluate_clog2(NetExpr*arg)
|
||||||
arg = arg >> 1;
|
arg = arg >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_neg && res < 32) res = 32;
|
|
||||||
|
if (is_neg && res < integer_width)
|
||||||
|
res = integer_width;
|
||||||
|
|
||||||
verinum tmp (res, 32);
|
verinum tmp (res, 32);
|
||||||
tmp.has_sign(true);
|
|
||||||
NetEConst*rtn = new NetEConst(tmp);
|
NetEConst*rtn = new NetEConst(tmp);
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue