Cast to real when add arguments have mixed type.
When synthesizing, be careful (especiall for addition) that if the arguments are mixed, then cast the non-IVL_VT_REAL arguments to IVL_VT_REAL.
This commit is contained in:
parent
3aaea46144
commit
2da50e1788
|
|
@ -632,9 +632,9 @@ NetExpr* PEBinary::elaborate_expr_base_add_(Design*des,
|
||||||
use_lossless_flag = false;
|
use_lossless_flag = false;
|
||||||
|
|
||||||
tmp = new NetEBAdd(op_, lp, rp, use_lossless_flag);
|
tmp = new NetEBAdd(op_, lp, rp, use_lossless_flag);
|
||||||
if (expr_wid > 0 && (tmp->expr_type() == IVL_VT_BOOL
|
if (expr_wid > 0 && type_is_vectorable(tmp->expr_type()))
|
||||||
|| tmp->expr_type() == IVL_VT_LOGIC))
|
|
||||||
tmp->set_width(expr_wid);
|
tmp->set_width(expr_wid);
|
||||||
|
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,20 +27,11 @@
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetExpr*expr, NetExpr*obj)
|
static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetEConst*expr)
|
||||||
{
|
{
|
||||||
NetNet* sig;
|
verireal vrl(expr->value().as_double());
|
||||||
|
NetECReal rlval(vrl);
|
||||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(expr)) {
|
NetNet* sig = rlval.synthesize(des, scope);
|
||||||
verireal vrl(tmp->value().as_double());
|
|
||||||
NetECReal rlval(vrl);
|
|
||||||
sig = rlval.synthesize(des, scope);
|
|
||||||
} else {
|
|
||||||
cerr << obj->get_fileline() << ": sorry: Cannot convert "
|
|
||||||
"bit based value (" << *expr << ") to real." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
sig = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
@ -55,19 +46,26 @@ static bool process_binary_args(Design*des, NetScope*scope,
|
||||||
right->expr_type() == IVL_VT_REAL) {
|
right->expr_type() == IVL_VT_REAL) {
|
||||||
real_args = true;
|
real_args = true;
|
||||||
|
|
||||||
/* Currently we will have a runtime assert if both expressions
|
/* Convert the arguments to real. Handle the special
|
||||||
are not real, though we can convert constants. */
|
cases of constants, which can be converted more directly. */
|
||||||
if (left->expr_type() == IVL_VT_REAL) {
|
if (left->expr_type() == IVL_VT_REAL) {
|
||||||
lsig = left->synthesize(des, scope);
|
lsig = left->synthesize(des, scope);
|
||||||
|
} else if (NetEConst*tmp = dynamic_cast<NetEConst*> (left)) {
|
||||||
|
lsig = convert_to_real_const(des, scope, tmp);
|
||||||
} else {
|
} else {
|
||||||
lsig = convert_to_real_const(des, scope, left, obj);
|
NetNet*tmp = left->synthesize(des, scope);
|
||||||
|
lsig = cast_to_real(des, scope, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right->expr_type() == IVL_VT_REAL) {
|
if (right->expr_type() == IVL_VT_REAL) {
|
||||||
rsig = right->synthesize(des, scope);
|
rsig = right->synthesize(des, scope);
|
||||||
|
} else if (NetEConst*tmp = dynamic_cast<NetEConst*> (right)) {
|
||||||
|
rsig = convert_to_real_const(des, scope, tmp);
|
||||||
} else {
|
} else {
|
||||||
rsig = convert_to_real_const(des, scope, right, obj);
|
NetNet*tmp = right->synthesize(des, scope);
|
||||||
|
rsig = cast_to_real(des, scope, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
real_args = false;
|
real_args = false;
|
||||||
lsig = left->synthesize(des, scope);
|
lsig = left->synthesize(des, scope);
|
||||||
|
|
@ -104,11 +102,21 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope)
|
||||||
assert(expr_width() >= lsig->vector_width());
|
assert(expr_width() >= lsig->vector_width());
|
||||||
assert(expr_width() >= rsig->vector_width());
|
assert(expr_width() >= rsig->vector_width());
|
||||||
|
|
||||||
lsig = pad_to_width(des, lsig, expr_width());
|
unsigned width;
|
||||||
rsig = pad_to_width(des, rsig, expr_width());
|
if (expr_type() == IVL_VT_REAL) {
|
||||||
|
width = 1;
|
||||||
|
if (lsig->data_type() != IVL_VT_REAL)
|
||||||
|
lsig = cast_to_real(des, scope, lsig);
|
||||||
|
if (rsig->data_type() != IVL_VT_REAL)
|
||||||
|
rsig = cast_to_real(des, scope, rsig);
|
||||||
|
|
||||||
assert(lsig->vector_width() == rsig->vector_width());
|
} else {
|
||||||
unsigned width=lsig->vector_width();
|
lsig = pad_to_width(des, lsig, expr_width());
|
||||||
|
rsig = pad_to_width(des, rsig, expr_width());
|
||||||
|
|
||||||
|
assert(lsig->vector_width() == rsig->vector_width());
|
||||||
|
width=lsig->vector_width();
|
||||||
|
}
|
||||||
|
|
||||||
perm_string path = lsig->scope()->local_symbol();
|
perm_string path = lsig->scope()->local_symbol();
|
||||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue