From 92493ad153a3513588ddd0bd5e0c509e335ec064 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 9 Feb 2012 02:26:03 -0800 Subject: [PATCH] fix mul/div kill bug occasionally, an in-progress multiply or divide could be erroneously killed, tying up the register forever. --- rocket/src/main/scala/divider.scala | 2 +- rocket/src/main/scala/dpath.scala | 11 +++-------- rocket/src/main/scala/multiplier.scala | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/rocket/src/main/scala/divider.scala b/rocket/src/main/scala/divider.scala index 1d1c8d57..b661ee62 100644 --- a/rocket/src/main/scala/divider.scala +++ b/rocket/src/main/scala/divider.scala @@ -56,7 +56,7 @@ class rocketDivider(width : Int) extends Component { val tc = (io.div_fn === DIV_D) || (io.div_fn === DIV_R); - when (io.div_kill) { + when (io.div_kill && Reg(state === s_ready)) { // can only kill on first cycle state <== s_ready; } diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 6dfa0a16..8112d968 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -111,8 +111,6 @@ class rocketDpath extends Component val mem_reg_wdata = Reg() { Bits() }; val mem_reg_raddr1 = Reg() { UFix() }; val mem_reg_raddr2 = Reg() { UFix() }; - val mem_reg_ctrl_mul_val = Reg(resetVal = Bool(false)); - val mem_reg_ctrl_div_val = Reg(resetVal = Bool(false)); val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false)); val mem_wdata = Wire() { Bits() }; @@ -276,7 +274,7 @@ class rocketDpath extends Component div.io.dw := ex_reg_ctrl_fn_dw; div.io.div_fn := ex_reg_ctrl_div_fn; div.io.div_val := ex_reg_ctrl_div_val; - div.io.div_kill := mem_reg_ctrl_div_val && io.ctrl.killm; + 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; @@ -287,7 +285,7 @@ class rocketDpath extends Component // multiplier mul.io.mul_val := ex_reg_ctrl_mul_val; - mul.io.mul_kill:= mem_reg_ctrl_mul_val && io.ctrl.killm; + mul.io.mul_kill:= io.ctrl.killm; mul.io.dw := ex_reg_ctrl_fn_dw; mul.io.mul_fn := ex_reg_ctrl_mul_fn; mul.io.mul_tag := ex_reg_waddr; @@ -354,8 +352,6 @@ class rocketDpath extends Component mem_reg_wdata <== ex_wdata; mem_reg_raddr1 <== ex_reg_raddr1 mem_reg_raddr2 <== ex_reg_raddr2; - mem_reg_ctrl_mul_val <== ex_reg_ctrl_mul_val; - mem_reg_ctrl_div_val <== ex_reg_ctrl_div_val; when (io.ctrl.killx) { mem_reg_valid <== Bool(false); @@ -392,8 +388,7 @@ class rocketDpath extends Component val mem_ll_wdata = Mux(div_result_val, div_result, Mux(mul_result_val, mul_result, mem_reg_wdata)) - val mem_ll_wb = mem_ll_waddr != UFix(0) && - (dmem_resp_replay || div_result_val || mul_result_val) + val mem_ll_wb = dmem_resp_replay || div_result_val || mul_result_val wb_reg_pc <== mem_reg_pc; wb_reg_inst <== mem_reg_inst diff --git a/rocket/src/main/scala/multiplier.scala b/rocket/src/main/scala/multiplier.scala index a3ce7bd8..52ab0ef0 100644 --- a/rocket/src/main/scala/multiplier.scala +++ b/rocket/src/main/scala/multiplier.scala @@ -62,7 +62,7 @@ class rocketMultiplier extends Component { r_prod<== rhs_in r_lsb <== Bool(false) } - when (io.result_val && io.result_rdy || io.mul_kill) { + when (io.result_val && io.result_rdy || io.mul_kill && r_cnt === UFix(0)) { // can only kill on first cycle r_val <== Bool(false) }