From 82700cad7254cf3f84caabdc76b20fdee7d537b4 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 17 Dec 2011 07:20:00 -0800 Subject: [PATCH] fix multiplier for rv32 --- rocket/src/main/scala/consts.scala | 12 ++++----- rocket/src/main/scala/ctrl.scala | 12 ++++----- rocket/src/main/scala/dpath.scala | 1 + rocket/src/main/scala/multiplier.scala | 37 ++++++++++++++++---------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 16f7b8a2..9906eaa9 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -44,13 +44,11 @@ object Constants val A1_RS1 = UFix(0, 1); val A1_LUI = UFix(1, 1); - val MUL_X = UFix(0, 3); - val MUL_NO = UFix(0, 3); - val MUL_64 = UFix(1, 3); - val MUL_64H = UFix(2, 3); - val MUL_64HU = UFix(3, 3); - val MUL_64HSU = UFix(4, 3); - val MUL_32 = UFix(5, 3); + val MUL_X = UFix(0, 2); + val MUL_LO = UFix(0, 2); + val MUL_HU = UFix(1, 2); + val MUL_HS = UFix(2, 2); + val MUL_HSU = UFix(3, 2); val DIV_X = UFix(0, 4); val DIV_NO = UFix(0, 4); diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index f44ee4d5..05220c7f 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -24,7 +24,7 @@ class ioCtrlDpath extends Bundle() val fn_dw = Bool('output); val fn_alu = UFix(4, 'output); val mul_val = Bool('output); - val mul_fn = UFix(3, 'output); + val mul_fn = UFix(2, 'output); val mul_wb = Bool('output); val div_val = Bool('output); val div_fn = UFix(4, 'output); @@ -234,11 +234,11 @@ class rocketCtrl extends Component SRLW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_RS2, A1_RS1,DW_32,FN_SR, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,I_X ,SYNC_N,N,N,N), SRAW-> List(xpr64, BR_N, REN_Y,REN_Y,A2_RS2, A1_RS1,DW_32,FN_SRA, M_N,M_X, MT_X, N,MUL_X, N,DIV_X, WEN_Y,WA_RD,WB_ALU,REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - MUL-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, Y,MUL_64, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - MULH-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, Y,MUL_64H, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - MULHU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, Y,MUL_64HU, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), - MULHSU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_X, FN_X, M_N,M_X, MT_X, Y,MUL_64HSU, 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_X, FN_X, M_N,M_X, MT_X, Y,MUL_32, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + MUL-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,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), + MULH-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, Y,MUL_HS, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + MULHU-> List(Y, BR_N, REN_Y,REN_Y,A2_X, A1_X, DW_XPR,FN_X, M_N,M_X, MT_X, Y,MUL_HU, N,DIV_X, WEN_N,WA_RD,WB_X, REN_N,WEN_N,I_X ,SYNC_N,N,N,N), + 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), diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index 57f2efd6..f394361d 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -283,6 +283,7 @@ class rocketDpath extends Component // multiplier mul.io.mul_val := ex_reg_ctrl_mul_val && !io.ctrl.killx; + mul.io.dw := ex_reg_ctrl_fn_dw; mul.io.mul_fn := ex_reg_ctrl_mul_fn; mul.io.mul_tag := ex_reg_waddr; mul.io.in0 := ex_reg_rs1; diff --git a/rocket/src/main/scala/multiplier.scala b/rocket/src/main/scala/multiplier.scala index 67a53ac3..bbcbef3b 100644 --- a/rocket/src/main/scala/multiplier.scala +++ b/rocket/src/main/scala/multiplier.scala @@ -7,7 +7,8 @@ import Constants._; class ioMultiplier(width: Int) extends Bundle { // requests val mul_val = Bool('input); - val mul_fn = UFix(3, 'input); + val dw = UFix(1, 'input); + val mul_fn = UFix(2, 'input); val mul_tag = UFix(5, 'input); val in0 = Bits(width, 'input); val in1 = Bits(width, 'input); @@ -22,30 +23,38 @@ class rocketMultiplier extends Component { val io = new ioMultiplier(64); val r_val = Reg(resetVal = Bool(false)); + val r_dw = Reg(resetVal = UFix(0,1)); val r_fn = Reg(resetVal = UFix(0,3)); val r_tag = Reg(resetVal = UFix(0,5)); - val r_in0 = Reg(resetVal = Bits(0,64)); - val r_in1 = Reg(resetVal = Bits(0,64)); + val r_lhs = Reg(resetVal = Bits(0,65)); + val r_rhs = Reg(resetVal = Bits(0,65)); + + val lhs_msb = Mux(io.dw === DW_64, io.in0(63), io.in0(31)).toBool + val lhs_sign = ((io.mul_fn === MUL_HS) || (io.mul_fn === MUL_HSU)) && lhs_msb + val lhs_hi = Mux(io.dw === DW_64, io.in0(63,32), Fill(32, lhs_sign)) + val lhs = Cat(lhs_sign, lhs_hi, io.in0(31,0)) + + val rhs_msb = Mux(io.dw === DW_64, io.in1(63), io.in1(31)).toBool + val rhs_sign = (io.mul_fn === MUL_HS) && rhs_msb + val rhs_hi = Mux(io.dw === DW_64, io.in1(63,32), Fill(32, rhs_sign)) + val rhs = Cat(rhs_sign, rhs_hi, io.in1(31,0)) r_val <== io.mul_val; when (io.mul_val) { + r_dw <== io.dw r_fn <== io.mul_fn; r_tag <== io.mul_tag; - r_in0 <== io.in0; - r_in1 <== io.in1; + r_lhs <== lhs; + r_rhs <== rhs; } - val sxl64 = (r_fn === MUL_64H) || (r_fn === MUL_64HSU); - val sxr64 = (r_fn === MUL_64H); + val mul_result = r_lhs.toFix * r_rhs.toFix; - val lhs = Cat(r_in0(63) & sxl64, r_in0); - val rhs = Cat(r_in1(63) & sxr64, r_in1); + val mul_output64 = Mux(r_fn === MUL_LO, mul_result(63,0), mul_result(127,64)) + val mul_output32 = Mux(r_fn === MUL_LO, mul_result(31,0), mul_result(63,31)) + val mul_output32_ext = Cat(Fill(32, mul_output32(31)), mul_output32) - val mul_result = lhs.toFix * rhs.toFix; - - val mul_output = MuxCase(mul_result(63,0), Array( - ((r_fn === MUL_64H) || (r_fn === MUL_64HU) || (r_fn === MUL_64HSU)) -> mul_result(127,64), - (r_fn === MUL_32) -> Cat(Fill(32, mul_result(31)), mul_result(31, 0)))); + val mul_output = Mux(r_dw === DW_64, mul_output64, mul_output32_ext) // just a hack for now, this should be a parameterized number of stages val r_result = Reg(Reg(Reg(mul_output)));