diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 3f82374c8..8222197cc 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -603,10 +603,10 @@ br_gh219 EF,-g2009,-pallowsigned=1 ivltests # creates a CA for the part select, but has nothing to connect it to. # It leaves the gate output unconnected. rise_fall_decay2 CE ivltests -# The code generator is generating unnecessary calls to $unsigned. +# The code generator emits signed casts for this test. array_packed_2d normal,-g2009,-pallowsigned=1 ivltests gold=array_packed_2d.gold -br_gh112c normal,-g2009,-pallowsigned=1 ivltests -br_gh112d normal,-g2009,-pallowsigned=1 ivltests +br_gh112c normal,-g2009 ivltests +br_gh112d normal,-g2009 ivltests # This generates a very larg (65536 bit) constant, and the parser can't cope. br_gh162 TE ivltests @@ -827,7 +827,7 @@ writemem-error normal ivltests gold=writemem-error-vlog95.gold # For Verilog 95 signed is supported as an option (-pallowsigned=1). array6 normal,-pallowsigned=1 ivltests -assign_op_oob normal,-g2009,-pallowsigned=1 ivltests +assign_op_oob normal,-g2009 ivltests assign_op_type normal,-g2009,-pallowsigned=1 ivltests bitp1 normal,-g2009,-pallowsigned=1 ivltests bits normal,-g2009,-pallowsigned=1 ivltests @@ -867,8 +867,8 @@ br_gh1237 normal,-pallowsigned=1 ivltests ca_mult normal,-pallowsigned=1 ivltests gold=ca_mult.gold cast_int normal,-pallowsigned=1 ivltests cfunc_assign_op_vec normal,-g2009,-pallowsigned=1 ivltests -constfunc4 normal,-pallowsigned=1 ivltests -constfunc6 normal,-pallowsigned=1 ivltests +constfunc4 normal ivltests +constfunc6 normal ivltests constfunc7 normal,-pallowsigned=1 ivltests constfunc13 normal,-pallowsigned=1 ivltests constfunc14 normal,-pallowsigned=1 ivltests @@ -909,7 +909,7 @@ pr1793749 normal,-pallowsigned=1 ivltests gold=pr1793749.gold pr1879226 normal,-pallowsigned=1 ivltests pr1883052 normal,-pallowsigned=1 ivltests pr1883052b normal,-pallowsigned=1 ivltests -pr1950282 normal,-pallowsigned=1 ivltests +pr1950282 normal ivltests pr1958801 normal,-pallowsigned=1 ivltests pr1993479 normal,-pallowsigned=1 ivltests gold=pr1993479.gold pr2030767 normal,-pallowsigned=1 ivltests @@ -959,7 +959,7 @@ simple_byte normal,-g2009,-pallowsigned=1 ivltests simple_int normal,-g2009,-pallowsigned=1 ivltests simple_longint normal,-g2009,-pallowsigned=1 ivltests simple_shortint normal,-g2009,-pallowsigned=1 ivltests -size_cast3 normal,-g2009,-pallowsigned=1 ivltests +size_cast3 normal,-g2009 ivltests size_cast5 normal,-g2009,-pallowsigned=1 ivltests struct_member_signed normal,-g2009,-pallowsigned=1 ivltests struct_packed_array normal,-g2009,-pallowsigned=1 ivltests diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index 3b6a18623..22296de3e 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -26,7 +26,8 @@ ivl_parameter_t emitting_param = 0; /* - * Data type used to signify if a $signed or $unsigned should be emitted. + * Data type used to signify whether to emit $signed() or wrap the + * expression in a concatenation for an unsigned self-determined context. */ typedef enum expr_sign_e { NO_SIGN = 0, @@ -77,7 +78,7 @@ static expr_sign_t expr_get_binary_sign_type(ivl_expr_t expr) break; } - /* Check to see if a $signed() or $unsigned() is needed. */ + /* Check to see if the expression sign needs to be forced. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign) rtn = NEED_UNSIGNED; @@ -97,11 +98,11 @@ static expr_sign_t expr_get_select_sign_type(ivl_expr_t expr, ivl_expr_t oper1 = ivl_expr_oper1(expr); opr_sign = ivl_expr_signed(oper1); /* If the expression being padded is not a signal then don't - * skip a soft $unsigned() (from the binary operator). */ + * skip the soft unsigned context from the binary operator. */ if (ivl_expr_type(oper1) != IVL_EX_SIGNAL) can_skip_unsigned -= 1; } - /* Check to see if a $signed() or $unsigned() is needed. */ + /* Check to see if the expression sign needs to be forced. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; @@ -115,7 +116,7 @@ static expr_sign_t expr_get_signal_sign_type(ivl_expr_t expr, int expr_sign = ivl_expr_signed(expr); expr_sign_t rtn = NO_SIGN; - /* Check to see if a $signed() or $unsigned() is needed. */ + /* Check to see if the expression sign needs to be forced. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; @@ -210,10 +211,10 @@ static unsigned expr_is_binary_self_det(ivl_expr_t expr) } /* - * Determine if a $signed() or $unsigned() system function is needed to get + * Determine if $signed() or a single-element concatenation is needed to get * the expression sign information correct. can_skip_unsigned may be set for - * the binary/ternary operators if one of the operands will implicitly cast - * the expression to unsigned. See calc_can_skip_unsigned() for the details. + * the binary/ternary operators if one of the operands will implicitly make + * the expression unsigned. See calc_can_skip_unsigned() for the details. */ static expr_sign_t expr_get_sign_type(ivl_expr_t expr, unsigned wid, unsigned can_skip_unsigned, @@ -399,8 +400,8 @@ static unsigned calc_can_skip_unsigned(ivl_expr_t oper1, ivl_expr_t oper2) oper2_signed |= (ivl_expr_type(oper2) == IVL_EX_SELECT) && (! ivl_expr_oper2(oper2)) && (ivl_expr_signed(ivl_expr_oper1(oper2))); - /* If either operand is a hard unsigned skip adding an explicit - * $unsigned() since it will be added implicitly. */ + /* If either operand is hard unsigned, the operator result is already + * unsigned so skip adding an explicit unsigned context. */ return ! oper1_signed || ! oper2_signed; } @@ -1145,7 +1146,7 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, sign_type = expr_get_sign_type(expr, wid, can_skip_unsigned, is_full_prec); - /* Check to see if a $signed() or $unsigned() needs to be emitted + /* Check to see if a $signed() or concatenation needs to be emitted * before the expression. */ if (sign_type == NEED_SIGNED) { fprintf(vlog_out, "$signed("); @@ -1161,14 +1162,8 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, is_full_prec = 0; } if (sign_type == NEED_UNSIGNED) { - fprintf(vlog_out, "$unsigned("); - if (! allow_signed) { - fprintf(stderr, "%s:%u: vlog95 error: $unsigned() is not " - "supported.\n", - ivl_expr_file(expr), ivl_expr_lineno(expr)); - vlog_errors += 1; - } - /* A $unsigned() creates a self-determined context. */ + fprintf(vlog_out, "{"); + /* A `{x}` creates a self-determined context. */ wid = 0; /* It also clears the full precision flag. */ is_full_prec = 0; @@ -1276,6 +1271,15 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, vlog_errors += 1; break; } - /* Close the $signed() or $unsigned() if need. */ - if (sign_type != NO_SIGN) fprintf(vlog_out, ")"); + /* Close the $signed() or concatenation if needed. */ + switch (sign_type) { + case NEED_SIGNED: + fprintf(vlog_out, ")"); + break; + case NEED_UNSIGNED: + fprintf(vlog_out, "}"); + break; + default: + break; + } } diff --git a/tgt-vlog95/logic_lpm.c b/tgt-vlog95/logic_lpm.c index 93c18c266..f8950bb65 100644 --- a/tgt-vlog95/logic_lpm.c +++ b/tgt-vlog95/logic_lpm.c @@ -22,7 +22,8 @@ # include "vlog95_priv.h" /* - * Data type used to signify if a $signed or $unsigned should be emitted. + * Data type used to signify whether to emit $signed() or wrap the + * expression in a concatenation for an unsigned self-determined context. */ typedef enum lpm_sign_e { NO_SIGN = 0, @@ -119,7 +120,7 @@ static lpm_sign_t lpm_get_sign_type(ivl_lpm_t lpm, break; } - /* Check to see if a $signed() or $unsigned() is needed. */ + /* Check to see if the expression sign needs to be forced. */ if (lpm_sign && ! opr_sign) rtn = NEED_SIGNED; if (! lpm_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; @@ -1173,7 +1174,7 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm, unsigned sign_extend) { lpm_sign_t sign_type; - /* Check to see if a $signed() or $unsigned() needs to be emitted + /* Check to see if a $signed() or concatenation needs to be emitted * before the expression. */ sign_type = lpm_get_sign_type(lpm, 0); if (sign_type == NEED_SIGNED) { @@ -1185,14 +1186,9 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm, vlog_errors += 1; } } + /* A concatenation creates a self-determined unsigned context */ if (sign_type == NEED_UNSIGNED) { - fprintf(vlog_out, "$unsigned("); - if (! allow_signed) { - fprintf(stderr, "%s:%u: vlog95 error: $unsigned() is not " - "supported.\n", - ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); - vlog_errors += 1; - } + fprintf(vlog_out, "{"); } switch (ivl_lpm_type(lpm)) { @@ -1472,8 +1468,17 @@ static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm, vlog_errors += 1; } - /* Close the $signed() or $unsigned() if needed. */ - if (sign_type != NO_SIGN) fprintf(vlog_out, ")"); + /* Close the $signed() or concatenation if needed. */ + switch (sign_type) { + case NEED_SIGNED: + fprintf(vlog_out, ")"); + break; + case NEED_UNSIGNED: + fprintf(vlog_out, "}"); + break; + default: + break; + } } static void emit_posedge_dff_prim(void)