ALU.v 2.1 KB
module ALU(clk, aluin1, aluin2, aluctrl, aluout, alubranch);
input clk;
input[31:0] aluin1, aluin2;
input[3:0] aluctrl;
output reg[31:0] aluout;
output reg[5:0] alubranch;

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

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

always @(*) begin
	overflow = 1'b0;
	alubranch = 6'b0;
	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.
			alubranch[0] = (aluout == 32'h00000000) ? 1'b1 : 1'b0;	// beq
			alubranch[1] = (aluout != 32'h00000000) ? 1'b1 : 1'b0;	// bne
			alubranch[2] = (aluin1 > 32'h00000000) ? 1'b1 : 1'b0;	// bgtz 
			alubranch[3] = (aluin1 < 32'h00000000) ? 1'b1 : 1'b0;	// bltz
			alubranch[4] = (aluin1 >= 32'h00000000) ? 1'b1 : 1'b0;	// bgez 
			alubranch[5] = (aluin1 <= 32'h00000000) ? 1'b1 : 1'b0;	// blez
		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;
			tempHI <= temp[63:32];
			tempLO <= temp[31:0];
		end
		4'b1001: begin				// div
			tempHI <= aluin1 % aluin2;
			tempLO <= 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'h00000000;
	endcase
end

always @(negedge clk) begin
	case(aluctrl)
		4'b1000: begin				// mult
			HI <= tempHI;
			LO <= tempLO;
		end
		4'b1001: begin				// div
			HI <= tempHI;
			LO <= tempLO;
		end
	endcase
	tempHI = 32'd0;
	tempLO = 32'd0;
end

endmodule