vlog95: Add $signed/$unsigned support for signals

The actual signal code is trivial, but the emit expression code needed
to be enhanced to pass a flag that says if one of the arguments in a
binary (except the shifts) or ternary (excluding the condition) context
is unsigned. This information is used to prevent emitting an explicit
$unsigned() for a signal that is used in this context since it will be
implicitly cast to unsigned.
This commit is contained in:
Cary R 2013-06-27 13:20:16 -07:00
parent 11e5641089
commit eecc3312b7
5 changed files with 105 additions and 85 deletions

View File

@ -48,7 +48,7 @@ static unsigned emit_power_as_shift(ivl_scope_t scope, ivl_expr_t expr,
if (value % 2) return 0; if (value % 2) return 0;
/* Generate the appropriate conversion. */ /* Generate the appropriate conversion. */
if (ivl_expr_signed(rval)) { if (ivl_expr_signed(rval)) {
emit_expr(scope, rval, 0); emit_expr(scope, rval, 0, 0);
fprintf(vlog_out, " < 0 ? %u'h0 : (", expr_wid); fprintf(vlog_out, " < 0 ? %u'h0 : (", expr_wid);
is_signed_rval = 1; is_signed_rval = 1;
} }
@ -63,7 +63,7 @@ static unsigned emit_power_as_shift(ivl_scope_t scope, ivl_expr_t expr,
} }
fprintf(vlog_out, " * "); fprintf(vlog_out, " * ");
} }
emit_expr(scope, rval, 0); emit_expr(scope, rval, 0, 0);
if (scale != 1) fprintf(vlog_out, ")"); if (scale != 1) fprintf(vlog_out, ")");
if (is_signed_rval) fprintf(vlog_out, ")"); if (is_signed_rval) fprintf(vlog_out, ")");
return 1; return 1;
@ -79,6 +79,11 @@ static void emit_expr_array(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
{ {
char *oper = "<invalid>"; char *oper = "<invalid>";
ivl_expr_t oper1 = ivl_expr_oper1(expr);
ivl_expr_t oper2 = ivl_expr_oper2(expr);
unsigned can_skip_unsigned = ! ivl_expr_signed(oper1) ||
! ivl_expr_signed(oper2);
switch (ivl_expr_opcode(expr)) { switch (ivl_expr_opcode(expr)) {
case '+': oper = "+"; break; case '+': oper = "+"; break;
case '-': oper = "-"; break; case '-': oper = "-"; break;
@ -134,15 +139,15 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
case '|': case '|':
case '^': case '^':
case 'X': case 'X':
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, can_skip_unsigned);
fprintf(vlog_out, " %s ", oper); fprintf(vlog_out, " %s ", oper);
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, can_skip_unsigned);
break; break;
case 'a': case 'a':
case 'o': case 'o':
emit_expr(scope, ivl_expr_oper1(expr), 0); emit_expr(scope, oper1, 0, can_skip_unsigned);
fprintf(vlog_out, " %s ", oper); fprintf(vlog_out, " %s ", oper);
emit_expr(scope, ivl_expr_oper2(expr), 0); emit_expr(scope, oper2, 0, can_skip_unsigned);
break; break;
case 'R': case 'R':
if (! allow_signed) { if (! allow_signed) {
@ -153,23 +158,23 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
} }
case 'l': case 'l':
case 'r': case 'r':
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, 0);
fprintf(vlog_out, " %s ", oper); fprintf(vlog_out, " %s ", oper);
emit_expr(scope, ivl_expr_oper2(expr), 0); emit_expr(scope, oper2, 0, 0);
break; break;
case 'A': case 'A':
case 'O': case 'O':
fprintf(vlog_out, "~("); fprintf(vlog_out, "~(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, can_skip_unsigned);
fprintf(vlog_out, " %s ", oper); fprintf(vlog_out, " %s ", oper);
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, can_skip_unsigned);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
break; break;
case 'p': case 'p':
if (! emit_power_as_shift(scope, expr, wid)) { if (! emit_power_as_shift(scope, expr, wid)) {
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, can_skip_unsigned);
fprintf(vlog_out, " ** "); fprintf(vlog_out, " ** ");
emit_expr(scope, ivl_expr_oper2(expr), 0); emit_expr(scope, oper2, 0, can_skip_unsigned);
fprintf(stderr, "%s:%u: vlog95 error: Power operator is not " fprintf(stderr, "%s:%u: vlog95 error: Power operator is not "
"supported.\n", "supported.\n",
ivl_expr_file(expr), ivl_expr_lineno(expr)); ivl_expr_file(expr), ivl_expr_lineno(expr));
@ -183,27 +188,27 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
/* For a real expression use the $min()/$max() function. */ /* For a real expression use the $min()/$max() function. */
if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min("); if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min(");
else fprintf(vlog_out, "$max("); else fprintf(vlog_out, "$max(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, 0);
fprintf(vlog_out, ","); fprintf(vlog_out, ",");
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
} else { } else {
/* This only works when the argument has no side effect. */ /* This only works when the argument has no side effect. */
fprintf(vlog_out, "(("); fprintf(vlog_out, "((");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, 0);
fprintf(vlog_out, ") %s (", oper); fprintf(vlog_out, ") %s (", oper);
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, 0);
fprintf(vlog_out, ") ? ("); fprintf(vlog_out, ") ? (");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, 0);
fprintf(vlog_out, ") : ("); fprintf(vlog_out, ") : (");
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, 0);
fprintf(vlog_out, "))"); fprintf(vlog_out, "))");
} }
break; break;
default: default:
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, oper1, wid, 0);
fprintf(vlog_out, "<unknown>"); fprintf(vlog_out, "<unknown>");
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, 0);
fprintf(stderr, "%s:%u: vlog95 error: Unknown expression " fprintf(stderr, "%s:%u: vlog95 error: Unknown expression "
"operator (%c).\n", "operator (%c).\n",
ivl_expr_file(expr), ivl_expr_file(expr),
@ -224,10 +229,10 @@ static void emit_expr_concat(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
fprintf(vlog_out, "{"); fprintf(vlog_out, "{");
count -= 1; count -= 1;
for (idx = 0; idx < count; idx += 1) { for (idx = 0; idx < count; idx += 1) {
emit_expr(scope, ivl_expr_parm(expr, idx), 0); emit_expr(scope, ivl_expr_parm(expr, idx), 0, 0);
fprintf(vlog_out, ", "); fprintf(vlog_out, ", ");
} }
emit_expr(scope, ivl_expr_parm(expr, count), 0); emit_expr(scope, ivl_expr_parm(expr, count), 0, 0);
fprintf(vlog_out, "}"); fprintf(vlog_out, "}");
if (repeat != 1) fprintf(vlog_out, "}"); if (repeat != 1) fprintf(vlog_out, "}");
} }
@ -327,7 +332,7 @@ static void emit_select_name(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
ivl_expr_file(expr), ivl_expr_lineno(expr)); ivl_expr_file(expr), ivl_expr_lineno(expr));
vlog_errors += 1; vlog_errors += 1;
} else { } else {
emit_expr(scope, expr, wid); emit_expr(scope, expr, wid, 0);
} }
} }
@ -343,12 +348,12 @@ static void emit_expr_packed(ivl_scope_t scope, ivl_expr_t sig_expr,
for (idx = wid - 1; idx > 0; idx -= 1) { for (idx = wid - 1; idx > 0; idx -= 1) {
emit_select_name(scope, sig_expr, wid); emit_select_name(scope, sig_expr, wid);
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0); emit_expr(scope, sel_expr, 0, 0);
fprintf(vlog_out, " + %u], ", idx); fprintf(vlog_out, " + %u], ", idx);
} }
emit_select_name(scope, sig_expr, wid); emit_select_name(scope, sig_expr, wid);
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0); emit_expr(scope, sel_expr, 0, 0);
fprintf(vlog_out, "]}"); fprintf(vlog_out, "]}");
} }
@ -503,7 +508,7 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
assert(sel_expr); assert(sel_expr);
emit_select_name(scope, sig_expr, wid); emit_select_name(scope, sig_expr, wid);
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0); emit_expr(scope, sel_expr, 0, 0);
fprintf(vlog_out, "]"); fprintf(vlog_out, "]");
return; return;
} }
@ -552,7 +557,7 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
} }
} else { } else {
// HERE: Should this sign extend if the expression is signed? // HERE: Should this sign extend if the expression is signed?
emit_expr(scope, sig_expr, wid); emit_expr(scope, sig_expr, wid, 0);
/* Select part of a signal when needed. */ /* Select part of a signal when needed. */
if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) && if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) &&
(ivl_expr_width(expr) < ivl_expr_width(sig_expr))) { (ivl_expr_width(expr) < ivl_expr_width(sig_expr))) {
@ -579,10 +584,10 @@ static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
fprintf(vlog_out, "("); fprintf(vlog_out, "(");
count -= 1; count -= 1;
for (idx = 0; idx < count; idx += 1) { for (idx = 0; idx < count; idx += 1) {
emit_expr(scope, ivl_expr_parm(expr, idx), 0); emit_expr(scope, ivl_expr_parm(expr, idx), 0, 0);
fprintf(vlog_out, ", "); fprintf(vlog_out, ", ");
} }
emit_expr(scope, ivl_expr_parm(expr, count), 0); emit_expr(scope, ivl_expr_parm(expr, count), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
/* User functions without arguments are not supported. */ /* User functions without arguments are not supported. */
} else if (ivl_expr_type(expr) == IVL_EX_UFUNC) { } else if (ivl_expr_type(expr) == IVL_EX_UFUNC) {
@ -606,12 +611,16 @@ static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
{ {
ivl_expr_t oper2 = ivl_expr_oper2(expr);
ivl_expr_t oper3 = ivl_expr_oper3(expr);
unsigned can_skip_unsigned = ! ivl_expr_signed(oper2) ||
! ivl_expr_signed(oper3);
fprintf(vlog_out, "("); fprintf(vlog_out, "(");
emit_expr(scope, ivl_expr_oper1(expr), 0); emit_expr(scope, ivl_expr_oper1(expr), 0, 0);
fprintf(vlog_out, " ? "); fprintf(vlog_out, " ? ");
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, oper2, wid, can_skip_unsigned);
fprintf(vlog_out, " : "); fprintf(vlog_out, " : ");
emit_expr(scope, ivl_expr_oper3(expr), wid); emit_expr(scope, oper3, wid, can_skip_unsigned);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
} }
@ -640,18 +649,18 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
case 'X': case 'X':
case '!': case '!':
fprintf(vlog_out, "(%s", oper); fprintf(vlog_out, "(%s", oper);
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
break; break;
case '2': case '2':
case 'v': case 'v':
case 'r': case 'r':
/* A cast is a noop. */ /* A cast is a noop. */
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
break; break;
case 'I': case 'I':
fprintf(vlog_out, "(++"); fprintf(vlog_out, "(++");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
fprintf(stderr, "%s:%u: vlog95 sorry: Pre-increment " fprintf(stderr, "%s:%u: vlog95 sorry: Pre-increment "
"operator is not currently translated.\n", "operator is not currently translated.\n",
@ -661,7 +670,7 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
break; break;
case 'i': case 'i':
fprintf(vlog_out, "("); fprintf(vlog_out, "(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, "++)"); fprintf(vlog_out, "++)");
fprintf(stderr, "%s:%u: vlog95 sorry: Post-increment " fprintf(stderr, "%s:%u: vlog95 sorry: Post-increment "
"operator is not currently translated.\n", "operator is not currently translated.\n",
@ -671,7 +680,7 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
break; break;
case 'D': case 'D':
fprintf(vlog_out, "(--"); fprintf(vlog_out, "(--");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
fprintf(stderr, "%s:%u: vlog95 sorry: Pre-decrement " fprintf(stderr, "%s:%u: vlog95 sorry: Pre-decrement "
"operator is not currently translated.\n", "operator is not currently translated.\n",
@ -681,7 +690,7 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
break; break;
case 'd': case 'd':
fprintf(vlog_out, "("); fprintf(vlog_out, "(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, "--)"); fprintf(vlog_out, "--)");
fprintf(stderr, "%s:%u: vlog95 sorry: Post-decrement " fprintf(stderr, "%s:%u: vlog95 sorry: Post-decrement "
"operator is not currently translated.\n", "operator is not currently translated.\n",
@ -694,22 +703,22 @@ static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
if (ivl_expr_value(expr) == IVL_VT_REAL) { if (ivl_expr_value(expr) == IVL_VT_REAL) {
/* For a real expression use the $abs() function. */ /* For a real expression use the $abs() function. */
fprintf(vlog_out, "$abs("); fprintf(vlog_out, "$abs(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
} else { } else {
/* This only works when the argument has no side effect. */ /* This only works when the argument has no side effect. */
fprintf(vlog_out, "(("); fprintf(vlog_out, "((");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ") > 0 ? ("); fprintf(vlog_out, ") > 0 ? (");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, ") : -("); fprintf(vlog_out, ") : -(");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(vlog_out, "))"); fprintf(vlog_out, "))");
} }
break; break;
default: default:
fprintf(vlog_out, "<unknown>"); fprintf(vlog_out, "<unknown>");
emit_expr(scope, ivl_expr_oper1(expr), wid); emit_expr(scope, ivl_expr_oper1(expr), wid, 0);
fprintf(stderr, "%s:%u: vlog95 error: Unknown unary " fprintf(stderr, "%s:%u: vlog95 error: Unknown unary "
"operator (%c).\n", "operator (%c).\n",
ivl_expr_file(expr), ivl_expr_file(expr),
@ -808,6 +817,20 @@ static expr_sign_t get_select_sign_type(ivl_expr_t expr)
return rtn; return rtn;
} }
static expr_sign_t get_signal_sign_type(ivl_expr_t expr,
unsigned can_skip_unsigned)
{
int opr_sign = ivl_signal_signed(ivl_expr_signal(expr));
int expr_sign = ivl_expr_signed(expr);
expr_sign_t rtn = NO_SIGN;
/* Check to see if a $signed() or $unsigned() are needed. */
if (expr_sign && ! opr_sign) rtn = NEED_SIGNED;
if (! expr_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED;
return rtn;
}
static expr_sign_t get_unary_sign_type(ivl_expr_t expr) static expr_sign_t get_unary_sign_type(ivl_expr_t expr)
{ {
ivl_expr_t expr1; ivl_expr_t expr1;
@ -861,13 +884,11 @@ static expr_sign_t get_unary_sign_type(ivl_expr_t expr)
return rtn; return rtn;
} }
expr_sign_t get_sign_type(ivl_expr_t expr) expr_sign_t get_sign_type(ivl_expr_t expr, unsigned can_skip_unsigned)
{ {
expr_sign_t rtn = NO_SIGN; expr_sign_t rtn = NO_SIGN;
switch (ivl_expr_type(expr)) { switch (ivl_expr_type(expr)) {
case IVL_EX_ARRAY:
break;
case IVL_EX_BINARY: case IVL_EX_BINARY:
rtn = get_binary_sign_type(expr); rtn = get_binary_sign_type(expr);
break; break;
@ -876,22 +897,15 @@ expr_sign_t get_sign_type(ivl_expr_t expr)
* needed. */ * needed. */
if (ivl_expr_signed(expr)) rtn = NEED_SIGNED; if (ivl_expr_signed(expr)) rtn = NEED_SIGNED;
break; break;
case IVL_EX_NUMBER:
break;
case IVL_EX_PROPERTY: case IVL_EX_PROPERTY:
break; break;
case IVL_EX_REALNUM:
break;
case IVL_EX_SCOPE:
break;
case IVL_EX_SELECT: case IVL_EX_SELECT:
rtn = get_select_sign_type(expr); rtn = get_select_sign_type(expr);
break; break;
case IVL_EX_SFUNC: case IVL_EX_SFUNC:
break; break;
case IVL_EX_SIGNAL: case IVL_EX_SIGNAL:
break; rtn = get_signal_sign_type(expr, can_skip_unsigned);
case IVL_EX_STRING:
break; break;
case IVL_EX_TERNARY: case IVL_EX_TERNARY:
break; break;
@ -901,22 +915,27 @@ expr_sign_t get_sign_type(ivl_expr_t expr)
rtn = get_unary_sign_type(expr); rtn = get_unary_sign_type(expr);
break; break;
/* These do not have/need sign casting information. */ /* These do not have/need sign casting information. */
case IVL_EX_ARRAY:
case IVL_EX_DELAY: case IVL_EX_DELAY:
case IVL_EX_ENUMTYPE: case IVL_EX_ENUMTYPE:
case IVL_EX_EVENT: case IVL_EX_EVENT:
case IVL_EX_NEW: case IVL_EX_NEW:
case IVL_EX_NULL: case IVL_EX_NULL:
case IVL_EX_NUMBER:
case IVL_EX_REALNUM:
case IVL_EX_SCOPE:
case IVL_EX_SHALLOWCOPY: case IVL_EX_SHALLOWCOPY:
// HERE: Do the array, property, real number or string belong here as well? case IVL_EX_STRING:
default: default:
break; break;
} }
return rtn; return rtn;
} }
void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
unsigned can_skip_unsigned)
{ {
expr_sign_t sign_type = get_sign_type(expr); expr_sign_t sign_type = get_sign_type(expr, can_skip_unsigned);
/* Check to see if a $signed() or $unsigned() needs to be emitted /* Check to see if a $signed() or $unsigned() needs to be emitted
* before the expression. */ * before the expression. */
@ -1002,7 +1021,7 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
break; break;
case IVL_EX_SHALLOWCOPY: case IVL_EX_SHALLOWCOPY:
fprintf(vlog_out, "<new> "); fprintf(vlog_out, "<new> ");
emit_expr(scope, ivl_expr_oper2(expr), wid); emit_expr(scope, ivl_expr_oper2(expr), wid, 0);
fprintf(stderr, "%s:%u: vlog95 error: New operator " fprintf(stderr, "%s:%u: vlog95 error: New operator "
"is not supported.\n", "is not supported.\n",
ivl_expr_file(expr), ivl_expr_file(expr),

View File

@ -74,7 +74,7 @@ static void emit_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt)
return; return;
} }
} }
emit_expr(scope, expr, 0); emit_expr(scope, expr, 0, 0);
} }
/* /*
@ -396,10 +396,10 @@ void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb)
fprintf(vlog_out, "%"PRId64, value); fprintf(vlog_out, "%"PRId64, value);
} else if (lsb == 0) { } else if (lsb == 0) {
/* If the LSB is zero then there is no scale. */ /* If the LSB is zero then there is no scale. */
emit_expr(scope, expr, 0); emit_expr(scope, expr, 0, 0);
} else { } else {
if (is_scaled_expr(expr, msb, lsb)) { if (is_scaled_expr(expr, msb, lsb)) {
emit_expr(scope, ivl_expr_oper1(expr), 0); emit_expr(scope, ivl_expr_oper1(expr), 0, 0);
} }
} }
} else { } else {
@ -413,7 +413,7 @@ void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb)
fprintf(vlog_out, "%"PRId64, value); fprintf(vlog_out, "%"PRId64, value);
} else { } else {
if (is_scaled_expr(expr, msb, lsb)) { if (is_scaled_expr(expr, msb, lsb)) {
emit_expr(scope, ivl_expr_oper2(expr), 0); emit_expr(scope, ivl_expr_oper2(expr), 0, 0);
} }
} }
} }

