tgt-vlog95: Use concatenation for unsigned expression contexts
The vlog95 backend currently emits `$unsigned()` when it needs to create a
self-determined unsigned expression context. `$unsigned()` is part of the
optional signed expression support in this backend and is only available when
the signed support flag is enabled.
Concatenation is part of the baseline Verilog-95 output and also creates a
self-determined unsigned expression context. Use `{expr}` for the unsigned case
and keep using `$signed()` when a signed context is needed.
Remove `-pallowsigned=1` from the existing vlog95 regression tests that now
pass without the optional signed support flag.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
daadc38f18
commit
e75b0d7968
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue