1
0

move replays to writeback stage

This commit is contained in:
Andrew Waterman 2012-01-17 21:12:31 -08:00
parent 1c8f496811
commit 0369b05deb
6 changed files with 54 additions and 41 deletions

View File

@ -21,7 +21,7 @@ object Constants
val PC_BR = UFix(3, 4); val PC_BR = UFix(3, 4);
val PC_JR = UFix(4, 4); val PC_JR = UFix(4, 4);
val PC_PCR = UFix(5, 4); val PC_PCR = UFix(5, 4);
val PC_MEM = UFix(6, 4); val PC_WB = UFix(6, 4);
val PC_EVEC = UFix(7, 4); val PC_EVEC = UFix(7, 4);
val KF_Y = UFix(1, 1); val KF_Y = UFix(1, 1);

View File

@ -11,6 +11,7 @@ class ioCtrlDpath extends Bundle()
// outputs to datapath // outputs to datapath
val sel_pc = UFix(4, 'output); val sel_pc = UFix(4, 'output);
val wen_btb = Bool('output); val wen_btb = Bool('output);
val clr_btb = Bool('output);
val stallf = Bool('output); val stallf = Bool('output);
val stalld = Bool('output); val stalld = Bool('output);
val killf = Bool('output); val killf = Bool('output);
@ -327,6 +328,7 @@ class rocketCtrl extends Component
val id_reg_xcpt_itlb = Reg(resetVal = Bool(false)); val id_reg_xcpt_itlb = Reg(resetVal = Bool(false));
val id_reg_xcpt_ma_inst = Reg(resetVal = Bool(false)); val id_reg_xcpt_ma_inst = Reg(resetVal = Bool(false));
val id_reg_icmiss = Reg(resetVal = Bool(false)); val id_reg_icmiss = Reg(resetVal = Bool(false));
val id_reg_replay = Reg(resetVal = Bool(false));
val ex_reg_br_type = Reg(){UFix(width = 4)}; val ex_reg_br_type = Reg(){UFix(width = 4)};
val ex_reg_btb_hit = Reg(){Bool()}; val ex_reg_btb_hit = Reg(){Bool()};
@ -345,7 +347,7 @@ class rocketCtrl extends Component
val ex_reg_xcpt_privileged = Reg(resetVal = Bool(false)); val ex_reg_xcpt_privileged = Reg(resetVal = Bool(false));
val ex_reg_xcpt_fpu = Reg(resetVal = Bool(false)); val ex_reg_xcpt_fpu = Reg(resetVal = Bool(false));
val ex_reg_xcpt_syscall = Reg(resetVal = Bool(false)); val ex_reg_xcpt_syscall = Reg(resetVal = Bool(false));
val ex_reg_icmiss = Reg(resetVal = Bool(false)); val ex_reg_replay = Reg(resetVal = Bool(false));
val mem_reg_inst_di = Reg(resetVal = Bool(false)); val mem_reg_inst_di = Reg(resetVal = Bool(false));
val mem_reg_inst_ei = Reg(resetVal = Bool(false)); val mem_reg_inst_ei = Reg(resetVal = Bool(false));
@ -364,22 +366,24 @@ class rocketCtrl extends Component
val wb_reg_eret = Reg(resetVal = Bool(false)); val wb_reg_eret = Reg(resetVal = Bool(false));
val wb_reg_exception = Reg(resetVal = Bool(false)); val wb_reg_exception = Reg(resetVal = Bool(false));
val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false)); val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false));
val wb_reg_replay = Reg(resetVal = Bool(false));
val wb_reg_cause = Reg(){UFix()}; val wb_reg_cause = Reg(){UFix()};
val take_pc = Wire() { Bool() }; val take_pc = Wire() { Bool() };
when (!io.dpath.stalld) { when (!io.dpath.stalld) {
when (io.dpath.killf) { when (io.dpath.killf) {
id_reg_btb_hit <== Bool(false);
id_reg_xcpt_ma_inst <== Bool(false); id_reg_xcpt_ma_inst <== Bool(false);
id_reg_xcpt_itlb <== Bool(false); id_reg_xcpt_itlb <== Bool(false);
id_reg_btb_hit <== Bool(false);
} }
otherwise{ otherwise{
id_reg_btb_hit <== io.dpath.btb_hit;
id_reg_xcpt_ma_inst <== if_reg_xcpt_ma_inst; id_reg_xcpt_ma_inst <== if_reg_xcpt_ma_inst;
id_reg_xcpt_itlb <== io.xcpt_itlb; id_reg_xcpt_itlb <== io.xcpt_itlb;
id_reg_btb_hit <== io.dpath.btb_hit;
} }
id_reg_icmiss <== !take_pc && !io.imem.resp_val; id_reg_icmiss <== !io.imem.resp_val;
id_reg_replay <== !take_pc && !io.imem.resp_val;
} }
// executing ERET when traps are enabled causes an illegal instruction exception (as per ISA sim) // executing ERET when traps are enabled causes an illegal instruction exception (as per ISA sim)
@ -402,7 +406,7 @@ class rocketCtrl extends Component
ex_reg_xcpt_privileged <== Bool(false); ex_reg_xcpt_privileged <== Bool(false);
ex_reg_xcpt_fpu <== Bool(false); ex_reg_xcpt_fpu <== Bool(false);
ex_reg_xcpt_syscall <== Bool(false); ex_reg_xcpt_syscall <== Bool(false);
ex_reg_icmiss <== Bool(false); ex_reg_replay <== Bool(false);
} }
otherwise { otherwise {
ex_reg_br_type <== id_br_type; ex_reg_br_type <== id_br_type;
@ -421,7 +425,7 @@ class rocketCtrl extends Component
// ex_reg_xcpt_fpu <== id_fp_val.toBool; // ex_reg_xcpt_fpu <== id_fp_val.toBool;
ex_reg_xcpt_fpu <== Bool(false); ex_reg_xcpt_fpu <== Bool(false);
ex_reg_xcpt_syscall <== id_syscall.toBool; ex_reg_xcpt_syscall <== id_syscall.toBool;
ex_reg_icmiss <== id_reg_icmiss; ex_reg_replay <== id_reg_replay;
} }
ex_reg_mem_cmd <== id_mem_cmd; ex_reg_mem_cmd <== id_mem_cmd;
ex_reg_mem_type <== id_mem_type; ex_reg_mem_type <== id_mem_type;
@ -492,14 +496,14 @@ class rocketCtrl extends Component
wb_reg_eret <== Bool(false); wb_reg_eret <== Bool(false);
wb_reg_inst_di <== Bool(false); wb_reg_inst_di <== Bool(false);
wb_reg_inst_ei <== Bool(false); wb_reg_inst_ei <== Bool(false);
wb_reg_div_mul_val <== Bool(false);
} }
otherwise { otherwise {
wb_reg_eret <== mem_reg_eret; wb_reg_eret <== mem_reg_eret;
wb_reg_inst_di <== mem_reg_inst_di; wb_reg_inst_di <== mem_reg_inst_di;
wb_reg_inst_ei <== mem_reg_inst_ei; wb_reg_inst_ei <== mem_reg_inst_ei;
wb_reg_div_mul_val <== mem_reg_div_mul_val;
} }
wb_reg_div_mul_val <== mem_reg_div_mul_val;
// exception handling // exception handling
// FIXME: verify PC in MEM stage points to valid, restartable instruction // FIXME: verify PC in MEM stage points to valid, restartable instruction
@ -547,40 +551,42 @@ class rocketCtrl extends Component
Mux(mem_xcpt_dtlb_st, UFix(11,5), // store fault Mux(mem_xcpt_dtlb_st, UFix(11,5), // store fault
UFix(0,5))))))))))); // instruction address misaligned UFix(0,5))))))))))); // instruction address misaligned
wb_reg_exception <== mem_exception;
wb_reg_badvaddr_wen <== mem_xcpt_dtlb_ld || mem_xcpt_dtlb_st;
wb_reg_cause <== mem_cause;
// write cause to PCR on an exception // write cause to PCR on an exception
io.dpath.exception := wb_reg_exception; io.dpath.exception := wb_reg_exception;
io.dpath.cause := wb_reg_cause; io.dpath.cause := wb_reg_cause;
io.dpath.badvaddr_wen := wb_reg_badvaddr_wen; io.dpath.badvaddr_wen := wb_reg_badvaddr_wen;
// replay mem stage PC on a DTLB miss
val replay_mem = io.dtlb_miss || io.dmem.resp_nack || mem_reg_replay;
val kill_mem = io.dtlb_miss || io.dmem.resp_nack || mem_exception;
val kill_dcache = io.dtlb_miss || mem_reg_kill || mem_exception;
// control transfer from ex/mem // control transfer from ex/mem
val ex_btb_match = ex_reg_btb_hit && io.dpath.btb_match val ex_btb_match = ex_reg_btb_hit && io.dpath.btb_match
val br_jr_taken = br_taken || jr_taken val br_jr_taken = br_taken || jr_taken
val take_pc_ex = !ex_btb_match && br_jr_taken || ex_reg_btb_hit && !br_jr_taken val take_pc_ex = !ex_btb_match && br_jr_taken || ex_reg_btb_hit && !br_jr_taken
val take_pc_mem = mem_exception || mem_reg_eret || replay_mem val take_pc_mem = Bool(false) //mem_exception || mem_reg_eret;
take_pc <== take_pc_ex || take_pc_mem val take_pc_wb = wb_reg_replay || wb_reg_exception || wb_reg_eret;
take_pc <== take_pc_ex || take_pc_mem || take_pc_wb;
// replay mem stage PC on a DTLB miss
val replay_mem = io.dtlb_miss || io.dmem.resp_nack || mem_reg_replay;
val kill_mem = io.dtlb_miss || io.dmem.resp_nack || take_pc_wb || mem_exception || mem_reg_kill;
val kill_dcache = io.dtlb_miss || take_pc_wb || mem_exception || mem_reg_kill;
// replay execute stage PC when the D$ is blocked, when the D$ misses, // replay execute stage PC when the D$ is blocked, when the D$ misses,
// for privileged instructions, and for fence.i instructions // for privileged instructions, and for fence.i instructions
val replay_ex = dcache_miss && Reg(io.dpath.mem_lu_bypass) || mem_reg_privileged || mem_reg_flush_inst || val replay_ex = dcache_miss && Reg(io.dpath.mem_lu_bypass) || mem_reg_privileged || mem_reg_flush_inst ||
ex_reg_mem_val && !(io.dmem.req_rdy && io.dtlb_rdy) ex_reg_replay || ex_reg_mem_val && !(io.dmem.req_rdy && io.dtlb_rdy)
val kill_ex = take_pc_mem || replay_ex val kill_ex = take_pc_mem || take_pc_wb || replay_ex
mem_reg_replay <== (ex_reg_icmiss || replay_ex) && !take_pc_mem; mem_reg_replay <== replay_ex && !(take_pc_mem || take_pc_wb);
mem_reg_kill <== kill_ex mem_reg_kill <== kill_ex;
wb_reg_replay <== replay_mem && !take_pc_wb;
wb_reg_exception <== mem_exception && !take_pc_wb;
wb_reg_badvaddr_wen <== (mem_xcpt_dtlb_ld || mem_xcpt_dtlb_st) && !take_pc_wb;
wb_reg_cause <== mem_cause;
io.dpath.sel_pc := io.dpath.sel_pc :=
Mux(replay_mem, PC_MEM, // dtlb miss Mux(wb_reg_exception, PC_EVEC, // exception
Mux(mem_exception, PC_EVEC, // exception Mux(wb_reg_replay, PC_WB, // replay
Mux(mem_reg_eret, PC_PCR, // eret instruction Mux(wb_reg_eret, PC_PCR, // eret instruction
Mux(ex_reg_btb_hit && !br_jr_taken, PC_EX4, // mispredicted not taken branch Mux(ex_reg_btb_hit && !br_jr_taken, PC_EX4, // mispredicted not taken branch
Mux(!ex_btb_match && br_taken, PC_BR, // mispredicted taken branch Mux(!ex_btb_match && br_taken, PC_BR, // mispredicted taken branch
Mux(!ex_btb_match && jr_taken, PC_JR, // mispredicted jump register Mux(!ex_btb_match && jr_taken, PC_JR, // mispredicted jump register
@ -588,6 +594,7 @@ class rocketCtrl extends Component
PC_4))))))); // PC+4 PC_4))))))); // PC+4
io.dpath.wen_btb := !ex_btb_match && br_jr_taken && !kill_ex; io.dpath.wen_btb := !ex_btb_match && br_jr_taken && !kill_ex;
io.dpath.clr_btb := ex_reg_btb_hit && !br_jr_taken || id_reg_icmiss;
// stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage. // stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage.
val ex_mem_cmd_load = val ex_mem_cmd_load =

