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)
|
||||
: 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());
|
||||
|
||||
/* 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;
|
||||
}
|
||||
} else {
|
||||
/* The width of multiply expressions is the sum of the
|
||||
widths of the operands. This is slightly different
|
||||
from the way the Verilog standard does it, but allows
|
||||
us to keep operands smaller. */
|
||||
width = ivl_expr_width(ivl_expr_oper1(net));
|
||||
width += ivl_expr_width(ivl_expr_oper2(net));
|
||||
if (ivl_expr_width(net) != width) {
|
||||
fprintf(out, "%*sERROR: Result width incorrect. Expecting %u, got %u\n",
|
||||
ind+3, "", width, ivl_expr_width(net));
|
||||
/* The width of a multiply may be any width. The
|
||||
implicit assumption is that the multiply
|
||||
returns a width that is the sum of the widths
|
||||
of the arguments, that is then truncated to the
|
||||
desired width, never padded. The compiler will
|
||||
automatically take care of sign extensions of
|
||||
arguments, so that the code generator need only
|
||||
generate an UNSIGNED multiply, and the result
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue