Replace div/rem expressions with divider modules in preparation for pipelining
This commit is contained in:
47
rtl/VX_alu.v
47
rtl/VX_alu.v
@@ -20,8 +20,10 @@ module VX_alu(
|
||||
wire[63:0] ALU_in1_mult;
|
||||
wire[63:0] ALU_in2_mult;
|
||||
wire[31:0] upper_immed;
|
||||
wire[31:0] div_result;
|
||||
wire[31:0] rem_result;
|
||||
wire[31:0] unsigned_div_result;
|
||||
wire[31:0] unsigned_rem_result;
|
||||
wire[31:0] signed_div_result;
|
||||
wire[31:0] signed_rem_result;
|
||||
|
||||
|
||||
assign which_in2 = in_rs2_src == `RS2_IMMED;
|
||||
@@ -33,6 +35,37 @@ module VX_alu(
|
||||
|
||||
assign upper_immed = {in_upper_immed, {12{1'b0}}};
|
||||
|
||||
VX_divide #(
|
||||
.WIDTHN(32),
|
||||
.WIDTHD(32),
|
||||
.SPEED("HIGHEST"),
|
||||
.PIPELINE(0)
|
||||
) unsigned_div (
|
||||
.clk(0),
|
||||
.aclr(0),
|
||||
.clken(1), // TODO this could be disabled on inactive instructions
|
||||
.numer(ALU_in1),
|
||||
.denom(ALU_in2),
|
||||
.quotient(unsigned_div_result),
|
||||
.remainder(unsigned_rem_result)
|
||||
);
|
||||
|
||||
VX_divide #(
|
||||
.WIDTHN(32),
|
||||
.WIDTHD(32),
|
||||
.NREP("SIGNED"),
|
||||
.DREP("SIGNED"),
|
||||
.SPEED("HIGHEST"),
|
||||
.PIPELINE(0)
|
||||
) signed_div (
|
||||
.clk(0),
|
||||
.aclr(0),
|
||||
.clken(1), // TODO this could be disabled on inactive instructions
|
||||
.numer(ALU_in1),
|
||||
.denom(ALU_in2),
|
||||
.quotient(signed_div_result),
|
||||
.remainder(signed_rem_result)
|
||||
);
|
||||
|
||||
|
||||
//always @(posedge `MUL) begin
|
||||
@@ -68,10 +101,10 @@ module VX_alu(
|
||||
`MULH: out_alu_result = mult_result[63:32];
|
||||
`MULHSU: out_alu_result = mult_result[63:32];
|
||||
`MULHU: out_alu_result = mult_result[63:32];
|
||||
`DIV: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : $signed($signed(ALU_in1) / $signed(ALU_in2));
|
||||
`DIVU: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : ALU_in1 / ALU_in2;
|
||||
`REM: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : $signed($signed(ALU_in1) % $signed(ALU_in2));
|
||||
`REMU: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : ALU_in1 % ALU_in2;
|
||||
`DIV: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : signed_div_result;
|
||||
`DIVU: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : unsigned_div_result;
|
||||
`REM: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : signed_rem_result;
|
||||
`REMU: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : unsigned_rem_result;
|
||||
default: out_alu_result = 32'h0;
|
||||
endcase // in_alu_op
|
||||
end
|
||||
@@ -136,4 +169,4 @@ module VX_alu(
|
||||
end
|
||||
`endif
|
||||
|
||||
endmodule // VX_alu
|
||||
endmodule
|
||||
Reference in New Issue
Block a user