View File

@ -111,6 +111,7 @@ class rocketDpath extends Component
val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false)); val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
// writeback definitions // writeback definitions
val wb_reg_valid = Reg(resetVal = Bool(false));
val wb_reg_pc = Reg() { UFix() }; val wb_reg_pc = Reg() { UFix() };
val wb_reg_waddr = Reg() { UFix() }; val wb_reg_waddr = Reg() { UFix() };
val wb_reg_wdata = Reg() { Bits() }; val wb_reg_wdata = Reg() { Bits() };
@ -145,9 +146,9 @@ class rocketDpath extends Component
Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4, Mux(io.ctrl.sel_pc === PC_EX4, ex_reg_pc_plus4,
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target, Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix, Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_wdata(VADDR_BITS-1,0), // only used for ERET Mux(io.ctrl.sel_pc === PC_PCR, wb_reg_wdata(VADDR_BITS-1,0), // only used for ERET
Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec, Mux(io.ctrl.sel_pc === PC_EVEC, pcr.io.evec,
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc, Mux(io.ctrl.sel_pc === PC_WB, wb_reg_pc,
if_pc_plus4))))))); // PC_4 if_pc_plus4))))))); // PC_4
when (!io.ctrl.stallf) { when (!io.ctrl.stallf) {
@ -164,6 +165,7 @@ class rocketDpath extends Component
btb.io.current_pc4 := if_pc_plus4; btb.io.current_pc4 := if_pc_plus4;
btb.io.hit ^^ io.ctrl.btb_hit; btb.io.hit ^^ io.ctrl.btb_hit;
btb.io.wen ^^ io.ctrl.wen_btb; btb.io.wen ^^ io.ctrl.wen_btb;
btb.io.clr ^^ io.ctrl.clr_btb;
btb.io.correct_pc4 := ex_reg_pc_plus4; btb.io.correct_pc4 := ex_reg_pc_plus4;
io.ctrl.btb_match := id_reg_pc === jr_br_target; io.ctrl.btb_match := id_reg_pc === jr_br_target;
@ -345,7 +347,7 @@ class rocketDpath extends Component
tsc_reg <== tsc_reg + UFix(1); tsc_reg <== tsc_reg + UFix(1);
// instructions retired counter // instructions retired counter
val irt_reg = Reg(resetVal = UFix(0,64)); val irt_reg = Reg(resetVal = UFix(0,64));
when (mem_reg_valid) { irt_reg <== irt_reg + UFix(1); } when (wb_reg_valid) { irt_reg <== irt_reg + UFix(1); }
// writeback select mux // writeback select mux
ex_wdata := ex_wdata :=
@ -394,10 +396,12 @@ class rocketDpath extends Component
wb_reg_raddr2 <== mem_reg_raddr2; wb_reg_raddr2 <== mem_reg_raddr2;
when (io.ctrl.killm) { when (io.ctrl.killm) {
wb_reg_valid <== Bool(false);
wb_reg_ctrl_wen <== Bool(false); wb_reg_ctrl_wen <== Bool(false);
wb_reg_ctrl_wen_pcr <== Bool(false); wb_reg_ctrl_wen_pcr <== Bool(false);
} }
otherwise { otherwise {
wb_reg_valid <== mem_reg_valid;
wb_reg_ctrl_wen <== mem_reg_ctrl_wen && !io.dmem.resp_miss; wb_reg_ctrl_wen <== mem_reg_ctrl_wen && !io.dmem.resp_miss;
wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr; wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr;
} }

View File

@ -12,6 +12,7 @@ class ioDpathBTB extends Bundle()
val hit = Bool('output); val hit = Bool('output);
val target = UFix(VADDR_BITS, 'output); val target = UFix(VADDR_BITS, 'output);
val wen = Bool('input); val wen = Bool('input);
val clr = Bool('input);
val correct_pc4 = UFix(VADDR_BITS, 'input); val correct_pc4 = UFix(VADDR_BITS, 'input);
val correct_target = UFix(VADDR_BITS, 'input); val correct_target = UFix(VADDR_BITS, 'input);
} }
@ -27,13 +28,13 @@ class rocketDpathBTB(entries: Int) extends Component
val tagmsb = (VADDR_BITS-idxmsb-1)+(VADDR_BITS-idxlsb)-1; val tagmsb = (VADDR_BITS-idxmsb-1)+(VADDR_BITS-idxlsb)-1;
val taglsb = (VADDR_BITS-idxlsb); val taglsb = (VADDR_BITS-idxlsb);
val rst_lwlr_pf = Mem(entries, io.wen, io.correct_pc4(idxmsb,idxlsb), UFix(1,1), resetVal = UFix(0,1)); val vb_array = Mem(entries, io.wen || io.clr, io.correct_pc4(idxmsb,idxlsb), !io.clr, resetVal = Bool(false));
val lwlr_pf = Mem(entries, io.wen, io.correct_pc4(idxmsb,idxlsb), val tag_target_array = Mem(entries, io.wen, io.correct_pc4(idxmsb,idxlsb),
Cat(io.correct_pc4(VADDR_BITS-1,idxmsb+1), io.correct_target(VADDR_BITS-1,idxlsb)), resetVal = UFix(0,1)); Cat(io.correct_pc4(VADDR_BITS-1,idxmsb+1), io.correct_target(VADDR_BITS-1,idxlsb)))
val is_val = rst_lwlr_pf(io.current_pc4(idxmsb,idxlsb)); val is_val = vb_array(io.current_pc4(idxmsb,idxlsb));
val tag_target = lwlr_pf(io.current_pc4(idxmsb, idxlsb)); val tag_target = tag_target_array(io.current_pc4(idxmsb, idxlsb));
io.hit := (is_val & (tag_target(tagmsb,taglsb) === io.current_pc4(VADDR_BITS-1, idxmsb+1))).toBool; io.hit := is_val && (tag_target(tagmsb,taglsb) === io.current_pc4(VADDR_BITS-1, idxmsb+1));
io.target := Cat(tag_target(taglsb-1, 0), Bits(0,idxlsb)).toUFix; io.target := Cat(tag_target(taglsb-1, 0), Bits(0,idxlsb)).toUFix;
} }

