This is my Verilog code of MIPS 32-bit ALU, which is able to perform 4 functions including addition, subtraction, exclusive-OR, and set-on-less-than.
I use the adder to perform both addition and subtraction.
Hope it is useful for amateurs like me! :)
`timescale 1 ps / 100 fs
// DA Cau Truc May Tinh - Lab 2 - ALU
// Ngo Dat - 11DT3
//32-BIT ALU
module alu(Output, Carryout, Zero, Overflow, Negative, BusA, BusB, ALUControl);
output Output;
output Carryout, Zero, Overflow, Negative;
input BusA, BusB;
input ALUControl;
wire c, Less, add_out, xor_out, Less_out, p, g, BusBinv;
wire CarryIn;
parameter delay = 50;
assign Less = 31'd0;
buf# (delay) buf0(CarryIn, ALUControl);
genvar k;
generate
for(k=0; k<32; k++)
begin: CalculatePandG
xor# (delay) myXor(BusBinv, BusB, ALUControl);
and# (delay) myAnd(g, BusA, BusBinv);
or # (delay) myOr(p, BusA, BusBinv);
end
endgenerate
carry_lookahead myCarryLookAhead(p, g, CarryIn, c, Carryout);
genvar i;
generate
for(i=0; i<32; i=i+1)
begin: JoinedALUs
alu_1bit myALU(add_out, xor_out, Less_out, BusA, BusB, c, Less, ALUControl);
end
endgenerate
buf# (delay) buf1(Negative, add_out);
xor# (delay) xor0(Overflow, c, Carryout);
xor# (delay) xor1(Less, Overflow, Negative);
Zero_module myZero(Zero, Output);
mux32x4_32 myMUX(Output, add_out, xor_out, add_out, Less_out, ALUControl, ALUControl);
endmodule
//1-BIT ALU
module alu_1bit(add_out, xor_out, Less_out, a, b, CarryIn, Less, ALUControl);
output add_out, xor_out, Less_out;
input a, b, CarryIn, Less;
input ALUControl;
parameter delay = 50;
wire bin, btemp;
not# (delay) not0(bin, b);
m2_1 myMUX0(btemp, ALUControl, b, bin);
xor# (delay) myAdder(add_out, a, btemp, CarryIn);
xor# (delay) xor0(xor_out, a, b);
buf# (delay) buf0(Less_out, Less);
endmodule
//CARRY-LOOKAHEAD
module carry_lookahead(p, g, CarryIn, c, CarryOut);
input p, g;
input CarryIn;
output c;
output CarryOut;
buf# 50 buf0(c, CarryIn);
genvar i;
generate
for(i=0; i<31; i++)
begin: CarryLookAhead
cal_carry myCarry(p, g, c, c);
end
endgenerate
cal_carry myCarry31(p, g, c, CarryOut);
endmodule
module cal_carry(p, g, cin, cout);
input p, g, cin;
output cout;
parameter delay = 50;
wire temp;
and# (delay) and0(temp, p, cin);
or # (delay) or0(cout, temp, g);
endmodule
//2-1 MULTIPLEXOR
module m2_1(data, sel, y0, y1);
output data;
input sel, y0, y1;
wire nsel, a, b;
parameter delay = 50;
not# (delay) not0(nsel, sel);
and# (delay) and0(a, nsel, y0);
and# (delay) and1(b, sel, y1);
or # (delay) or0(data, a, b);
endmodule
//4-1 MULTIPLEXOR
module m4_1(data, sel1, sel0, y0, y1, y2, y3);
output data;
input sel1, sel0, y0, y1, y2, y3;
wire out0, out1;
m2_1 myMultiplexer0(out0, sel0, y0, y1);
m2_1 myMultiplexer1(out1, sel0, y2, y3);
m2_1 myMultiplexer2(data, sel1, out0, out1);
endmodule
//32x4 TO 32 MULTIPLEXOR
module mux32x4_32(Output, Add, Xor, Subtract, SLT, control_1,control_0);
output Output;
input Add, Xor, Subtract, SLT;
input control_1, control_0;
genvar i;
generate
for(i=0; i<32; i=i+1)
begin : mux32x4_32
m4_1 myMux(Output, control_1, control_0, Add, Xor, Subtract, SLT);
end
endgenerate
endmodule
//ZERO FLAG
module Zero_module(Output,Input);
output Output;
input Input;
wire temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9;
parameter delay = 50;
or# (delay) or0(temp0, Input, Input, Input,Input);
or# (delay) or1(temp1, Input, Input, Input,Input);
or# (delay) or2(temp2, Input, Input, Input,Input);
or# (delay) or3(temp3, Input, Input, Input,Input);
or# (delay) or4(temp4, Input, Input, Input,Input);
or# (delay) or5(temp5, Input, Input, Input,Input);
or# (delay) or6(temp6, Input, Input, Input,Input);
or# (delay) or7(temp7, Input, Input, Input,Input);
or# (delay) or8(temp8, temp0, temp1, temp2, temp3);
or# (delay) or9(temp9, temp4, temp5, temp6, temp7);
nor# (delay) nor0(Output, temp8, temp9);
endmodule
// Test bench for ALU file
module ALUStimulus();
parameter ClockDelay = 100000;
reg BusA, BusB;
reg ALUControl;
wire Output;
wire Zero, Overflow, Carryout, Negative;
integer i;
// If your register file module is not named "alu" then you will
// have to change the following line in order to create an instance of
// your register file. Also you must make sure that the port declarations
// match up with the module instance in this stimulus file.
alu alu1(.Output, .Carryout, .Zero, .Overflow, .Negative, .BusA, .BusB, .ALUControl);
initial begin
// Addition unit testing
ALUControl=00;
BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 000018AB
BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00001339
BusA=32'h7FFFFFFF; BusB=32'h00000001;# (ClockDelay); // Should output 80000000, overflow, negative
// Xor unit testing
ALUControl=01;
BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 00000753
BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00001331
BusA=32'h80000000; BusB=32'h00000001;# (ClockDelay); // Should output 80000001
// Subtraction unit testing
ALUControl=10;
BusA=32'h00000DEF; BusB=32'h00000ABC;# (ClockDelay); // Should output 00000333
BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 0000112F
BusA=32'h80000000; BusB=32'h00000001;# (ClockDelay); // Should output 7FFFFFFF, overflow
// Set Less Than unit testing
ALUControl=11;
BusA=32'h00000000; BusB=32'h00000DEF;# (ClockDelay); // Should output 00000001
BusA=32'h00001234; BusB=32'h00000105;# (ClockDelay); // Should output 00000000
end
endmodule