Improved AstNode::asReal for large integers

This commit is contained in:
Clifford Wolf 2014-06-15 08:38:31 +02:00
parent 11d2add1b9
commit 48dc6ab98d
2 changed files with 13 additions and 10 deletions

View File

@ -775,17 +775,20 @@ int AstNode::isConst()
double AstNode::asReal(bool is_signed) double AstNode::asReal(bool is_signed)
{ {
if (type == AST_CONSTANT) { if (type == AST_CONSTANT) {
RTLIL::Const val; RTLIL::Const val(bits);
val.bits = bits;
double p = exp2(int(val.bits.size())-32); bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1;
if (val.bits.size() > 32) if (is_negative)
val.bits.erase(val.bits.begin(), val.bits.begin()+(int(val.bits.size())-32)); val = const_neg(val, val, false, false, val.bits.size());
int32_t v = val.as_int() << (32-int(val.bits.size()));
if (is_signed) double v = 0;
return v * p; for (size_t i = 0; i < val.bits.size(); i++)
return uint32_t(v) * p; if (val.bits.at(i) == RTLIL::State::S1)
v += exp2(i);
if (is_negative)
v *= -1;
return v;
} }
if (type == AST_REALVALUE) if (type == AST_REALVALUE)

View File

@ -533,7 +533,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (children[0]->type == AST_REALVALUE) { if (children[0]->type == AST_REALVALUE) {
RTLIL::Const constvalue = children[0]->realAsConst(width); RTLIL::Const constvalue = children[0]->realAsConst(width);
log("Warning: converting real value %e to binary %s at %s:%d.\n", log("Warning: converting real value %e to binary %s at %s:%d.\n",
realvalue, log_signal(constvalue), filename.c_str(), linenum); children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum);
delete children[0]; delete children[0];
children[0] = mkconst_bits(constvalue.bits, sign_hint); children[0] = mkconst_bits(constvalue.bits, sign_hint);
did_something = true; did_something = true;