1
0
Fork 0

fix multiplier for rv32

This commit is contained in:
Andrew Waterman 2011-12-17 07:20:00 -08:00
parent a8d0cd95e6
commit 82700cad72
4 changed files with 35 additions and 27 deletions

View File

@ -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);

View File

@ -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),

View File

@ -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;

View File

@ -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)));