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:
Stephen Williams 2008-09-25 20:33:29 -07:00
parent ce7dd6b4ff
commit 873ed60ff8
2 changed files with 18 additions and 10 deletions

View File

@ -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

View File

@ -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;
}
}