Add: named parameter for ALU func | alu test case

This commit is contained in:
brice.boisson 2023-10-24 10:49:29 +09:00
parent 5829400fea
commit b99914f42d
4 changed files with 135 additions and 28 deletions

View File

@ -2,17 +2,20 @@ module alu (input [31:0] in_a, in_b,
input [3:0] op_code, input [3:0] op_code,
output reg [31:0] out); output reg [31:0] out);
`include "alu_func.vh"
always@ (*) begin always@ (*) begin
case (op_code) case (op_code)
4'b0000 : out <= in_a + in_b; ADD : out <= in_a + in_b;
4'b0001 : out <= in_a - in_b; SUB : out <= in_a - in_b;
4'b0010 : out <= in_a << in_b; SLL : out <= in_a << in_b;
4'b0011 : out <= (in_a < in_b) ? 1 : 0; SLT : out <= ((in_a[31] != in_b[31]) ? in_a[31] == 1'b1 : in_a < in_b) ? 1 : 0;
4'b0100 : out <= in_a ^ in_b; SLTU : out <= (in_a < in_b) ? 1 : 0;
4'b0101 : out <= in_a >> in_b; XOR : out <= in_a ^ in_b;
4'b0111 : out <= in_a >>> in_b; SRL : out <= in_a >> in_b;
4'b1000 : out <= in_a | in_b; SRA : out <= in_a >>> in_b;
4'b1001 : out <= in_a & in_b; OR : out <= in_a | in_b;
AND : out <= in_a & in_b;
default : out <= 32'b0; default : out <= 32'b0;
endcase endcase
end end

10
rtl/alu_func.vh Normal file
View File

@ -0,0 +1,10 @@
parameter [3:0] ADD = 4'b0000;
parameter [3:0] SUB = 4'b0001;
parameter [3:0] SLL = 4'b0010;
parameter [3:0] SLT = 4'b0011;
parameter [3:0] SLTU = 4'b0100;
parameter [3:0] XOR = 4'b0101;
parameter [3:0] SRL = 4'b0110;
parameter [3:0] SRA = 4'b0111;
parameter [3:0] OR = 4'b1000;
parameter [3:0] AND = 4'b1001;

View File

@ -10,19 +10,19 @@ module decoder (input [31:0] instruction,
output reg pc_is_jmp, alu_not); output reg pc_is_jmp, alu_not);
`include "op_code.vh" `include "op_code.vh"
`include "alu_func.vh"
function [3:0] get_alu_func(input [2:0] op_code, input arithmetic); function [3:0] get_alu_func(input [2:0] op_code, input arithmetic);
begin begin
case (op_code) case (op_code)
3'b000 : get_alu_func = arithmetic ? 4'b0001 : 4'b0000; 3'b000 : get_alu_func = arithmetic ? SUB : ADD;
3'b001 : get_alu_func = 4'b0010; 3'b001 : get_alu_func = SLL;
3'b010 : get_alu_func = 4'b0011; 3'b010 : get_alu_func = SLT;
3'b011 : get_alu_func = 4'b0011; 3'b011 : get_alu_func = SLTU;
3'b100 : get_alu_func = 4'b0100; 3'b100 : get_alu_func = XOR;
3'b101 : get_alu_func = arithmetic ? 4'b0111 : 4'b0101; 3'b101 : get_alu_func = arithmetic ? SRA : SRL;
3'b110 : get_alu_func = 4'b1000; 3'b110 : get_alu_func = OR;
3'b111 : get_alu_func = 4'b1010; 3'b111 : get_alu_func = AND;
3'b111 : get_alu_func = 4'b1011;
default : get_alu_func= 4'b0000; default : get_alu_func= 4'b0000;
endcase endcase
end end
@ -31,15 +31,14 @@ endfunction
function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic); function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic);
begin begin
case (op_code) case (op_code)
3'b000 : get_alu_func_imm = 4'b0000; 3'b000 : get_alu_func_imm = ADD;
3'b001 : get_alu_func_imm = 4'b0010; 3'b001 : get_alu_func_imm = SLL;
3'b010 : get_alu_func_imm = 4'b0011; 3'b010 : get_alu_func_imm = SLT;
3'b011 : get_alu_func_imm = 4'b0100; 3'b011 : get_alu_func_imm = SLTU;
3'b100 : get_alu_func_imm = 4'b0101; 3'b100 : get_alu_func_imm = XOR;
3'b101 : get_alu_func_imm = arithmetic ? 4'b1000 : 4'b0111; 3'b101 : get_alu_func_imm = arithmetic ? SRA : SRL;
3'b110 : get_alu_func_imm = 4'b1001; 3'b110 : get_alu_func_imm = OR;
3'b111 : get_alu_func_imm = 4'b1010; 3'b111 : get_alu_func_imm = AND;
3'b111 : get_alu_func_imm = 4'b1011;
default : get_alu_func_imm = 4'b0000; default : get_alu_func_imm = 4'b0000;
endcase endcase
end end

View File

