// 4-bit MIPS ALU in Verilog (1-bit ALU bihavioral implementation) module ALU (op,a,b,result,zero); input [3:0] a; input [3:0] b; input [3:0] op; output [3:0] result; output zero; ALU1 alu0 (a[0],b[0],op[3],op[2],op[1:0],set, op[2],c1,result[0]); ALU1 alu1 (a[1],b[1],op[3],op[2],op[1:0],1'b0,c1, c2,result[1]); ALU1 alu2 (a[2],b[2],op[3],op[2],op[1:0],1'b0,c2, c3,result[2]); ALUmsb alu3 (a[3],b[3],op[3],op[2],op[1:0],1'b0,c3, c4,result[3],set); nor nor1(zero, result[0],result[1],result[2],result[3]); endmodule // 1-bit ALU for bits 0-2 module ALU1 (a,b,ainvert,binvert,op,less,carryin,carryout,result); input a,b,less,carryin,ainvert,binvert; input [1:0] op; output carryout,result; reg result; assign a_inv = ~a; assign a1 = ainvert? a_inv: a; assign b_inv = ~b; assign b1 = binvert? b_inv: b; assign a_and_b = a1 && b1; assign a_or_b = a1 || b1; assign {carryout,sum} = a + b1 + carryin; always @ (a_and_b,a_or_b,sum,less,op) case (op) 2'b00: result = a_and_b; 2'b01: result = a_or_b; 2'b10: result = sum; 2'b11: result = less; endcase endmodule // 1-bit ALU for the most significant bit module ALUmsb (a,b,ainvert,binvert,op,less,carryin,carryout,result,sum); input a,b,less,carryin,ainvert,binvert; input [1:0] op; output carryout,result,sum; reg result; assign a_inv = ~a; assign a1 = ainvert? a_inv: a; assign b_inv = ~b; assign b1 = binvert? b_inv: b; assign a_and_b = a1 && b1; assign a_or_b = a1 || b1; assign {carryout,sum} = a + b1 + carryin; always @ (a_and_b,a_or_b,sum,less,op) case (op) 2'b00: result = a_and_b; 2'b01: result = a_or_b; 2'b10: result = sum; 2'b11: result = less; endcase endmodule // Test Module module testALU; reg signed [3:0] a; reg signed [3:0] b; reg [3:0] op; wire signed [3:0] result; wire zero; ALU alu (op,a,b,result,zero); initial begin $display("op a b result zero"); $monitor ("%b %b(%d) %b(%d) %b(%d) %b",op,a,a,b,b,result,result,zero); op = 4'b0000; a = 4'b0111; b = 4'b0001; // AND #1 op = 4'b0001; a = 4'b0101; b = 4'b0010; // OR #1 op = 4'b0010; a = 4'b0100; b = 4'b0010; // ADD #1 op = 4'b0010; a = 4'b0111; b = 4'b0001; // ADD #1 op = 4'b0110; a = 4'b0101; b = 4'b0011; // SUB #1 op = 4'b0110; a = 4'b1111; b = 4'b0001; // SUB #1 op = 4'b0111; a = 4'b0101; b = 4'b0001; // SLT #1 op = 4'b0111; a = 4'b1110; b = 4'b1111; // SLT #1 op = 4'b1100; a = 4'b0101; b = 4'b0010; // NOR #1 op = 4'b1101; a = 4'b0101; b = 4'b0010; // NAND end endmodule /* Output op a b result zero 0000 0111( 7) 0001( 1) 0001( 1) 0 0001 0101( 5) 0010( 2) 0111( 7) 0 0010 0100( 4) 0010( 2) 0110( 6) 0 0010 0111( 7) 0001( 1) 1000(-8) 0 0110 0101( 5) 0011( 3) 0010( 2) 0 0110 1111(-1) 0001( 1) 1110(-2) 0 0111 0101( 5) 0001( 1) 0000( 0) 1 0111 1110(-2) 1111(-1) 0001( 1) 0 1100 0101( 5) 0010( 2) 1000(-8) 0 1101 0101( 5) 0010( 2) 1111(-1) 0 */