diff --git a/ivtest/ivltests/shift6.v b/ivtest/ivltests/shift6.v new file mode 100644 index 000000000..7dd09a75c --- /dev/null +++ b/ivtest/ivltests/shift6.v @@ -0,0 +1,51 @@ +module test; + +// Check that the right hand side for a shift instruction is always treated as +// unsigned. Even if its a signed register, or a transformation thereof. + + reg failed = 1'b0; + + `define check(val, exp) \ + if ((val) !== (exp)) begin \ + $display("FAILED(%0d): `%s`, expected `%0d`, got `%0d`.", `__LINE__, \ + `"val`", (exp), (val), 4); \ + failed = 1'b1; \ + end + + reg signed [1:0] shift = 2'b10; + + initial begin + `check(1 << shift, 4) + `check(1 << shift[1:0], 4) + `check(2 << shift[1], 4) + `check(1 << $unsigned(shift), 4) + `check(1 << $signed(shift), 4) + `check(1 << {shift}, 4) + + `check(1 <<< shift, 4) + `check(1 <<< shift[1:0], 4) + `check(2 <<< shift[1], 4) + `check(1 <<< $unsigned(shift), 4) + `check(1 <<< $signed(shift), 4) + `check(1 <<< {shift}, 4) + + `check(16 >> shift, 4) + `check(16 >> shift[1:0], 4) + `check(8 >> shift[1], 4) + `check(16 >> $unsigned(shift), 4) + `check(16 >> $signed(shift), 4) + `check(16 >> {shift}, 4) + + `check(16 >>> shift, 4) + `check(16 >>> shift[1:0], 4) + `check(8 >>> shift[1], 4) + `check(16 >>> $unsigned(shift), 4) + `check(16 >>> $signed(shift), 4) + `check(16 >>> {shift}, 4) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 53a18766b..1a63588fd 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -185,6 +185,7 @@ sf_countones_fail vvp_tests/sf_countones_fail.json sf_isunknown_fail vvp_tests/sf_isunknown_fail.json sf_onehot_fail vvp_tests/sf_onehot_fail.json sf_onehot0_fail vvp_tests/sf_onehot0_fail.json +shift6 vvp_tests/shift6.json single_element_array vvp_tests/single_element_array.json struct_enum_partsel vvp_tests/struct_enum_partsel.json struct_field_left_right vvp_tests/struct_field_left_right.json diff --git a/ivtest/vvp_tests/shift6.json b/ivtest/vvp_tests/shift6.json new file mode 100644 index 000000000..b88acf95c --- /dev/null +++ b/ivtest/vvp_tests/shift6.json @@ -0,0 +1,5 @@ + +{ + "type" : "normal", + "source" : "shift6.v" +} diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 443a821eb..4103bc735 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -226,12 +226,12 @@ void eval_logic_into_integer(ivl_expr_t expr, unsigned ix) reading index values directly from variables. In this case, try to use that special instruction. */ case IVL_EX_SIGNAL: { + const char*type = ivl_expr_signed(expr) ? "/s" : ""; ivl_signal_t sig = ivl_expr_signal(expr); unsigned word = 0; if (ivl_signal_dimensions(sig) > 0) { ivl_expr_t ixe; - const char*type = ivl_expr_signed(expr) ? "/s" : ""; /* Detect the special case that this is a variable array. In this case, the ix/getv @@ -252,7 +252,6 @@ void eval_logic_into_integer(ivl_expr_t expr, unsigned ix) break; } } - const char*type = ivl_signal_signed(sig) ? "/s" : ""; fprintf(vvp_out, " %%ix/getv%s %u, v%p_%u;\n", type, ix, sig, word); break;