ALU.v.bak 1.69 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 alubranch;

reg overflow;
reg[63:0] temp;
reg[31:0] HI, LO;				// HI, LO register for multiplication and division.
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;
	tempHI = 32'h00000000;
	tempLO = 32'h00000000;
	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;
		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'b0;
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