fix divider for RV32
This commit is contained in:
parent
bcceb08373
commit
b5a8b6dc73
@ -50,16 +50,11 @@ object Constants
|
|||||||
val MUL_HS = UFix(2, 2);
|
val MUL_HS = UFix(2, 2);
|
||||||
val MUL_HSU = UFix(3, 2);
|
val MUL_HSU = UFix(3, 2);
|
||||||
|
|
||||||
val DIV_X = UFix(0, 4);
|
val DIV_X = UFix(0, 2);
|
||||||
val DIV_NO = UFix(0, 4);
|
val DIV_D = UFix(0, 2);
|
||||||
val DIV_64D = UFix(1, 4);
|
val DIV_DU = UFix(1, 2);
|
||||||
val DIV_64DU = UFix(2, 4);
|
val DIV_R = UFix(2, 2);
|
||||||
val DIV_64R = UFix(3, 4);
|
val DIV_RU = UFix(3, 2);
|
||||||
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 M_N = UFix(0, 1);
|
val M_N = UFix(0, 1);
|
||||||
val M_Y = UFix(1, 1);
|
val M_Y = UFix(1, 1);
|
||||||
|
@ -27,7 +27,7 @@ class ioCtrlDpath extends Bundle()
|
|||||||
val mul_fn = UFix(2, '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(2, 'output);
|
||||||
val div_wb = Bool('output);
|
val div_wb = Bool('output);
|
||||||
val sel_wa = Bool('output);
|
val sel_wa = Bool('output);
|
||||||
val sel_wb = UFix(3, '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),
|
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),
|
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_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_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_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_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),
|
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_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),
|
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_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),
|
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_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),
|
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_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),
|
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_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),
|
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),
|
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),
|
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),
|
||||||
|
@ -8,7 +8,8 @@ class ioDivider(width: Int) extends Bundle {
|
|||||||
// requests
|
// requests
|
||||||
val div_val = Bool('input);
|
val div_val = Bool('input);
|
||||||
val div_rdy = Bool('output);
|
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 div_waddr = UFix(5, 'input);
|
||||||
val dpath_rs1 = Bits(width, 'input);
|
val dpath_rs1 = Bits(width, 'input);
|
||||||
val dpath_rs2 = 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 reg_waddr = Reg(resetVal = UFix(0, 5));
|
||||||
val rem = Reg(resetVal = Bool(false));
|
val rem = Reg(resetVal = Bool(false));
|
||||||
val half = Reg(resetVal = Bool(false));
|
val half = Reg(resetVal = Bool(false));
|
||||||
val tc = Reg(resetVal = Bool(false));
|
|
||||||
|
|
||||||
val divisor = Reg(resetVal = UFix(0, width));
|
val divisor = Reg(resetVal = UFix(0, width));
|
||||||
val remainder = Reg(resetVal = UFix(0, 2*width+1));
|
val remainder = Reg(resetVal = UFix(0, 2*width+1));
|
||||||
val subtractor = remainder(2*width, width).toUFix - divisor;
|
val subtractor = remainder(2*width, width).toUFix - divisor;
|
||||||
|
|
||||||
val v_tc = ((io.div_fn === DIV_64D) || (io.div_fn === DIV_64R)) ||
|
val tc = (io.div_fn === DIV_D) || (io.div_fn === DIV_R);
|
||||||
((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));
|
|
||||||
|
|
||||||
// state machine
|
// state machine
|
||||||
switch (state) {
|
switch (state) {
|
||||||
is (s_ready) {
|
is (s_ready) {
|
||||||
when (!io.div_val) { state <== 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; }
|
otherwise { state <== s_busy; }
|
||||||
}
|
}
|
||||||
is (s_neg_inputs) { 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
|
// if we're doing 32-bit unsigned division, then we don't want the 32-bit
|
||||||
// inputs to be sign-extended.
|
// 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)),
|
Cat(Fill(width/2, UFix(0,1)), io.dpath_rs1(width/2-1, 0)),
|
||||||
io.dpath_rs1).toUFix;
|
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)),
|
Cat(Fill(width/2, UFix(0,1)), io.dpath_rs2(width/2-1, 0)),
|
||||||
io.dpath_rs2).toUFix;
|
io.dpath_rs2).toUFix;
|
||||||
|
|
||||||
when ((state === s_ready) && io.div_val) {
|
when ((state === s_ready) && io.div_val) {
|
||||||
count <== UFix(0, count_bits);
|
count <== UFix(0, count_bits);
|
||||||
half <== v_half;
|
half <== (io.dw === DW_32);
|
||||||
neg_quo <== Bool(false);
|
neg_quo <== Bool(false);
|
||||||
neg_rem <== Bool(false);
|
neg_rem <== Bool(false);
|
||||||
rem <== v_rem;
|
rem <== (io.div_fn === DIV_R) || (io.div_fn === DIV_RU);
|
||||||
tc <== v_tc;
|
|
||||||
reg_waddr <== io.div_waddr;
|
reg_waddr <== io.div_waddr;
|
||||||
divby0 <== Bool(true);
|
divby0 <== Bool(true);
|
||||||
divisor <== in_rhs;
|
divisor <== in_rhs;
|
||||||
|
@ -271,6 +271,7 @@ class rocketDpath extends Component
|
|||||||
alu.io.in1 := ex_alu_in1.toUFix;
|
alu.io.in1 := ex_alu_in1.toUFix;
|
||||||
|
|
||||||
// divider
|
// divider
|
||||||
|
div.io.dw := ex_reg_ctrl_fn_dw;
|
||||||
div.io.div_fn := ex_reg_ctrl_div_fn;
|
div.io.div_fn := ex_reg_ctrl_div_fn;
|
||||||
div.io.div_val := ex_reg_ctrl_div_val && !io.ctrl.killx;
|
div.io.div_val := ex_reg_ctrl_div_val && !io.ctrl.killx;
|
||||||
div.io.div_waddr := ex_reg_waddr;
|
div.io.div_waddr := ex_reg_waddr;
|
||||||
|
Loading…
Reference in New Issue
Block a user