View File

@ -55,10 +55,10 @@ class rocketDTLB(entries: Int) extends Component
r_cpu_req_vpn <== io.cpu.req_vpn; r_cpu_req_vpn <== io.cpu.req_vpn;
r_cpu_req_cmd <== io.cpu.req_cmd; r_cpu_req_cmd <== io.cpu.req_cmd;
r_cpu_req_asid <== io.cpu.req_asid; r_cpu_req_asid <== io.cpu.req_asid;
r_cpu_req_val <== Bool(true);
} }
otherwise {
when (io.cpu.req_rdy) { r_cpu_req_val <== Bool(false);
r_cpu_req_val <== io.cpu.req_val;
} }
val req_load = (r_cpu_req_cmd === M_XRD); val req_load = (r_cpu_req_cmd === M_XRD);

View File

@ -106,9 +106,10 @@ class rocketITLB(entries: Int) extends Component
when (io.cpu.req_val && io.cpu.req_rdy) { when (io.cpu.req_val && io.cpu.req_rdy) {
r_cpu_req_vpn <== io.cpu.req_vpn; r_cpu_req_vpn <== io.cpu.req_vpn;
r_cpu_req_asid <== io.cpu.req_asid; r_cpu_req_asid <== io.cpu.req_asid;
r_cpu_req_val <== Bool(true);
} }
when (io.cpu.req_rdy) { otherwise {
r_cpu_req_val <== io.cpu.req_val; r_cpu_req_val <== Bool(false);
} }
val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn); val lookup_tag = Cat(r_cpu_req_asid, r_cpu_req_vpn);