1
0

improve id/ex datapath

move operand selection into decode stage; simplify bypassing
This commit is contained in:
Andrew Waterman
2012-02-08 06:47:26 -08:00
parent d471a8b2da
commit e9da2cf66a
4 changed files with 179 additions and 207 deletions

View File

@ -75,13 +75,11 @@ class rocketDpath extends Component
// execute definitions
val ex_reg_valid = Reg(resetVal = Bool(false));
val ex_reg_pc = Reg() { UFix() };
val ex_reg_inst = Reg() { Bits() };
val ex_reg_raddr2 = Reg() { UFix() };
val ex_reg_op2 = Reg() { Bits() };
val ex_reg_rs2 = Reg() { Bits() };
val ex_reg_rs1 = Reg() { Bits() };
val ex_reg_waddr = Reg() { UFix() };
val ex_reg_ctrl_sel_alu2 = Reg() { UFix() };
val ex_reg_ctrl_sel_alu1 = Reg() { UFix() };
val ex_reg_ctrl_eret = Reg(resetVal = Bool(false));
val ex_reg_ctrl_fn_dw = Reg() { UFix() };
val ex_reg_ctrl_fn_alu = Reg() { UFix() };
@ -124,31 +122,23 @@ class rocketDpath extends Component
val if_pc_plus4 = if_reg_pc + UFix(4);
val ex_pc_plus4 = ex_reg_pc + UFix(4);
val ex_sign_extend =
Cat(Fill(52, ex_reg_inst(21)), ex_reg_inst(21,10));
val ex_sign_extend_split =
Cat(Fill(52, ex_reg_inst(31)), ex_reg_inst(31,27), ex_reg_inst(16,10));
val ex_branch_target = ex_reg_pc + Cat(ex_reg_op2, Bits(0,1)).toUFix
val branch_adder_rhs =
Mux(io.ctrl.ex_jmp, Cat(Fill(VADDR_BITS-25, ex_reg_inst(31)), ex_reg_inst(31,7), UFix(0,1)),
Cat(ex_sign_extend_split(VADDR_BITS-1,0), UFix(0, 1)));
val ex_branch_target = ex_reg_pc + branch_adder_rhs.toUFix;
val ex_jr_target_sign = Mux(ex_alu_adder_out(VADDR_BITS-1), ~ex_alu_adder_out(63,VADDR_BITS) === UFix(0), ex_alu_adder_out(63,VADDR_BITS) != UFix(0))
val ex_jr_target_extended = Cat(ex_jr_target_sign, ex_alu_adder_out(VADDR_BITS-1,0)).toUFix
val jr_br_target = Mux(io.ctrl.ex_jr, ex_jr_target_extended, ex_branch_target);
btb.io.correct_target := jr_br_target
val ex_ea_sign = Mux(ex_alu_adder_out(VADDR_BITS-1), ~ex_alu_adder_out(63,VADDR_BITS) === UFix(0), ex_alu_adder_out(63,VADDR_BITS) != UFix(0))
val ex_effective_address = Cat(ex_ea_sign, ex_alu_adder_out(VADDR_BITS-1,0)).toUFix
val ex_br_target_sel = Reg(io.ctrl.sel_alu2 === A2_BTYPE || io.ctrl.sel_alu2 === A2_JTYPE)
val ex_br_target = Mux(ex_br_target_sel, ex_branch_target, ex_effective_address)
btb.io.correct_target := ex_br_target
val if_next_pc =
Mux(io.ctrl.sel_pc === PC_BTB, Cat(if_btb_target(VADDR_BITS-1), if_btb_target),
Mux(io.ctrl.sel_pc === PC_EX4, ex_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target_extended,
Mux(io.ctrl.sel_pc === PC_BR, ex_br_target,
Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS,0), // only used for ERET
Mux(io.ctrl.sel_pc === PC_EVEC, Cat(pcr.io.evec(VADDR_BITS-1), pcr.io.evec),
Mux(io.ctrl.sel_pc === PC_WB, wb_reg_pc,
if_pc_plus4))))))); // PC_4
if_pc_plus4)))))); // PC_4
when (!io.ctrl.stallf) {
if_reg_pc <== if_next_pc.toUFix;
@ -165,7 +155,7 @@ class rocketDpath extends Component
btb.io.wen <> io.ctrl.wen_btb;
btb.io.clr <> io.ctrl.clr_btb;
btb.io.correct_pc4 := ex_pc_plus4;
io.ctrl.btb_match := id_reg_pc === jr_br_target;
io.ctrl.btb_match := id_reg_pc === ex_br_target;
// instruction decode stage
when (!io.ctrl.stalld) {
@ -210,17 +200,33 @@ class rocketDpath extends Component
Mux((io.ctrl.wb_wen || wb_reg_ll_wb) && id_raddr2 === wb_reg_waddr, wb_wdata,
id_rdata2)));
// immediate generation
val id_imm_bj = io.ctrl.sel_alu2 === A2_BTYPE || io.ctrl.sel_alu2 === A2_JTYPE
val id_imm_l = io.ctrl.sel_alu2 === A2_LTYPE
val id_imm_zero = io.ctrl.sel_alu2 === A2_ZERO || io.ctrl.sel_alu2 === A2_RTYPE
val id_imm_ibz = io.ctrl.sel_alu2 === A2_ITYPE || io.ctrl.sel_alu2 === A2_BTYPE || id_imm_zero
val id_imm_sign = Mux(id_imm_bj, id_reg_inst(31),
Mux(id_imm_l, id_reg_inst(26),
Mux(id_imm_zero, Bits(0,1),
id_reg_inst(21)))) // IMM_ITYPE
val id_imm_small = Mux(id_imm_zero, Bits(0,12),
Cat(Mux(id_imm_bj, id_reg_inst(31,27), id_reg_inst(21,17)), id_reg_inst(16,10)))
val id_imm = Cat(Fill(32, id_imm_sign),
Mux(id_imm_l, Cat(id_reg_inst(26,7), Bits(0,12)),
Mux(id_imm_ibz, Cat(Fill(20, id_imm_sign), id_imm_small),
Cat(Fill(7, id_imm_sign), id_reg_inst(31,7))))) // A2_JTYPE
val id_op2 = Mux(io.ctrl.sel_alu2 === A2_RTYPE, id_rs2, id_imm)
io.ctrl.inst := id_reg_inst;
// execute stage
ex_reg_pc <== id_reg_pc;
ex_reg_inst <== id_reg_inst;
ex_reg_raddr2 <== id_raddr2;
ex_reg_op2 <== id_op2;
ex_reg_rs2 <== id_rs2;
ex_reg_rs1 <== id_rs1;
ex_reg_waddr <== id_waddr;
ex_reg_ctrl_sel_alu2 <== io.ctrl.sel_alu2;
ex_reg_ctrl_sel_alu1 <== io.ctrl.sel_alu1.toUFix;
ex_reg_ctrl_fn_dw <== io.ctrl.fn_dw.toUFix;
ex_reg_ctrl_fn_alu <== io.ctrl.fn_alu;
ex_reg_ctrl_mul_fn <== io.ctrl.mul_fn;
@ -243,24 +249,10 @@ class rocketDpath extends Component
ex_reg_ctrl_eret <== io.ctrl.id_eret;
}
val ex_alu_in2 =
Mux(ex_reg_ctrl_sel_alu2 === A2_SEXT, ex_sign_extend,
Mux(ex_reg_ctrl_sel_alu2 === A2_SPLIT, ex_sign_extend_split,
Mux(ex_reg_ctrl_sel_alu2 === A2_RS2, ex_reg_rs2,
UFix(0, 64)))); // A2_0
val ex_alu_in1 =
Mux(ex_reg_ctrl_sel_alu1 === A1_RS1, ex_reg_rs1,
Cat(Fill(32, ex_reg_inst(26)),ex_reg_inst(26,7),UFix(0, 12))); // A1_LUI
val ex_alu_shamt =
Cat(ex_alu_in2(5) & ex_reg_ctrl_fn_dw === DW_64, ex_alu_in2(4,0)).toUFix;
alu.io.dw := ex_reg_ctrl_fn_dw;
alu.io.fn := ex_reg_ctrl_fn_alu;
alu.io.shamt := ex_alu_shamt.toUFix;
alu.io.in2 := ex_alu_in2.toUFix;
alu.io.in1 := ex_alu_in1.toUFix;
alu.io.in2 := ex_reg_op2.toUFix;
alu.io.in1 := ex_reg_rs1.toUFix;
// divider
div.io.dw := ex_reg_ctrl_fn_dw;
@ -292,7 +284,7 @@ class rocketDpath extends Component
// D$ request interface (registered inside D$ module)
// other signals (req_val, req_rdy) connect to control module
io.dmem.req_addr := ex_jr_target_extended.toUFix;
io.dmem.req_addr := ex_effective_address.toUFix;
if (HAVE_FPU) {
io.dmem.req_data := Mux(io.ctrl.ex_fp_val, io.fpu.store_data, ex_reg_rs2)
io.dmem.req_tag := Cat(ex_reg_waddr, io.ctrl.ex_fp_val).toUFix
@ -335,12 +327,11 @@ class rocketDpath extends Component
// writeback select mux
ex_wdata :=
Mux(ex_reg_ctrl_wen_pcr, ex_reg_rs1,
Mux(ex_reg_ctrl_sel_wb === WB_PC, Cat(Fill(64-VADDR_BITS, ex_pc_plus4(VADDR_BITS-1)), ex_pc_plus4),
Mux(ex_reg_ctrl_sel_wb === WB_PCR, ex_pcr,
Mux(ex_reg_ctrl_sel_wb === WB_TSC, tsc_reg,
Mux(ex_reg_ctrl_sel_wb === WB_IRT, irt_reg,
ex_alu_out))))).toBits; // WB_ALU
ex_alu_out)))).toBits; // WB_ALU
// memory stage
mem_reg_pc <== ex_reg_pc;