From eecc3312b732c6e7ae2c7d9d87b91e5f6d538b29 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 27 Jun 2013 13:20:16 -0700 Subject: [PATCH] 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. --- tgt-vlog95/expr.c | 135 ++++++++++++++++++++++----------------- tgt-vlog95/misc.c | 8 +-- tgt-vlog95/scope.c | 2 +- tgt-vlog95/stmt.c | 42 ++++++------ tgt-vlog95/vlog95_priv.h | 3 +- 5 files changed, 105 insertions(+), 85 deletions(-) diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index c06e2b5b4..9e7e000c3 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -48,7 +48,7 @@ static unsigned emit_power_as_shift(ivl_scope_t scope, ivl_expr_t expr, if (value % 2) return 0; /* Generate the appropriate conversion. */ if (ivl_expr_signed(rval)) { - emit_expr(scope, rval, 0); + emit_expr(scope, rval, 0, 0); fprintf(vlog_out, " < 0 ? %u'h0 : (", expr_wid); 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, " * "); } - emit_expr(scope, rval, 0); + emit_expr(scope, rval, 0, 0); if (scale != 1) fprintf(vlog_out, ")"); if (is_signed_rval) fprintf(vlog_out, ")"); 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) { char *oper = ""; + 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)) { 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 'X': - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, can_skip_unsigned); fprintf(vlog_out, " %s ", oper); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, can_skip_unsigned); break; case 'a': case 'o': - emit_expr(scope, ivl_expr_oper1(expr), 0); + emit_expr(scope, oper1, 0, can_skip_unsigned); fprintf(vlog_out, " %s ", oper); - emit_expr(scope, ivl_expr_oper2(expr), 0); + emit_expr(scope, oper2, 0, can_skip_unsigned); break; case 'R': 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 'r': - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, 0); fprintf(vlog_out, " %s ", oper); - emit_expr(scope, ivl_expr_oper2(expr), 0); + emit_expr(scope, oper2, 0, 0); break; case 'A': case 'O': fprintf(vlog_out, "~("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, can_skip_unsigned); fprintf(vlog_out, " %s ", oper); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, can_skip_unsigned); fprintf(vlog_out, ")"); break; case 'p': 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, " ** "); - 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 " "supported.\n", 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. */ if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min("); else fprintf(vlog_out, "$max("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, 0); fprintf(vlog_out, ","); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, 0); fprintf(vlog_out, ")"); } else { /* This only works when the argument has no side effect. */ fprintf(vlog_out, "(("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, 0); fprintf(vlog_out, ") %s (", oper); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, 0); fprintf(vlog_out, ") ? ("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, 0); fprintf(vlog_out, ") : ("); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, 0); fprintf(vlog_out, "))"); } break; default: - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, oper1, wid, 0); fprintf(vlog_out, ""); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, 0); fprintf(stderr, "%s:%u: vlog95 error: Unknown expression " "operator (%c).\n", 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, "{"); count -= 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, ", "); } - emit_expr(scope, ivl_expr_parm(expr, count), 0); + emit_expr(scope, ivl_expr_parm(expr, count), 0, 0); 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)); vlog_errors += 1; } 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) { emit_select_name(scope, sig_expr, wid); fprintf(vlog_out, "["); - emit_expr(scope, sel_expr, 0); + emit_expr(scope, sel_expr, 0, 0); fprintf(vlog_out, " + %u], ", idx); } emit_select_name(scope, sig_expr, wid); fprintf(vlog_out, "["); - emit_expr(scope, sel_expr, 0); + emit_expr(scope, sel_expr, 0, 0); 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); emit_select_name(scope, sig_expr, wid); fprintf(vlog_out, "["); - emit_expr(scope, sel_expr, 0); + emit_expr(scope, sel_expr, 0, 0); fprintf(vlog_out, "]"); return; } @@ -552,7 +557,7 @@ static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) } } else { // 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. */ if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) && (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, "("); count -= 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, ", "); } - emit_expr(scope, ivl_expr_parm(expr, count), 0); + emit_expr(scope, ivl_expr_parm(expr, count), 0, 0); fprintf(vlog_out, ")"); /* User functions without arguments are not supported. */ } 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) { + 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, "("); - emit_expr(scope, ivl_expr_oper1(expr), 0); + emit_expr(scope, ivl_expr_oper1(expr), 0, 0); fprintf(vlog_out, " ? "); - emit_expr(scope, ivl_expr_oper2(expr), wid); + emit_expr(scope, oper2, wid, can_skip_unsigned); fprintf(vlog_out, " : "); - emit_expr(scope, ivl_expr_oper3(expr), wid); + emit_expr(scope, oper3, wid, can_skip_unsigned); 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 '!': 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, ")"); break; case '2': case 'v': case 'r': /* A cast is a noop. */ - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); break; case 'I': fprintf(vlog_out, "(++"); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 sorry: Pre-increment " "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; case 'i': fprintf(vlog_out, "("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, "++)"); fprintf(stderr, "%s:%u: vlog95 sorry: Post-increment " "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; case 'D': fprintf(vlog_out, "(--"); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 sorry: Pre-decrement " "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; case 'd': fprintf(vlog_out, "("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, "--)"); fprintf(stderr, "%s:%u: vlog95 sorry: Post-decrement " "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) { /* For a real expression use the $abs() function. */ fprintf(vlog_out, "$abs("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, ")"); } else { /* This only works when the argument has no side effect. */ fprintf(vlog_out, "(("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 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, ") : -("); - emit_expr(scope, ivl_expr_oper1(expr), wid); + emit_expr(scope, ivl_expr_oper1(expr), wid, 0); fprintf(vlog_out, "))"); } break; default: fprintf(vlog_out, ""); - 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 " "operator (%c).\n", ivl_expr_file(expr), @@ -808,6 +817,20 @@ static expr_sign_t get_select_sign_type(ivl_expr_t expr) 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) { ivl_expr_t expr1; @@ -861,13 +884,11 @@ static expr_sign_t get_unary_sign_type(ivl_expr_t expr) 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; switch (ivl_expr_type(expr)) { - case IVL_EX_ARRAY: - break; case IVL_EX_BINARY: rtn = get_binary_sign_type(expr); break; @@ -876,22 +897,15 @@ expr_sign_t get_sign_type(ivl_expr_t expr) * needed. */ if (ivl_expr_signed(expr)) rtn = NEED_SIGNED; break; - case IVL_EX_NUMBER: - break; case IVL_EX_PROPERTY: break; - case IVL_EX_REALNUM: - break; - case IVL_EX_SCOPE: - break; case IVL_EX_SELECT: rtn = get_select_sign_type(expr); break; case IVL_EX_SFUNC: break; case IVL_EX_SIGNAL: - break; - case IVL_EX_STRING: + rtn = get_signal_sign_type(expr, can_skip_unsigned); break; case IVL_EX_TERNARY: break; @@ -901,22 +915,27 @@ expr_sign_t get_sign_type(ivl_expr_t expr) rtn = get_unary_sign_type(expr); break; /* These do not have/need sign casting information. */ + case IVL_EX_ARRAY: case IVL_EX_DELAY: case IVL_EX_ENUMTYPE: case IVL_EX_EVENT: case IVL_EX_NEW: case IVL_EX_NULL: + case IVL_EX_NUMBER: + case IVL_EX_REALNUM: + case IVL_EX_SCOPE: case IVL_EX_SHALLOWCOPY: -// HERE: Do the array, property, real number or string belong here as well? + case IVL_EX_STRING: default: break; } 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 * before the expression. */ @@ -1002,7 +1021,7 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) break; case IVL_EX_SHALLOWCOPY: fprintf(vlog_out, " "); - 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 " "is not supported.\n", ivl_expr_file(expr), diff --git a/tgt-vlog95/misc.c b/tgt-vlog95/misc.c index d12218b40..1688ba2b8 100644 --- a/tgt-vlog95/misc.c +++ b/tgt-vlog95/misc.c @@ -74,7 +74,7 @@ static void emit_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt) 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); } else if (lsb == 0) { /* If the LSB is zero then there is no scale. */ - emit_expr(scope, expr, 0); + emit_expr(scope, expr, 0, 0); } else { 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 { @@ -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); } else { if (is_scaled_expr(expr, msb, lsb)) { - emit_expr(scope, ivl_expr_oper2(expr), 0); + emit_expr(scope, ivl_expr_oper2(expr), 0, 0); } } } diff --git a/tgt-vlog95/scope.c b/tgt-vlog95/scope.c index 0a3ea0561..200d1b4cc 100644 --- a/tgt-vlog95/scope.c +++ b/tgt-vlog95/scope.c @@ -312,7 +312,7 @@ void emit_scope_variables(ivl_scope_t scope) fprintf(vlog_out, "%*cparameter ", indent, ' '); emit_id(ivl_parameter_basename(par)); fprintf(vlog_out, " = "); - emit_expr(scope, pex, 0); + emit_expr(scope, pex, 0, 0); fprintf(vlog_out, ";"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", diff --git a/tgt-vlog95/stmt.c b/tgt-vlog95/stmt.c index 695299bd3..b68f4a6f0 100644 --- a/tgt-vlog95/stmt.c +++ b/tgt-vlog95/stmt.c @@ -69,7 +69,7 @@ static void emit_stmt_inter_delay(ivl_scope_t scope, ivl_statement_t stmt) } } else { fprintf(vlog_out, "repeat("); - emit_expr(scope, count, 0); + emit_expr(scope, count, 0, 0); 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) { emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); - emit_expr(scope, sel_expr, 0); + emit_expr(scope, sel_expr, 0, 0); fprintf(vlog_out, " + %u], ", idx); } emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); - emit_expr(scope, sel_expr, 0); + emit_expr(scope, sel_expr, 0, 0); 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)); if (idx) { fprintf(vlog_out, "["); - emit_expr(scope, idx, 0); + emit_expr(scope, idx, 0, 0); fprintf(vlog_out, "]"); } } @@ -375,7 +375,7 @@ static unsigned is_delayed_or_event_assign(ivl_scope_t scope, emit_event(scope, delay); } fprintf(vlog_out, ") "); - emit_expr(scope, ivl_stmt_rval(assign), wid); + emit_expr(scope, ivl_stmt_rval(assign), wid, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); 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; } } - 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); fprintf(vlog_out, "; "); /* 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, "; "); /* Emit the increment statement (an opcode is allowed). */ 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, " ="); if (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, " @("); emit_event(scope, event); fprintf(vlog_out, ") "); - emit_expr(scope, ivl_stmt_rval(assign), wid); + emit_expr(scope, ivl_stmt_rval(assign), wid, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); 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. */ 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, ")"); emit_stmt_file_line(stmt); 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) { 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 { /* This is a self-determined context so we don't care about * 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); fprintf(vlog_out, " <= "); 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, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); @@ -940,7 +940,7 @@ static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt) assert(0); } 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, ")"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); @@ -955,7 +955,7 @@ static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt) continue; } fprintf(vlog_out, "%*c", get_indent(), ' '); - emit_expr(scope, expr, 0); + emit_expr(scope, expr, 0, 0); fprintf(vlog_out, ":"); single_indent = 1; 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. wid = emit_stmt_lval(scope, stmt); fprintf(vlog_out, " = "); - emit_expr(scope, ivl_stmt_rval(stmt), wid); + emit_expr(scope, ivl_stmt_rval(stmt), wid, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); 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); unsigned nest = 0; 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, ")"); emit_stmt_file_line(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. wid = emit_stmt_lval(scope, stmt); fprintf(vlog_out, " = "); - emit_expr(scope, ivl_stmt_rval(stmt), wid); + emit_expr(scope, ivl_stmt_rval(stmt), wid, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); 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) { 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, ")"); emit_stmt_file_line(stmt); single_indent = 1; @@ -1132,10 +1132,10 @@ static void emit_stmt_stask(ivl_scope_t scope, ivl_statement_t stmt) count -= 1; for (idx = 0; idx < count; idx += 1) { 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, ", "); } - 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, ";"); @@ -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) { 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, ")"); emit_stmt_file_line(stmt); single_indent = 1; diff --git a/tgt-vlog95/vlog95_priv.h b/tgt-vlog95/vlog95_priv.h index 1625074da..917946118 100644 --- a/tgt-vlog95/vlog95_priv.h +++ b/tgt-vlog95/vlog95_priv.h @@ -66,7 +66,8 @@ extern unsigned allow_signed; * Emit various Verilog types. */ 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_lpm(ivl_scope_t scope, ivl_lpm_t lpm); extern void emit_process(ivl_scope_t scope, ivl_process_t proc);