Multiply of real values has width of 1.
When a multiply expression is IVL_VT_REAL, then the default width is the width of the operands, and not the sum of the operands. In fact, it should turn out to be 1. Also, the width of the multiply expression when we get to the ivl_target API, need not be the sum of the widths of its arguments. In fact, if the arguments are signed, that would be completely wrong. So adjust the stub target to properly test this constraint.
This commit is contained in:
parent
ce7dd6b4ff
commit
873ed60ff8
|
|
@ -242,7 +242,11 @@ ivl_variable_type_t NetEBMinMax::expr_type() const
|
||||||
NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
|
NetEBMult::NetEBMult(char op, NetExpr*l, NetExpr*r)
|
||||||
: NetEBinary(op, l, r)
|
: NetEBinary(op, l, r)
|
||||||
{
|
{
|
||||||
expr_width(l->expr_width() + r->expr_width());
|
if (expr_type() == IVL_VT_REAL)
|
||||||
|
expr_width(1);
|
||||||
|
else
|
||||||
|
expr_width(l->expr_width() + r->expr_width());
|
||||||
|
|
||||||
cast_signed(l->has_sign() && r->has_sign());
|
cast_signed(l->has_sign() && r->has_sign());
|
||||||
|
|
||||||
/* If it turns out that this is not a signed expression, then
|
/* If it turns out that this is not a signed expression, then
|
||||||
|
|
|
||||||
|
|
@ -88,15 +88,19 @@ static void show_binary_expression(ivl_expr_t net, unsigned ind)
|
||||||
stub_errors += 1;
|
stub_errors += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The width of multiply expressions is the sum of the
|
/* The width of a multiply may be any width. The
|
||||||
widths of the operands. This is slightly different
|
implicit assumption is that the multiply
|
||||||
from the way the Verilog standard does it, but allows
|
returns a width that is the sum of the widths
|
||||||
us to keep operands smaller. */
|
of the arguments, that is then truncated to the
|
||||||
width = ivl_expr_width(ivl_expr_oper1(net));
|
desired width, never padded. The compiler will
|
||||||
width += ivl_expr_width(ivl_expr_oper2(net));
|
automatically take care of sign extensions of
|
||||||
if (ivl_expr_width(net) != width) {
|
arguments, so that the code generator need only
|
||||||
fprintf(out, "%*sERROR: Result width incorrect. Expecting %u, got %u\n",
|
generate an UNSIGNED multiply, and the result
|
||||||
ind+3, "", width, ivl_expr_width(net));
|
will come out right. */
|
||||||
|
unsigned max_width = ivl_expr_width(oper1) + ivl_expr_width(oper2);
|
||||||
|
if (ivl_expr_width(net) > max_width) {
|
||||||
|
fprintf(out, "%*sERROR: Result width to width. Expecting <= %u, got %u\n",
|
||||||
|
ind+3, "", max_width, ivl_expr_width(net));
|
||||||
stub_errors += 1;
|
stub_errors += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue