fix multiplier for rv32
This commit is contained in:
parent
a8d0cd95e6
commit
82700cad72
@ -44,13 +44,11 @@ object Constants
|
|||||||
val A1_RS1 = UFix(0, 1);
|
val A1_RS1 = UFix(0, 1);
|
||||||
val A1_LUI = UFix(1, 1);
|
val A1_LUI = UFix(1, 1);
|
||||||
|
|
||||||
val MUL_X = UFix(0, 3);
|
val MUL_X = UFix(0, 2);
|
||||||
val MUL_NO = UFix(0, 3);
|
val MUL_LO = UFix(0, 2);
|
||||||
val MUL_64 = UFix(1, 3);
|
val MUL_HU = UFix(1, 2);
|
||||||
val MUL_64H = UFix(2, 3);
|
val MUL_HS = UFix(2, 2);
|
||||||
val MUL_64HU = UFix(3, 3);
|
val MUL_HSU = UFix(3, 2);
|
||||||
val MUL_64HSU = UFix(4, 3);
|
|
||||||
val MUL_32 = UFix(5, 3);
|
|
||||||
|
|
||||||
val DIV_X = UFix(0, 4);
|
val DIV_X = UFix(0, 4);
|
||||||
val DIV_NO = UFix(0, 4);
|
val DIV_NO = UFix(0, 4);
|
||||||
|
@ -24,7 +24,7 @@ class ioCtrlDpath extends Bundle()
|
|||||||
val fn_dw = Bool('output);
|
val fn_dw = Bool('output);
|
||||||
val fn_alu = UFix(4, 'output);
|
val fn_alu = UFix(4, 'output);
|
||||||
val mul_val = Bool('output);
|
val mul_val = Bool('output);
|
||||||
val mul_fn = UFix(3, 'output);
|
val mul_fn = UFix(2, 'output);
|
||||||
val mul_wb = Bool('output);
|
val mul_wb = Bool('output);
|
||||||
val div_val = Bool('output);
|
val div_val = Bool('output);
|
||||||
val div_fn = UFix(4, '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),
|
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),
|
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),
|
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_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),
|
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_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),
|
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_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),
|
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_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),
|
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),
|
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),
|
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),
|
||||||
|
@ -283,6 +283,7 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
// multiplier
|
// multiplier
|
||||||
mul.io.mul_val := ex_reg_ctrl_mul_val && !io.ctrl.killx;
|
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_fn := ex_reg_ctrl_mul_fn;
|
||||||
mul.io.mul_tag := ex_reg_waddr;
|
mul.io.mul_tag := ex_reg_waddr;
|
||||||
mul.io.in0 := ex_reg_rs1;
|
mul.io.in0 := ex_reg_rs1;
|
||||||
|
@ -7,7 +7,8 @@ import Constants._;
|
|||||||
class ioMultiplier(width: Int) extends Bundle {
|
class ioMultiplier(width: Int) extends Bundle {
|
||||||
// requests
|
// requests
|
||||||
val mul_val = Bool('input);
|
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 mul_tag = UFix(5, 'input);
|
||||||
val in0 = Bits(width, 'input);
|
val in0 = Bits(width, 'input);
|
||||||
val in1 = Bits(width, 'input);
|
val in1 = Bits(width, 'input);
|
||||||
@ -22,30 +23,38 @@ class rocketMultiplier extends Component {
|
|||||||
val io = new ioMultiplier(64);
|
val io = new ioMultiplier(64);
|
||||||
|
|
||||||
val r_val = Reg(resetVal = Bool(false));
|
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_fn = Reg(resetVal = UFix(0,3));
|
||||||
val r_tag = Reg(resetVal = UFix(0,5));
|
val r_tag = Reg(resetVal = UFix(0,5));
|
||||||
val r_in0 = Reg(resetVal = Bits(0,64));
|
val r_lhs = Reg(resetVal = Bits(0,65));
|
||||||
val r_in1 = Reg(resetVal = Bits(0,64));
|
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;
|
r_val <== io.mul_val;
|
||||||
when (io.mul_val) {
|
when (io.mul_val) {
|
||||||
|
r_dw <== io.dw
|
||||||
r_fn <== io.mul_fn;
|
r_fn <== io.mul_fn;
|
||||||
r_tag <== io.mul_tag;
|
r_tag <== io.mul_tag;
|
||||||
r_in0 <== io.in0;
|
r_lhs <== lhs;
|
||||||
r_in1 <== io.in1;
|
r_rhs <== rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
val sxl64 = (r_fn === MUL_64H) || (r_fn === MUL_64HSU);
|
val mul_result = r_lhs.toFix * r_rhs.toFix;
|
||||||
val sxr64 = (r_fn === MUL_64H);
|
|
||||||
|
|
||||||
val lhs = Cat(r_in0(63) & sxl64, r_in0);
|
val mul_output64 = Mux(r_fn === MUL_LO, mul_result(63,0), mul_result(127,64))
|
||||||
val rhs = Cat(r_in1(63) & sxr64, r_in1);
|
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 = Mux(r_dw === DW_64, mul_output64, mul_output32_ext)
|
||||||
|
|
||||||
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))));
|
|
||||||
|
|
||||||
// just a hack for now, this should be a parameterized number of stages
|
// just a hack for now, this should be a parameterized number of stages
|
||||||
val r_result = Reg(Reg(Reg(mul_output)));
|
val r_result = Reg(Reg(Reg(mul_output)));
|
||||||
|
Loading…
Reference in New Issue
Block a user