ALU.v 1.3 KB
module ALU(aluin1, aluin2, aluctrl, aluout, alubranch);

input[31:0] aluin1, aluin2;
input[3:0] aluctrl;
output reg[31:0] aluout;
output alubranch;

reg overflow;
reg[63:0] temp;
reg[31:0] HI, LO;				// HI, LO register for multiplication and division.

assign alubranch = aluout == 32'h00000000 ? 1'b1 : 1'b0;

initial begin
	temp = 64'h0000000000000000;
	HI = 32'h00000000;
	LO = 32'h00000000;
end

always @(*) begin
overflow = 0;
case(aluctrl)
	4'b0000: aluout = aluin1 & aluin2;	// and
	4'b0001: aluout = aluin1 | aluin2;	// or
	4'b0010: begin 				// add
		aluout = aluin1 + aluin2;
		overflow = aluin1[31]==aluin2[31] && aluin1[31]!=aluout[31] ? 1'b1 : 1'b0;	// overflow detection.
	end
	4'b0110: begin				// sub
		aluout = aluin1 - aluin2;
		overflow = aluin1[31]!=aluin2[31] && aluin1[31]!=aluout[31] ? 1'b1 : 1'b0;	// overflow detection.
	end

	4'b0111: begin				// slt
		aluout[31:1] = {31{1'b0}};
		aluout[0] = aluin1 < aluin2 ? 1'b1 : 1'b0;
	end
	4'b1000: begin				// mult
		temp = aluin1 * aluin2;
		HI = temp[63:32];
		LO = temp[31:0];
	end
	4'b1001: begin				// div
		HI = aluin1 % aluin2;
		LO = aluin1 / aluin2;
	end
	4'b1010: aluout = HI;			// mfhi
	4'b1011: aluout = LO;			// mflo
	4'b1100: aluout = ~(aluin1 | aluin2);	// nor
	4'b1101: aluout = aluin1 ^ aluin2;	// xor
	default: aluout = 32'b0;
endcase
end

endmodule