Add regression tests for SystemVerilog sign cast

Check that SystemVerilog sign cast are supported correctly. The regression
tests are modeled after the existing tests for $unsigned/$signed.

They check that
 * Width extension is done correctly on the cast expression
 * Expressions in the sign cast are evaluated as self-determined

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-09-11 17:57:31 +02:00
parent a73ee3e3e7
commit 8315b82f40
5 changed files with 185 additions and 0 deletions

View File

@ -0,0 +1,30 @@
// Check that sign casts have the expected results when the value gets width
// extended.
module test;
bit failed = 1'b0;
reg [7:0] val;
reg signed [7:0] sval;
`define check(val, exp) \
if (exp !== val) begin \
$display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \
failed = 1'b1; \
end
initial begin
// An unsized number has an implicit width of integer width.
val = unsigned'(-4);
`check(val, 8'hfc);
val = unsigned'(-4'sd4);
`check(val, 8'h0c);
sval = signed'(4'hc);
`check(sval, -4);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,74 @@
// Check that unsigned arguments to a sign cast are evaluated as self-determined.
module test;
reg [3:0] op1;
reg [2:0] op2;
reg [7:0] result;
bit failed = 1'b0;
`define check(val, exp) \
if (exp !== val) begin \
$display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \
failed = 1'b1; \
end
initial begin
// Addition tests
op1 = 4'b1111; op2 = 3'b111;
result = 8'sd0 + signed'(op1 + op2);
`check(result, 8'b00000110);
result = 8'sd0 + unsigned'(op1 + op2);
`check(result, 8'b00000110);
op1 = 4'b1000; op2 = 3'b011;
result = 8'sd0 + signed'(op1 + op2);
`check(result, 8'b11111011);
result = 8'sd0 + unsigned'(op1 + op2);
`check(result, 8'b00001011);
// Multiply tests
op1 = 4'b0101; op2 = 3'b100;
result = 8'sd0 + signed'(op1 * op2);
`check(result, 8'b00000100);
result = 8'sd0 + unsigned'(op1 * op2);
`check(result, 8'b00000100);
op1 = 4'b0010; op2 = 3'b100;
result = 8'sd0 + signed'(op1 * op2);
`check(result, 8'b11111000);
result = 8'sd0 + unsigned'(op1 * op2);
`check(result, 8'b00001000);
// Left ASR tests
op1 = 4'b1010;
result = 8'sd0 + signed'(op1 <<< 1);
`check(result, 8'b00000100);
result = 8'sd0 + unsigned'(op1 <<< 1);
`check(result, 8'b00000100);
op1 = 4'b0101;
result = 8'sd0 + signed'(op1 <<< 1);
`check(result, 8'b11111010);
result = 8'sd0 + unsigned'(op1 <<< 1);
`check(result, 8'b00001010);
// Right ASR tests
op1 = 4'b1010;
result = 8'sd0 + signed'(op1 >>> 1);
`check(result, 8'b00000101);
result = 8'sd0 + unsigned'(op1 >>> 1);
`check(result, 8'b00000101);
op1 = 4'b1010;
result = 8'sd0 + signed'(op1 >>> 0);
`check(result, 8'b11111010);
result = 8'sd0 + unsigned'(op1 >>> 0);
`check(result, 8'b00001010);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,75 @@
// Check that signed arguments to a sign cast are evaluated as self-determined.
module test;
reg signed [3:0] op1;
reg signed [2:0] op2;
reg [7:0] result;
bit failed = 1'b0;
`define check(val, exp) \
if (exp !== val) begin \
$display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \
failed = 1'b1; \
end
initial begin
// Addition tests
op1 = 4'b1111; op2 = 3'b111;
result = 8'sd0 + signed'(op1 + op2);
`check(result, 8'b11111110);
result = 8'sd0 + unsigned'(op1 + op2);
`check(result, 8'b00001110);
op1 = 4'b1000; op2 = 3'b011;
result = 8'sd0 + signed'(op1 + op2);
`check(result, 8'b11111011);
result = 8'sd0 + unsigned'(op1 + op2);
`check(result, 8'b00001011);
// Multiply tests
op1 = 4'b0101; op2 = 3'b100;
result = 8'sd0 + signed'(op1 * op2);
`check(result, 8'b11111100);
result = 8'sd0 + unsigned'(op1 * op2);
`check(result, 8'b00001100);
op1 = 4'b0010; op2 = 3'b100;
result = 8'sd0 + signed'(op1 * op2);
`check(result, 8'b11111000);
result = 8'sd0 + unsigned'(op1 * op2);
`check(result, 8'b00001000);
// Left ASR tests
op1 = 4'b1010;
result = 8'sd0 + signed'(op1 <<< 1);
`check(result, 8'b00000100);
result = 8'sd0 + unsigned'(op1 <<< 1);
`check(result, 8'b00000100);
op1 = 4'b0101;
result = 8'sd0 + signed'(op1 <<< 1);
`check(result, 8'b11111010);
result = 8'sd0 + unsigned'(op1 <<< 1);
`check(result, 8'b00001010);
// Right ASR tests
op1 = 4'b0101;
result = 8'sd0 + signed'(op1 >>> 1);
`check(result, 8'b00000010);
result = 8'sd0 + unsigned'(op1 >>> 1);
`check(result, 8'b00000010);
op1 = 4'b1010;
result = 8'sd0 + signed'(op1 >>> 1);
`check(result, 8'b11111101);
result = 8'sd0 + unsigned'(op1 >>> 1);
`check(result, 8'b00001101);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -628,6 +628,9 @@ sv_queue_vec_fail CE,-g2009 ivltests gold=sv_queue_vec_fail.gold
sv_root_class normal,-g2009 ivltests gold=sv_root_class.gold
sv_root_func normal,-g2009 ivltests gold=sv_root_func.gold
sv_root_task normal,-g2009 ivltests gold=sv_root_task.gold
sv_sign_cast1 normal,-g2005-sv ivltests
sv_sign_cast2 normal,-g2005-sv ivltests
sv_sign_cast3 normal,-g2005-sv ivltests
sv_string1 normal,-g2009 ivltests
sv_string2 normal,-g2009 ivltests
sv_string3 normal,-g2009 ivltests

View File

@ -1034,6 +1034,9 @@ shift4 normal,-pallowsigned=1 ivltests
signed5 normal,-pallowsigned=1 ivltests
signed10 normal,-pallowsigned=1 ivltests gold=signed10.gold
signed13 normal,-pallowsigned=1 ivltests
sv_sign_cast1 normal,-g2005-sv,-pallowsigned=1 ivltests
sv_sign_cast2 normal,-g2005-sv,-pallowsigned=1 ivltests
sv_sign_cast3 normal,-g2005-sv,-pallowsigned=1 ivltests
# Also tests have different output because of file name/line, etc. differences.
readmem-error normal,-pallowsigned=1 ivltests gold=readmem-error-vlog95.gold