Skip to content

Commit 680dbe3

Browse files
authored
Merge pull request #807 from diffblue/riscv-alu.sv
SystemVerilog: RISC-V ALU test
2 parents a56896e + a510a36 commit 680dbe3

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
riscv-alu.sv
3+
--module alu --bound 0
4+
^\[alu\.pADD\] always alu\.op == \{ 7'b0000000, 3'b000 \} -> alu\.out == alu\.a \+ alu\.b: PROVED up to bound 0$
5+
^\[alu\.pSUB\] always alu\.op == \{ 7'b0100000, 3'b000 \} -> alu\.out == alu\.a - alu\.b: PROVED up to bound 0$
6+
^\[alu\.pSLL\] always alu\.op == \{ 7'b0000000, 3'b001 \} -> alu\.out == alu\.a << alu\.b\[4:0\]: PROVED up to bound 0$
7+
^\[alu\.pSLT\] always alu\.op == \{ 7'b0000000, 3'b010 \} -> alu\.out == alu\.a < alu\.b: PROVED up to bound 0$
8+
^\[alu\.pSLTU\] always alu\.op == \{ 7'b0000000, 3'b011 \} -> alu\.out == alu\.a < alu\.b: PROVED up to bound 0$
9+
^\[alu\.pXOR\] always alu\.op == \{ 7'b0000000, 3'b100 \} -> alu\.out == \(alu\.a \^ alu\.b\): PROVED up to bound 0$
10+
^\[alu\.pSRL\] always alu\.op == \{ 7'b0000000, 3'b101 \} -> alu\.out == alu\.a >> alu\.b\[4:0\]: PROVED up to bound 0$
11+
^\[alu\.pSRA\] always alu\.op == \{ 7'b0100000, 3'b101 \} -> alu\.out == alu\.a >>> alu\.b\[4:0\]: PROVED up to bound 0$
12+
^\[alu\.pOR\] always alu\.op == \{ 7'b0000000, 3'b110 \} -> alu\.out == \(alu\.a | alu\.b\): PROVED up to bound 0$
13+
^\[alu\.pAND\] always alu\.op == \{ 7'b0000000, 3'b111 \} -> alu\.out == \(alu\.a & alu\.b\): PROVED up to bound 0$
14+
^EXIT=0$
15+
^SIGNAL=0$
16+
--
17+
^warning: ignoring
18+
--
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
module alu(
3+
input [2:0] func3,
4+
input [6:0] func7,
5+
input [63:0] a, b,
6+
output reg [63:0] out);
7+
8+
// https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
9+
// Page 104
10+
wire ADD = func7 == 'b0000000 & func3 == 'b000;
11+
wire SUB = func7 == 'b0100000 & func3 == 'b000;
12+
wire SLL = func7 == 'b0000000 & func3 == 'b001;
13+
wire SLT = func7 == 'b0000000 & func3 == 'b010;
14+
wire SLTU = func7 == 'b0000000 & func3 == 'b011;
15+
wire XOR = func7 == 'b0000000 & func3 == 'b100;
16+
wire SRL = func7 == 'b0000000 & func3 == 'b101;
17+
wire SRA = func7 == 'b0100000 & func3 == 'b101;
18+
wire OR = func7 == 'b0000000 & func3 == 'b110;
19+
wire AND = func7 == 'b0000000 & func3 == 'b111;
20+
21+
wire subtraction = SUB || SLT || SLTU;
22+
wire [64:0] a_ext = {SLT ? a[63] : 0, a};
23+
wire [64:0] b_ext = {SLT ? b[63] : 0, b};
24+
wire [64:0] b_inv = (subtraction?~b_ext:b_ext);
25+
wire [64:0] adder_out = a_ext + b_inv + subtraction;
26+
27+
always_comb case(1)
28+
ADD || SUB: out <= adder_out[63:0];
29+
SLL: out <= a << b[4:0];
30+
SLT || SLTU: out <= adder_out[64];
31+
XOR: out <= a ^ b;
32+
SRL: out <= a >> b[4:0];
33+
SRA: out <= $signed(a) >>> b[4:0];
34+
OR: out <= a | b;
35+
AND: out <= a & b;
36+
default: out <= 0;
37+
endcase
38+
39+
wire [9:0] op = {func7, func3};
40+
pADD: assert final (op == {7'b0000000, 3'b000} -> out == a + b);
41+
pSUB: assert final (op == {7'b0100000, 3'b000} -> out == a - b);
42+
pSLL: assert final (op == {7'b0000000, 3'b001} -> out == a << b[4:0]);
43+
pSLT: assert final (op == {7'b0000000, 3'b010} -> out == ($signed(a) < $signed(b)));
44+
pSLTU: assert final (op == {7'b0000000, 3'b011} -> out == (a < b));
45+
pXOR: assert final (op == {7'b0000000, 3'b100} -> out == (a ^ b));
46+
pSRL: assert final (op == {7'b0000000, 3'b101} -> out == a >> b[4:0]);
47+
pSRA: assert final (op == {7'b0100000, 3'b101} -> out == $signed(a) >>> b[4:0]);
48+
pOR: assert final (op == {7'b0000000, 3'b110} -> out == (a | b));
49+
pAND: assert final (op == {7'b0000000, 3'b111} -> out == (a & b));
50+
51+
endmodule

0 commit comments

Comments
 (0)