fix 32-bit divider bug
thanks, torture! also, tidied up the code a bit.
This commit is contained in:
parent
03ee49f424
commit
f8b937d590
@ -11,14 +11,14 @@ class ioDivider(width: Int) extends Bundle {
|
|||||||
val div_rdy = Bool(OUTPUT);
|
val div_rdy = Bool(OUTPUT);
|
||||||
val dw = UFix(1, INPUT);
|
val dw = UFix(1, INPUT);
|
||||||
val div_fn = UFix(2, INPUT);
|
val div_fn = UFix(2, INPUT);
|
||||||
val div_waddr = UFix(5, INPUT);
|
val div_tag = UFix(5, INPUT);
|
||||||
val dpath_rs1 = Bits(width, INPUT);
|
val in0 = Bits(width, INPUT);
|
||||||
val dpath_rs2 = Bits(width, INPUT);
|
val in1 = Bits(width, INPUT);
|
||||||
// responses
|
// responses
|
||||||
val div_result_bits = Bits(width, OUTPUT);
|
val result = Bits(width, OUTPUT);
|
||||||
val div_result_tag = UFix(5, OUTPUT);
|
val result_tag = UFix(5, OUTPUT);
|
||||||
val div_result_val = Bool(OUTPUT);
|
val result_val = Bool(OUTPUT);
|
||||||
val div_result_rdy = Bool(INPUT);
|
val result_rdy = Bool(INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// class ioDivider extends Bundle {
|
// class ioDivider extends Bundle {
|
||||||
@ -41,12 +41,11 @@ class rocketDivider(width : Int) extends Component {
|
|||||||
val s_ready :: s_neg_inputs :: s_busy :: s_neg_outputs :: s_done :: Nil = Enum(5) { UFix() };
|
val s_ready :: s_neg_inputs :: s_busy :: s_neg_outputs :: s_done :: Nil = Enum(5) { UFix() };
|
||||||
val state = Reg(resetVal = s_ready);
|
val state = Reg(resetVal = s_ready);
|
||||||
|
|
||||||
val count_bits = java.math.BigInteger.valueOf(width).bitLength();
|
|
||||||
val count = Reg() { UFix() };
|
val count = Reg() { UFix() };
|
||||||
val divby0 = Reg() { Bool() };
|
val divby0 = Reg() { Bool() };
|
||||||
val neg_quo = Reg() { Bool() };
|
val neg_quo = Reg() { Bool() };
|
||||||
val neg_rem = Reg() { Bool() };
|
val neg_rem = Reg() { Bool() };
|
||||||
val reg_waddr = Reg() { UFix() };
|
val reg_tag = Reg() { UFix() };
|
||||||
val rem = Reg() { Bool() };
|
val rem = Reg() { Bool() };
|
||||||
val half = Reg() { Bool() };
|
val half = Reg() { Bool() };
|
||||||
|
|
||||||
@ -75,30 +74,28 @@ class rocketDivider(width : Int) extends Component {
|
|||||||
}
|
}
|
||||||
is (s_neg_outputs) { state <== s_done; }
|
is (s_neg_outputs) { state <== s_done; }
|
||||||
is (s_done) {
|
is (s_done) {
|
||||||
when (io.div_result_rdy) { state <== s_ready; }
|
when (io.result_rdy) { state <== s_ready; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're doing 32-bit unsigned division, then we don't want the 32-bit
|
val lhs_sign = tc && Mux(io.dw === DW_64, io.in0(width-1), io.in0(width/2-1)).toBool
|
||||||
// inputs to be sign-extended.
|
val lhs_hi = Mux(io.dw === DW_64, io.in0(width-1,width/2), Fill(width/2, lhs_sign))
|
||||||
val in_lhs = Mux(((io.dw === DW_32) && !tc),
|
val lhs_in = Cat(lhs_hi, io.in0(width/2-1,0))
|
||||||
Cat(Fill(width/2, UFix(0,1)), io.dpath_rs1(width/2-1, 0)),
|
|
||||||
io.dpath_rs1).toUFix;
|
|
||||||
|
|
||||||
val in_rhs = Mux(((io.dw === DW_32) && !tc),
|
val rhs_sign = tc && Mux(io.dw === DW_64, io.in1(width-1), io.in1(width/2-1)).toBool
|
||||||
Cat(Fill(width/2, UFix(0,1)), io.dpath_rs2(width/2-1, 0)),
|
val rhs_hi = Mux(io.dw === DW_64, io.in1(width-1,width/2), Fill(width/2, rhs_sign))
|
||||||
io.dpath_rs2).toUFix;
|
val rhs_in = Cat(rhs_hi, io.in1(width/2-1,0))
|
||||||
|
|
||||||
when ((state === s_ready) && io.div_val) {
|
when ((state === s_ready) && io.div_val) {
|
||||||
count <== UFix(0, count_bits);
|
count <== UFix(0, log2up(width+1));
|
||||||
half <== (io.dw === DW_32);
|
half <== (io.dw === DW_32);
|
||||||
neg_quo <== Bool(false);
|
neg_quo <== Bool(false);
|
||||||
neg_rem <== Bool(false);
|
neg_rem <== Bool(false);
|
||||||
rem <== (io.div_fn === DIV_R) || (io.div_fn === DIV_RU);
|
rem <== (io.div_fn === DIV_R) || (io.div_fn === DIV_RU);
|
||||||
reg_waddr <== io.div_waddr;
|
reg_tag <== io.div_tag;
|
||||||
divby0 <== Bool(true);
|
divby0 <== Bool(true);
|
||||||
divisor <== in_rhs;
|
divisor <== rhs_in.toUFix;
|
||||||
remainder <== Cat(Fill(width+1, UFix(0,1)), in_lhs).toUFix;
|
remainder <== Cat(UFix(0,width+1), lhs_in).toUFix;
|
||||||
}
|
}
|
||||||
|
|
||||||
when (state === s_neg_inputs) {
|
when (state === s_neg_inputs) {
|
||||||
@ -135,10 +132,11 @@ class rocketDivider(width : Int) extends Component {
|
|||||||
|
|
||||||
val result = Mux(rem, remainder(2*width, width+1), remainder(width-1,0));
|
val result = Mux(rem, remainder(2*width, width+1), remainder(width-1,0));
|
||||||
|
|
||||||
io.div_result_bits := Mux(half, Cat(Fill(width/2, result(width/2-1)), result(width/2-1,0)), result);
|
io.result := Mux(half, Cat(Fill(width/2, result(width/2-1)), result(width/2-1,0)), result);
|
||||||
|
io.result_tag := reg_tag;
|
||||||
|
io.result_val := (state === s_done);
|
||||||
|
|
||||||
io.div_rdy := (state === s_ready);
|
io.div_rdy := (state === s_ready);
|
||||||
io.div_result_tag := reg_waddr;
|
|
||||||
io.div_result_val := (state === s_done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,9 @@ class rocketDpath extends Component
|
|||||||
val ex_alu_adder_out = alu.io.adder_out;
|
val ex_alu_adder_out = alu.io.adder_out;
|
||||||
|
|
||||||
val div = new rocketDivider(64);
|
val div = new rocketDivider(64);
|
||||||
val div_result = div.io.div_result_bits;
|
val div_result = div.io.result;
|
||||||
val div_result_tag = div.io.div_result_tag;
|
val div_result_tag = div.io.result_tag;
|
||||||
val div_result_val = div.io.div_result_val;
|
val div_result_val = div.io.result_val;
|
||||||
|
|
||||||
val mul = new rocketMultiplier();
|
val mul = new rocketMultiplier();
|
||||||
val mul_result = mul.io.result;
|
val mul_result = mul.io.result;
|
||||||
@ -275,13 +275,13 @@ class rocketDpath extends Component
|
|||||||
div.io.div_fn := ex_reg_ctrl_div_fn;
|
div.io.div_fn := ex_reg_ctrl_div_fn;
|
||||||
div.io.div_val := ex_reg_ctrl_div_val;
|
div.io.div_val := ex_reg_ctrl_div_val;
|
||||||
div.io.div_kill := io.ctrl.killm;
|
div.io.div_kill := io.ctrl.killm;
|
||||||
div.io.div_waddr := ex_reg_waddr;
|
div.io.div_tag := ex_reg_waddr;
|
||||||
div.io.dpath_rs1 := ex_reg_rs1;
|
div.io.in0 := ex_reg_rs1;
|
||||||
div.io.dpath_rs2 := ex_reg_rs2;
|
div.io.in1 := ex_reg_rs2;
|
||||||
div.io.div_result_rdy := !dmem_resp_replay
|
div.io.result_rdy:= !dmem_resp_replay
|
||||||
|
|
||||||
io.ctrl.div_rdy := div.io.div_rdy;
|
io.ctrl.div_rdy := div.io.div_rdy;
|
||||||
io.ctrl.div_result_val := div.io.div_result_val;
|
io.ctrl.div_result_val := div.io.result_val;
|
||||||
|
|
||||||
// multiplier
|
// multiplier
|
||||||
mul.io.mul_val := ex_reg_ctrl_mul_val;
|
mul.io.mul_val := ex_reg_ctrl_mul_val;
|
||||||
@ -294,7 +294,7 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
io.ctrl.mul_rdy := mul.io.mul_rdy
|
io.ctrl.mul_rdy := mul.io.mul_rdy
|
||||||
io.ctrl.mul_result_val := mul.io.result_val;
|
io.ctrl.mul_result_val := mul.io.result_val;
|
||||||
mul.io.result_rdy := !dmem_resp_replay && !div.io.div_result_val
|
mul.io.result_rdy := !dmem_resp_replay && !div.io.result_val
|
||||||
|
|
||||||
io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection & bypass control
|
io.ctrl.ex_waddr := ex_reg_waddr; // for load/use hazard detection & bypass control
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user