View File

@ -312,7 +312,7 @@ void emit_scope_variables(ivl_scope_t scope)
fprintf(vlog_out, "%*cparameter ", indent, ' '); fprintf(vlog_out, "%*cparameter ", indent, ' ');
emit_id(ivl_parameter_basename(par)); emit_id(ivl_parameter_basename(par));
fprintf(vlog_out, " = "); fprintf(vlog_out, " = ");
emit_expr(scope, pex, 0); emit_expr(scope, pex, 0, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
if (emit_file_line) { if (emit_file_line) {
fprintf(vlog_out, " /* %s:%u */", fprintf(vlog_out, " /* %s:%u */",

View File

@ -69,7 +69,7 @@ static void emit_stmt_inter_delay(ivl_scope_t scope, ivl_statement_t stmt)
} }
} else { } else {
fprintf(vlog_out, "repeat("); fprintf(vlog_out, "repeat(");
emit_expr(scope, count, 0); emit_expr(scope, count, 0, 0);
fprintf(vlog_out, ") "); fprintf(vlog_out, ") ");
} }
} }
@ -115,12 +115,12 @@ static void emit_stmt_lval_packed(ivl_scope_t scope, ivl_lval_t lval,
for (idx = wid - 1; idx > 0; idx -= 1) { for (idx = wid - 1; idx > 0; idx -= 1) {
emit_stmt_lval_name(scope, lval, sig); emit_stmt_lval_name(scope, lval, sig);
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0); emit_expr(scope, sel_expr, 0, 0);
fprintf(vlog_out, " + %u], ", idx); fprintf(vlog_out, " + %u], ", idx);
} }
emit_stmt_lval_name(scope, lval, sig); emit_stmt_lval_name(scope, lval, sig);
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, sel_expr, 0); emit_expr(scope, sel_expr, 0, 0);
fprintf(vlog_out, "]}"); fprintf(vlog_out, "]}");
} }
@ -205,7 +205,7 @@ static void emit_stmt_lval_darray(ivl_scope_t scope, ivl_lval_t lval,
emit_id(ivl_signal_basename(sig)); emit_id(ivl_signal_basename(sig));
if (idx) { if (idx) {
fprintf(vlog_out, "["); fprintf(vlog_out, "[");
emit_expr(scope, idx, 0); emit_expr(scope, idx, 0, 0);
fprintf(vlog_out, "]"); fprintf(vlog_out, "]");
} }
} }
@ -375,7 +375,7 @@ static unsigned is_delayed_or_event_assign(ivl_scope_t scope,
emit_event(scope, delay); emit_event(scope, delay);
} }
fprintf(vlog_out, ") "); fprintf(vlog_out, ") ");
emit_expr(scope, ivl_stmt_rval(assign), wid); emit_expr(scope, ivl_stmt_rval(assign), wid, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -442,7 +442,7 @@ static void emit_assign_and_opt_opcode(ivl_scope_t scope, ivl_statement_t stmt,
vlog_errors += 1; vlog_errors += 1;
} }
} }
emit_expr(scope, ivl_stmt_rval(stmt), wid); emit_expr(scope, ivl_stmt_rval(stmt), wid, 0);
} }
/* /*
@ -497,7 +497,7 @@ static unsigned is_for_loop(ivl_scope_t scope, ivl_statement_t stmt)
emit_assign_and_opt_opcode(scope, assign, 0); emit_assign_and_opt_opcode(scope, assign, 0);
fprintf(vlog_out, "; "); fprintf(vlog_out, "; ");
/* Emit the condition. */ /* Emit the condition. */
emit_expr(scope, ivl_stmt_cond_expr(while_lp), 0); emit_expr(scope, ivl_stmt_cond_expr(while_lp), 0, 0);
fprintf(vlog_out, "; "); fprintf(vlog_out, "; ");
/* Emit the increment statement (an opcode is allowed). */ /* Emit the increment statement (an opcode is allowed). */
emit_assign_and_opt_opcode(scope, incr_assign, 1); emit_assign_and_opt_opcode(scope, incr_assign, 1);
@ -575,13 +575,13 @@ static unsigned is_repeat_event_assign(ivl_scope_t scope, ivl_statement_t stmt)
fprintf(vlog_out, " ="); fprintf(vlog_out, " =");
if (repeat) { if (repeat) {
fprintf(vlog_out, " repeat ("); fprintf(vlog_out, " repeat (");
emit_expr(scope, ivl_stmt_cond_expr(repeat), 0); emit_expr(scope, ivl_stmt_cond_expr(repeat), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
} }
fprintf(vlog_out, " @("); fprintf(vlog_out, " @(");
emit_event(scope, event); emit_event(scope, event);
fprintf(vlog_out, ") "); fprintf(vlog_out, ") ");
emit_expr(scope, ivl_stmt_rval(assign), wid); emit_expr(scope, ivl_stmt_rval(assign), wid, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -634,7 +634,7 @@ static unsigned is_wait(ivl_scope_t scope, ivl_statement_t stmt)
/* The pattern matched so generate the appropriate code. */ /* The pattern matched so generate the appropriate code. */
fprintf(vlog_out, "%*cwait(", get_indent(), ' '); fprintf(vlog_out, "%*cwait(", get_indent(), ' ');
emit_expr(scope, ivl_expr_oper1(while_expr), 0); emit_expr(scope, ivl_expr_oper1(while_expr), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
single_indent = 1; single_indent = 1;
@ -740,7 +740,7 @@ typedef struct port_expr_s {
static void emit_port(ivl_scope_t scope, struct port_expr_s port_expr) static void emit_port(ivl_scope_t scope, struct port_expr_s port_expr)
{ {
if (port_expr.type == IVL_SIP_INPUT) { if (port_expr.type == IVL_SIP_INPUT) {
emit_expr(scope, port_expr.expr.rval, 0); emit_expr(scope, port_expr.expr.rval, 0, 0);
} else { } else {
/* This is a self-determined context so we don't care about /* This is a self-determined context so we don't care about
* the width of the L-value. */ * the width of the L-value. */
@ -894,7 +894,7 @@ static void emit_stmt_assign_nb(ivl_scope_t scope, ivl_statement_t stmt)
wid = emit_stmt_lval(scope, stmt); wid = emit_stmt_lval(scope, stmt);
fprintf(vlog_out, " <= "); fprintf(vlog_out, " <= ");
emit_stmt_inter_delay(scope, stmt); emit_stmt_inter_delay(scope, stmt);
emit_expr(scope, ivl_stmt_rval(stmt), wid); emit_expr(scope, ivl_stmt_rval(stmt), wid, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -940,7 +940,7 @@ static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt)
assert(0); assert(0);
} }
fprintf(vlog_out, "%*c%s (", get_indent(), ' ', case_type); fprintf(vlog_out, "%*c%s (", get_indent(), ' ', case_type);
emit_expr(scope, ivl_stmt_cond_expr(stmt), 0); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -955,7 +955,7 @@ static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt)
continue; continue;
} }
fprintf(vlog_out, "%*c", get_indent(), ' '); fprintf(vlog_out, "%*c", get_indent(), ' ');
emit_expr(scope, expr, 0); emit_expr(scope, expr, 0, 0);
fprintf(vlog_out, ":"); fprintf(vlog_out, ":");
single_indent = 1; single_indent = 1;
emit_stmt(scope, ivl_stmt_case_stmt(stmt, idx)); emit_stmt(scope, ivl_stmt_case_stmt(stmt, idx));
@ -978,7 +978,7 @@ static void emit_stmt_cassign(ivl_scope_t scope, ivl_statement_t stmt)
// done this for us. // done this for us.
wid = emit_stmt_lval(scope, stmt); wid = emit_stmt_lval(scope, stmt);
fprintf(vlog_out, " = "); fprintf(vlog_out, " = ");
emit_expr(scope, ivl_stmt_rval(stmt), wid); emit_expr(scope, ivl_stmt_rval(stmt), wid, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -990,7 +990,7 @@ static void emit_stmt_condit(ivl_scope_t scope, ivl_statement_t stmt)
ivl_statement_t false_stmt = ivl_stmt_cond_false(stmt); ivl_statement_t false_stmt = ivl_stmt_cond_false(stmt);
unsigned nest = 0; unsigned nest = 0;
fprintf(vlog_out, "%*cif (", get_indent(), ' '); fprintf(vlog_out, "%*cif (", get_indent(), ' ');
emit_expr(scope, ivl_stmt_cond_expr(stmt), 0); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
if (true_stmt) { if (true_stmt) {
@ -1068,7 +1068,7 @@ static void emit_stmt_force(ivl_scope_t scope, ivl_statement_t stmt)
// done this for us. // done this for us.
wid = emit_stmt_lval(scope, stmt); wid = emit_stmt_lval(scope, stmt);
fprintf(vlog_out, " = "); fprintf(vlog_out, " = ");
emit_expr(scope, ivl_stmt_rval(stmt), wid); emit_expr(scope, ivl_stmt_rval(stmt), wid, 0);
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
fprintf(vlog_out, "\n"); fprintf(vlog_out, "\n");
@ -1115,7 +1115,7 @@ static void emit_stmt_release(ivl_scope_t scope, ivl_statement_t stmt)
static void emit_stmt_repeat(ivl_scope_t scope, ivl_statement_t stmt) static void emit_stmt_repeat(ivl_scope_t scope, ivl_statement_t stmt)
{ {
fprintf(vlog_out, "%*crepeat (", get_indent(), ' '); fprintf(vlog_out, "%*crepeat (", get_indent(), ' ');
emit_expr(scope, ivl_stmt_cond_expr(stmt), 0); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
single_indent = 1; single_indent = 1;
@ -1132,10 +1132,10 @@ static void emit_stmt_stask(ivl_scope_t scope, ivl_statement_t stmt)
count -= 1; count -= 1;
for (idx = 0; idx < count; idx += 1) { for (idx = 0; idx < count; idx += 1) {
ivl_expr_t expr = ivl_stmt_parm(stmt, idx); ivl_expr_t expr = ivl_stmt_parm(stmt, idx);
if (expr) emit_expr(scope, expr, 0); if (expr) emit_expr(scope, expr, 0, 0);
fprintf(vlog_out, ", "); fprintf(vlog_out, ", ");
} }
emit_expr(scope, ivl_stmt_parm(stmt, count), 0); emit_expr(scope, ivl_stmt_parm(stmt, count), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
} }
fprintf(vlog_out, ";"); fprintf(vlog_out, ";");
@ -1183,7 +1183,7 @@ static void emit_stmt_wait(ivl_scope_t scope, ivl_statement_t stmt)
static void emit_stmt_while(ivl_scope_t scope, ivl_statement_t stmt) static void emit_stmt_while(ivl_scope_t scope, ivl_statement_t stmt)
{ {
fprintf(vlog_out, "%*cwhile (", get_indent(), ' '); fprintf(vlog_out, "%*cwhile (", get_indent(), ' ');
emit_expr(scope, ivl_stmt_cond_expr(stmt), 0); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0);
fprintf(vlog_out, ")"); fprintf(vlog_out, ")");
emit_stmt_file_line(stmt); emit_stmt_file_line(stmt);
single_indent = 1; single_indent = 1;

View File

@ -66,7 +66,8 @@ extern unsigned allow_signed;
* Emit various Verilog types. * Emit various Verilog types.
*/ */
extern void emit_event(ivl_scope_t scope, ivl_statement_t stmt); extern void emit_event(ivl_scope_t scope, ivl_statement_t stmt);
extern void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned width); extern void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned width,
unsigned can_skip_unsigned);
extern void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic); extern void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic);
extern void emit_lpm(ivl_scope_t scope, ivl_lpm_t lpm); extern void emit_lpm(ivl_scope_t scope, ivl_lpm_t lpm);
extern void emit_process(ivl_scope_t scope, ivl_process_t proc); extern void emit_process(ivl_scope_t scope, ivl_process_t proc);