From f8b937d59093e6e56ded600fa6db636778e1bd91 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 9 Feb 2012 03:47:59 -0800 Subject: [PATCH] fix 32-bit divider bug thanks, torture! also, tidied up the code a bit. --- rocket/src/main/scala/divider.scala | 48 ++++++++++++++--------------- rocket/src/main/scala/dpath.scala | 18 +++++------ 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/rocket/src/main/scala/divider.scala b/rocket/src/main/scala/divider.scala index b661ee62..8fb98c1d 100644 --- a/rocket/src/main/scala/divider.scala +++ b/rocket/src/main/scala/divider.scala @@ -11,14 +11,14 @@ class ioDivider(width: Int) extends Bundle { val div_rdy = Bool(OUTPUT); val dw = UFix(1, INPUT); val div_fn = UFix(2, INPUT); - val div_waddr = UFix(5, INPUT); - val dpath_rs1 = Bits(width, INPUT); - val dpath_rs2 = Bits(width, INPUT); + val div_tag = UFix(5, INPUT); + val in0 = Bits(width, INPUT); + val in1 = Bits(width, INPUT); // responses - val div_result_bits = Bits(width, OUTPUT); - val div_result_tag = UFix(5, OUTPUT); - val div_result_val = Bool(OUTPUT); - val div_result_rdy = Bool(INPUT); + val result = Bits(width, OUTPUT); + val result_tag = UFix(5, OUTPUT); + val result_val = Bool(OUTPUT); + val result_rdy = Bool(INPUT); } // 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 state = Reg(resetVal = s_ready); - val count_bits = java.math.BigInteger.valueOf(width).bitLength(); val count = Reg() { UFix() }; val divby0 = Reg() { Bool() }; val neg_quo = Reg() { Bool() }; val neg_rem = Reg() { Bool() }; - val reg_waddr = Reg() { UFix() }; + val reg_tag = Reg() { UFix() }; val rem = 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_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 - // inputs to be sign-extended. - val in_lhs = Mux(((io.dw === DW_32) && !tc), - Cat(Fill(width/2, UFix(0,1)), io.dpath_rs1(width/2-1, 0)), - io.dpath_rs1).toUFix; + val lhs_sign = tc && Mux(io.dw === DW_64, io.in0(width-1), io.in0(width/2-1)).toBool + val lhs_hi = Mux(io.dw === DW_64, io.in0(width-1,width/2), Fill(width/2, lhs_sign)) + val lhs_in = Cat(lhs_hi, io.in0(width/2-1,0)) - val in_rhs = Mux(((io.dw === DW_32) && !tc), - Cat(Fill(width/2, UFix(0,1)), io.dpath_rs2(width/2-1, 0)), - io.dpath_rs2).toUFix; + val rhs_sign = tc && Mux(io.dw === DW_64, io.in1(width-1), io.in1(width/2-1)).toBool + val rhs_hi = Mux(io.dw === DW_64, io.in1(width-1,width/2), Fill(width/2, rhs_sign)) + val rhs_in = Cat(rhs_hi, io.in1(width/2-1,0)) when ((state === s_ready) && io.div_val) { - count <== UFix(0, count_bits); + count <== UFix(0, log2up(width+1)); half <== (io.dw === DW_32); neg_quo <== Bool(false); neg_rem <== Bool(false); rem <== (io.div_fn === DIV_R) || (io.div_fn === DIV_RU); - reg_waddr <== io.div_waddr; + reg_tag <== io.div_tag; divby0 <== Bool(true); - divisor <== in_rhs; - remainder <== Cat(Fill(width+1, UFix(0,1)), in_lhs).toUFix; + divisor <== rhs_in.toUFix; + remainder <== Cat(UFix(0,width+1), lhs_in).toUFix; } 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)); - 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_result_tag := reg_waddr; - io.div_result_val := (state === s_done); } } diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index ecb62e52..96be17b5 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -61,9 +61,9 @@ class rocketDpath extends Component val ex_alu_adder_out = alu.io.adder_out; val div = new rocketDivider(64); - val div_result = div.io.div_result_bits; - val div_result_tag = div.io.div_result_tag; - val div_result_val = div.io.div_result_val; + val div_result = div.io.result; + val div_result_tag = div.io.result_tag; + val div_result_val = div.io.result_val; val mul = new rocketMultiplier(); 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_val := ex_reg_ctrl_div_val; div.io.div_kill := io.ctrl.killm; - div.io.div_waddr := ex_reg_waddr; - div.io.dpath_rs1 := ex_reg_rs1; - div.io.dpath_rs2 := ex_reg_rs2; - div.io.div_result_rdy := !dmem_resp_replay + div.io.div_tag := ex_reg_waddr; + div.io.in0 := ex_reg_rs1; + div.io.in1 := ex_reg_rs2; + div.io.result_rdy:= !dmem_resp_replay 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 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_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