From 8315b82f403ea373681e31926b785b4c6856872c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 11 Sep 2022 17:57:31 +0200 Subject: [PATCH] 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 --- ivtest/ivltests/sv_sign_cast1.v | 30 +++++++++++++ ivtest/ivltests/sv_sign_cast2.v | 74 ++++++++++++++++++++++++++++++++ ivtest/ivltests/sv_sign_cast3.v | 75 +++++++++++++++++++++++++++++++++ ivtest/regress-sv.list | 3 ++ ivtest/regress-vlog95.list | 3 ++ 5 files changed, 185 insertions(+) create mode 100644 ivtest/ivltests/sv_sign_cast1.v create mode 100644 ivtest/ivltests/sv_sign_cast2.v create mode 100644 ivtest/ivltests/sv_sign_cast3.v diff --git a/ivtest/ivltests/sv_sign_cast1.v b/ivtest/ivltests/sv_sign_cast1.v new file mode 100644 index 000000000..7699a880c --- /dev/null +++ b/ivtest/ivltests/sv_sign_cast1.v @@ -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 diff --git a/ivtest/ivltests/sv_sign_cast2.v b/ivtest/ivltests/sv_sign_cast2.v new file mode 100644 index 000000000..313d2aeee --- /dev/null +++ b/ivtest/ivltests/sv_sign_cast2.v @@ -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 diff --git a/ivtest/ivltests/sv_sign_cast3.v b/ivtest/ivltests/sv_sign_cast3.v new file mode 100644 index 000000000..ae38d3a7b --- /dev/null +++ b/ivtest/ivltests/sv_sign_cast3.v @@ -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 diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index c01b065bb..1fa5ad77a 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -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 diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 0f0b72526..88f865357 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -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