From b5a8b6dc7395e4da924fe4c11c9689c83ab001be Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 19 Dec 2011 16:57:53 -0800 Subject: [PATCH] fix divider for RV32 --- rocket/src/main/scala/consts.scala | 15 +++++---------- rocket/src/main/scala/ctrl.scala | 18 +++++++++--------- rocket/src/main/scala/divider.scala | 24 ++++++++---------------- rocket/src/main/scala/dpath.scala | 1 + 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 9906eaa9..fa7b6ddb 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -50,16 +50,11 @@ object Constants val MUL_HS = UFix(2, 2); val MUL_HSU = UFix(3, 2); - val DIV_X = UFix(0, 4); - val DIV_NO = UFix(0, 4); - val DIV_64D = UFix(1, 4); - val DIV_64DU = UFix(2, 4); - val DIV_64R = UFix(3, 4); - val DIV_64RU = UFix(4, 4); - val DIV_32D = UFix(5, 4); - val DIV_32DU = UFix(6, 4); - val DIV_32R = UFix(7, 4); - val DIV_32RU = UFix(8, 4); + val DIV_X = UFix(0, 2); + val DIV_D = UFix(0, 2); + val DIV_DU = UFix(1, 2); + val DIV_R = UFix(2, 2); + val DIV_RU = UFix(3, 2); val M_N = UFix(0, 1); val M_Y = UFix(1, 1); diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index bfc0f148..c4dd282a 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -27,7 +27,7 @@ class ioCtrlDpath extends Bundle() val mul_fn = UFix(2, 'output); val mul_wb = Bool('output); val div_val = Bool('output); - val div_fn = UFix(4, 'output); + val div_fn = UFix(2, 'output); val div_wb = Bool('output); val sel_wa = Bool('output); val sel_wb = UFix(3, 'output); @@ -241,14 +241,14 @@ class rocketCtrl extends Component MULHSU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, Y,MUL_HSU, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), MULW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_32, FN_X, M_N,M_X, MT_X, Y,MUL_LO, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - DIV-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_64D, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - DIVU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_64DU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - REM-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_64R, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - REMU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_64RU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - DIVW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_32D, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - DIVUW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_32DU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - REMW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_32R, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - REMUW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_32RU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + DIV-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_D, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + DIVU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_DU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + REM-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_R, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + REMU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_RU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + DIVW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_32, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_D, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + DIVUW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_32, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_DU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + REMW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_32, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_R, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + REMUW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_32, FN_X, M_N,M_X, MT_X, N,MUL_X, Y,DIV_RU, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), SYSCALL-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,Y,N), EI-> List(Y, BR_N, REN_N,REN_N,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_N,WA_X, WB_X, REN_N,WEN_N,I_EI,SYNC_N,N,N,Y), diff --git a/rocket/src/main/scala/divider.scala b/rocket/src/main/scala/divider.scala index 6e383a3e..66c2617f 100644 --- a/rocket/src/main/scala/divider.scala +++ b/rocket/src/main/scala/divider.scala @@ -8,7 +8,8 @@ class ioDivider(width: Int) extends Bundle { // requests val div_val = Bool('input); val div_rdy = Bool('output); - val div_fn = UFix(4, 'input); + 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); @@ -47,26 +48,18 @@ class rocketDivider(width : Int) extends Component { val reg_waddr = Reg(resetVal = UFix(0, 5)); val rem = Reg(resetVal = Bool(false)); val half = Reg(resetVal = Bool(false)); - val tc = Reg(resetVal = Bool(false)); val divisor = Reg(resetVal = UFix(0, width)); val remainder = Reg(resetVal = UFix(0, 2*width+1)); val subtractor = remainder(2*width, width).toUFix - divisor; - val v_tc = ((io.div_fn === DIV_64D) || (io.div_fn === DIV_64R)) || - ((io.div_fn === DIV_32D) || (io.div_fn === DIV_32R)); - - val v_rem = ((io.div_fn === DIV_32R) || (io.div_fn === DIV_32RU)) || - ((io.div_fn === DIV_64R) || (io.div_fn === DIV_64RU)); - - val v_half = ((io.div_fn === DIV_32R) || (io.div_fn === DIV_32RU)) || - ((io.div_fn === DIV_32D) || (io.div_fn === DIV_32DU)); + val tc = (io.div_fn === DIV_D) || (io.div_fn === DIV_R); // state machine switch (state) { is (s_ready) { when (!io.div_val) { state <== s_ready; } - when (v_tc) { state <== s_neg_inputs }; + when (tc) { state <== s_neg_inputs }; otherwise { state <== s_busy; } } is (s_neg_inputs) { state <== s_busy; } @@ -83,21 +76,20 @@ class rocketDivider(width : Int) extends Component { // 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((v_half && !v_tc), + 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 in_rhs = Mux((v_half && !v_tc), + 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; when ((state === s_ready) && io.div_val) { count <== UFix(0, count_bits); - half <== v_half; + half <== (io.dw === DW_32); neg_quo <== Bool(false); neg_rem <== Bool(false); - rem <== v_rem; - tc <== v_tc; + rem <== (io.div_fn === DIV_R) || (io.div_fn === DIV_RU); reg_waddr <== io.div_waddr; divby0 <== Bool(true); divisor <== in_rhs; diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 1e3ac340..9feaaa16 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -271,6 +271,7 @@ class rocketDpath extends Component alu.io.in1 := ex_alu_in1.toUFix; // divider + 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 && !io.ctrl.killx; div.io.div_waddr := ex_reg_waddr;