@ -2,6 +2,8 @@
`include "tb_tools.vh" `include "tb_tools.vh"
module tb_alu (); module tb_alu ();
`include "../rtl/alu_func.vh"
reg [31:0] in_a; reg [31:0] in_a;
reg [31:0] in_b; reg [31:0] in_b;
reg [3:0] op_code; reg [3:0] op_code;
@ -15,9 +17,10 @@ module tb_alu ();
); );
initial begin initial begin
// ALU - Add
in_a = 32'b0; in_a = 32'b0;
in_b = 32'b0; in_b = 32'b0;
op_code = 4'b0000; op_code = ADD;
`assert("alu : 0 + 0", out, 0) `assert("alu : 0 + 0", out, 0)
in_a = 32'b1; in_a = 32'b1;
`assert("alu : 1 + 0", out, 1) `assert("alu : 1 + 0", out, 1)
@ -26,6 +29,98 @@ module tb_alu ();
op_code = 4'b0001; op_code = 4'b0001;
`assert("alu : 1 - 1", out, 0) `assert("alu : 1 - 1", out, 0)
// ALU - left shift
in_a = 32'b1;
in_b = 32'b1;
op_code = SLL;
`assert("alu : 1 << 1", out, 2)
in_b = 32'b10;
`assert("alu : 1 << 2", out, 4)
in_a = 32'b11;
`assert("alu : 3 << 2", out, 12)
in_b = 32'b11110;
`assert("alu : 3 << 30", out, 32'b11000000000000000000000000000000)
in_b = 32'b11111;
`assert("alu : 3 << 31", out, 32'b10000000000000000000000000000000)
in_b = 32'b100000;
`assert("alu : 3 << 31", out, 32'b00000000000000000000000000000000)
// ALU - less than
in_a = 32'b0;
in_b = 32'b0;
op_code = SLT;
`assert("alu : 0 < 0", out, 0)
in_b = 32'b10;
`assert("alu : 0 << 2", out, 1)
in_a = 32'b11;
`assert("alu : 3 < 2", out, 0)
in_b = 32'b11111111111111111111111111111111;
in_a = 32'b11111111111111111111111111111111;
`assert("alu : -1 < -1", out, 0)
in_b = 32'b0;
`assert("alu : -1 < 0", out, 1)
in_a = 32'b10000000000000000000000000000000;
in_b = 32'b10000000000000000000000000000001;
`assert("alu : MIN_INT << MIN_INT + 1", out, 1)
// ALU - xor
in_a = 32'b0;
in_b = 32'b0;
op_code = XOR;
`assert("alu : 0 ^ 0", out, 32'b00000000000000000000000000000000)
in_a = 32'b1;
`assert("alu : 1 ^ 0", out, 32'b00000000000000000000000000000001)
in_a = 32'b0;
in_b = 32'b1;
`assert("alu : 0 ^ 1", out, 32'b00000000000000000000000000000001)
in_a = 32'b11111111111111111111111111111111;
in_b = 32'b11111111111111111111111111111111;
`assert("alu : MAX_INT ^ MAX_INT", out, 32'b00000000000000000000000000000000)
in_a = 32'b00000000000000000000000000000000;
in_b = 32'b11111111111111111111111111111111;
`assert("alu : 0 ^ MAX_INT", out, 32'b11111111111111111111111111111111)
in_a = 32'b00000011001000010001000011000000;
in_b = 32'b10101111001011101110111111111011;
`assert("alu : 00000011001000010001000011000000 ^ 10101111001011101110111111111011", out, 32'b10101100000011111111111100111011)
// ALU - right shift
in_a = 32'b1;
in_b = 32'b1;
op_code = SRL;
`assert("alu : 1 >> 1", out, 0)
in_a = 32'b10;
`assert("alu : 2 >> 1", out, 1)
in_a = 32'b11;
`assert("alu : 3 >> 2", out, 1)
in_a = 32'b11110;
in_b = 32'b1;
`assert("alu : 30 >> 1", out, 32'b1111)
in_a = 32'b10000000000000000000000000000000;
in_b = 32'b11111;
`assert("alu : 1000...000 >> 31", out, 32'b00000000000000000000000000000001)
in_a = 32'b10000000111100000000000111111111;
in_b = 32'b11111;
`assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001)
// // ALU - logical right shift
// in_a = 32'b1;
// in_b = 32'b1;
// op_code = 4'b0110;
// `assert("alu : 1 >> 1", out, 0)
// in_a = 32'b10;
// `assert("alu : 2 >> 1", out, 1)
// in_a = 32'b11;
// `assert("alu : 3 >> 2", out, 1)
// in_a = 32'b11110;
// in_b = 32'b1;
// `assert("alu : 30 >> 1", out, 32'b1111)
// in_a = 32'b10000000000000000000000000000000;
// in_b = 32'b11111;
// `assert("alu : 1000...000 >> 31", out, 32'b00000000000000000000000000000001)
// in_a = 32'b10000000111100000000000111111111;
// in_b = 32'b11111;
// `assert("alu : 1000..111 >> 31", out, 32'b00000000000000000000000000000001)
`end_message `end_message
end end