This is 32bit ALU with a zero flag,
F2:0 Function
000 A AND B
001 A OR B
010 A + B
011 not used
100 A AND B
101 A OR B
110 A − B
111 SLT
SLT is set less than, it sets the least the output of ALU to 1 if A < B
This is the ALU module
module alu(input logic [31:0] a, input logic [31:0] b, input logic [2:0] f, output logic [31:0] out, output logic zero);
logic [31:0]tmp;
always @(a, b,f)
begin
if (f == 3'b000) // And
out = a & b;
else if( f == 3'b001) // Or
out = a | b;
else if( f == 3'b010) // Add
out = a + b;
else if( f == 3'b100) // New and
out = a & ~b;
else if( f == 3'b101) // New or
out = a | ~b;
else if( f == 3'b110) // SUB
out = a - b;
else if( f == 3'b111) // SLT
begin
tmp = a - b;
out[31:1] = 31'h0;
out[0] = (tmp[31] == 1'b1);
end
if (out == 32'h00000000)
zero = 1;
else
zero = 0;
end
endmodule
This is the test bench I built for the code
module alu_tb;
reg[31:0] a;
reg [31:0] b;
reg[2:0] f;
wire [31:0] out;
wire zero;
alu DUT (a,b,f,out,zero);
initial begin
$dumpfile("alu.vcd");
$dumpvars(0, DUT);
$monitor("A = 0x%x, B = 0x%x, f=0b%b\n\tOut = 0x%x, z = %b", a, b,f, out, zero);
f = 3'b010; // 0 + 0
a = 32'h0000_0000;
b = 32'h0000_0000;
#10
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s0 + 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b010; // 0 + (-1)
a = 32'h0000_0000;
b = 32'hFFFF_FFFF;
#10
if ( out !== 32'hFFFF_FFFF | zero !== 1'b0)
$display("\t%s0 + (-1) failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'hFFFF_FFFF, 1'b0, "\033[0m");
f = 3'b010; // 1 + (-1)
a = 32'h0000_0001;
b = 32'hFFFF_FFFF;
#10
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s1 + (-1) failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b010; // FF + 1
a = 32'h0000_00FF;
b = 32'h0000_0001;
#10;
if ( out !== 32'h100 | zero !== 1'b0)
$display("\t%s0xFF + 1 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h100, 1'b0, "\033[0m");
f = 3'b110; // 0 - 0
a = 32'h0000_0000;
b = 32'h0000_0000;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s0 - 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b110; // 0 - (-1)
a = 32'h0000_0000;
b = 32'hFFFF_FFFF;
#10;
if ( out !== 32'h1 | zero !== 1'b0)
$display("\t%s0 - (-1) failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h1, 1'b0, "\033[0m");
f = 3'b110; // 1 - 1
a = 32'h0000_0001;
b = 32'h0000_0001;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s1 - 1 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b110; // 100 - 1
a = 32'h0000_0100;
b = 32'h0000_0001;
#10;
if ( out !== 32'hFF | zero !== 1'b0)
$display("\t%s100 - 1 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'hFF, 1'b0, "\033[0m");
f = 3'b111; // SLT 0, 0
a = 32'h0000_0000;
b = 32'h0000_0000;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%sSLT 0, 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b111; // SLT 0, 1
a = 32'h0000_0000;
b = 32'h0000_0001;
#10;
if ( out !== 32'h1 | zero !== 1'b0)
$display("\t%sSLT 0, 1 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h1, 1'b0, "\033[0m");
f = 3'b111; // SLT 0, -1
a = 32'h0000_0000;
b = 32'hFFFF_FFFF;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%sSLT 0, -1 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b111; // SLT 1, 0
a = 32'h0000_0001;
b = 32'h0000_0000;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%sSLT 1, 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b111; // SLT -1, 0
a = 32'hFFFF_FFFF;
b = 32'h0000_0000;
#10;
if ( out !== 32'h1 | zero !== 1'b0)
$display("\t%sSLT -1, 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h1, 1'b0, "\033[0m");
f = 3'b000; // -1 & -1
a = 32'hFFFF_FFFF;
b = 32'hFFFF_FFFF;
#10;
if ( out !== 32'hFFFF_FFFF | zero !== 1'b0)
$display("\t%s 0xFFFFFFFF & 0xFFFFFFFF failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'hFFFF_FFFF, 1'b0, "\033[0m");
f = 3'b000; // -1 & 12345678
a = 32'hFFFF_FFFF;
b = 32'h1234_5678;
#10;
if ( out !== 32'h1234_5678 | zero !== 1'b0)
$display("\t%s0xFFFFFFFF & 0x12345678 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h12345678, 1'b0, "\033[0m");
f = 3'b000; // 12345678 & 87654321
a = 32'h1234_5678;
b = 32'h8765_4321;
#10;
if ( out !== 32'h02244220 | zero !== 1'b0)
$display("\t%s0x12345678 & 0x87654321 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h02244220, 1'b0, "\033[0m");
f = 3'b000; // -1 & 0
a = 32'hFFFF_FFFF;
b = 32'h0000_0000;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s0xFFFFFFFF & 0x0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
f = 3'b001; // -1 | -1
a = 32'hFFFF_FFFF;
b = 32'hFFFF_FFFF;
#10;
if ( out !== 32'hFFFF_FFFF | zero !== 1'b0)
$display("\t%s0xFFFFFFFF | 0xFFFFFFFF failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'hFFFFFFFF, 1'b0, "\033[0m");
f = 3'b001; // 12345678 | 87654321
a = 32'h1234_5678;
b = 32'h8765_4321;
#10;
if ( out !== 32'h9775_5779 | zero !== 1'b0)
$display("\t%s0x12345678 | 0x87654321 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h97755779, 1'b0, "\033[0m");
f = 3'b001; // 0 | -1
a = 32'h0000_0000;
b = 32'hFFFF_FFFF;
#10;
if ( out !== 32'hFFFF_FFFF | zero !== 1'b0)
$display("\t%s0x0 | 0xFFFFFFFF failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'hFFFFFFFF, 1'b0, "\033[0m");
f = 3'b001; // 0 | 0
a = 32'h0000_0000;
b = 32'h0000_0000;
#10;
if ( out !== 32'h0 | zero !== 1'b1)
$display("\t%s0 | 0 failed.\tExpected out = 0x%0x, z = %b%s","\033[0;31m", 32'h0, 1'b1, "\033[0m");
$finish;
end
endmodule
Improvement to the ALU code or the test bench will be appreciated.