fixes to exception and dcache miss/blocked handling
This commit is contained in:
parent
7a528d6255
commit
3a02028a35
@ -56,8 +56,6 @@ class ioCtrlDpath extends Bundle()
|
||||
val wb_waddr = UFix(5,'input); // write addr from writeback stage
|
||||
val exception = Bool('input);
|
||||
val status = Bits(8, 'input);
|
||||
// val sboard_set = Bool('input);
|
||||
// val sboard_seta = UFix(5, 'input);
|
||||
val sboard_clr0 = Bool('input);
|
||||
val sboard_clr0a = UFix(5, 'input);
|
||||
val sboard_clr1 = Bool('input);
|
||||
@ -214,9 +212,6 @@ class rocketCtrl extends Component
|
||||
sboard.io.raddra := id_raddr2.toUFix;
|
||||
sboard.io.raddrb := id_raddr1.toUFix;
|
||||
sboard.io.raddrc := id_waddr.toUFix;
|
||||
|
||||
// sboard.io.set := io.dpath.sboard_set;
|
||||
// sboard.io.seta := io.dpath.sboard_seta;
|
||||
|
||||
// scoreboard set (for D$ misses, div, mul)
|
||||
sboard.io.set := wb_reg_div_mul_val | dcache_miss;
|
||||
@ -298,21 +293,27 @@ class rocketCtrl extends Component
|
||||
io.dmem.req_type := ex_reg_mem_type;
|
||||
|
||||
val mem_reg_div_mul_val = Reg(){Bool()};
|
||||
val mem_reg_eret = Reg(){Bool()};
|
||||
val mem_reg_mem_val = Reg(){Bool()};
|
||||
val mem_reg_mem_cmd = Reg(){UFix(width = 4)};
|
||||
val mem_reg_mem_type = Reg(){UFix(width = 3)};
|
||||
val mem_reg_privileged = Reg(){Bool()};
|
||||
|
||||
when (reset.toBool || io.dpath.killx) {
|
||||
mem_reg_div_mul_val <== Bool(false);
|
||||
mem_reg_eret <== Bool(false);
|
||||
mem_reg_mem_val <== Bool(false);
|
||||
mem_reg_mem_cmd <== UFix(0, 4);
|
||||
mem_reg_mem_type <== UFix(0, 3);
|
||||
mem_reg_privileged <== Bool(false);
|
||||
}
|
||||
otherwise {
|
||||
mem_reg_div_mul_val <== ex_reg_div_mul_val;
|
||||
mem_reg_eret <== ex_reg_eret;
|
||||
mem_reg_mem_val <== ex_reg_mem_val;
|
||||
mem_reg_mem_cmd <== ex_reg_mem_cmd;
|
||||
mem_reg_mem_type <== ex_reg_mem_type;
|
||||
mem_reg_privileged <== ex_reg_privileged;
|
||||
}
|
||||
|
||||
when (reset.toBool || io.dpath.killm) {
|
||||
@ -327,8 +328,10 @@ class rocketCtrl extends Component
|
||||
// replay PC+4 on a D$ load miss
|
||||
val mem_cmd_load = mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD);
|
||||
val replay_mem_pc_plus4 = mem_cmd_load && !io.dmem.resp_val;
|
||||
val replay_mem = replay_mem_pc | replay_mem_pc_plus4;
|
||||
|
||||
val kill_ex = replay_mem_pc | replay_mem_pc_plus4 | mem_reg_privileged | io.dpath.exception;
|
||||
val kill_mem = io.dpath.exception;
|
||||
|
||||
dcache_miss <== replay_mem_pc_plus4;
|
||||
|
||||
io.dpath.mem_load := mem_cmd_load;
|
||||
@ -336,10 +339,11 @@ class rocketCtrl extends Component
|
||||
|
||||
io.dpath.sel_pc :=
|
||||
Mux(replay_mem_pc, PC_MEM,
|
||||
Mux(replay_mem_pc_plus4, PC_MEM4,
|
||||
Mux(io.dpath.exception || ex_reg_eret, PC_PCR,
|
||||
Mux(replay_mem_pc_plus4 || mem_reg_privileged, PC_MEM4,
|
||||
Mux(io.dpath.exception || mem_reg_eret, PC_PCR,
|
||||
Mux(!ex_reg_btb_hit && br_taken, PC_BR,
|
||||
Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4,
|
||||
Mux(ex_reg_btb_hit && !br_taken, PC_EX4,
|
||||
// Mux(ex_reg_btb_hit && !br_taken || ex_reg_privileged, PC_EX4,
|
||||
Mux(jr_taken, PC_JR,
|
||||
Mux(j_taken, PC_J,
|
||||
Mux(io.dpath.btb_hit, PC_BTB,
|
||||
@ -353,8 +357,8 @@ class rocketCtrl extends Component
|
||||
jr_taken |
|
||||
j_taken |
|
||||
io.dpath.exception |
|
||||
ex_reg_privileged |
|
||||
ex_reg_eret |
|
||||
mem_reg_privileged |
|
||||
mem_reg_eret |
|
||||
replay_mem_pc |
|
||||
replay_mem_pc_plus4;
|
||||
|
||||
@ -369,15 +373,10 @@ class rocketCtrl extends Component
|
||||
// check for loads in execute and mem stages to detect load/use hazards
|
||||
val ex_mem_cmd_load = ex_reg_mem_val && (ex_reg_mem_cmd === M_XRD);
|
||||
|
||||
val lu_stall_raddr1_ex =
|
||||
val lu_stall_ex =
|
||||
ex_mem_cmd_load &&
|
||||
id_ren1.toBool &&
|
||||
(id_raddr1 === io.dpath.ex_waddr);
|
||||
|
||||
val lu_stall_raddr2_ex =
|
||||
ex_mem_cmd_load &&
|
||||
id_ren2.toBool &&
|
||||
(id_raddr2 === io.dpath.ex_waddr);
|
||||
((id_ren1.toBool && (id_raddr1 === io.dpath.ex_waddr)) ||
|
||||
(id_ren2.toBool && (id_raddr2 === io.dpath.ex_waddr)));
|
||||
|
||||
val mem_mem_cmd_load_bh =
|
||||
mem_reg_mem_val &&
|
||||
@ -387,15 +386,12 @@ class rocketCtrl extends Component
|
||||
(mem_reg_mem_type === MT_H) ||
|
||||
(mem_reg_mem_type === MT_HU));
|
||||
|
||||
val lu_stall_raddr1_mem =
|
||||
val lu_stall_mem =
|
||||
mem_mem_cmd_load_bh &&
|
||||
id_ren1.toBool &&
|
||||
(id_raddr1 === io.dpath.mem_waddr);
|
||||
((id_ren1.toBool && (id_raddr1 === io.dpath.mem_waddr)) ||
|
||||
(id_ren2.toBool && (id_raddr2 === io.dpath.mem_waddr)));
|
||||
|
||||
val lu_stall_raddr2_mem =
|
||||
mem_mem_cmd_load_bh &&
|
||||
id_ren2.toBool &&
|
||||
(id_raddr2 === io.dpath.mem_waddr);
|
||||
val lu_stall = lu_stall_ex || lu_stall_mem;
|
||||
|
||||
// check for divide and multiply instructions in ex,mem,wb stages
|
||||
val dm_stall_ex =
|
||||
@ -419,19 +415,13 @@ class rocketCtrl extends Component
|
||||
~take_pc &
|
||||
(
|
||||
dm_stall |
|
||||
lu_stall_raddr1_ex |
|
||||
lu_stall_raddr2_ex |
|
||||
lu_stall_raddr1_mem |
|
||||
lu_stall_raddr2_mem |
|
||||
lu_stall |
|
||||
id_ren2 & id_stall_raddr2 |
|
||||
id_ren1 & id_stall_raddr1 |
|
||||
(id_sel_wa === WA_RD) && id_stall_waddr |
|
||||
(id_sel_wa === WA_RD) & id_stall_waddr |
|
||||
(id_sel_wa === WA_RA) & id_stall_ra |
|
||||
id_mem_val & ~io.dmem.req_rdy |
|
||||
id_sync & ~io.dmem.req_rdy |
|
||||
// id_mem_val_masked & id_full_mrq |
|
||||
// id_sync & (~id_empty_mrq | io.mem.dc_busy) |
|
||||
// mem_xstore_val & ~io.mem.xsdq_rdy |
|
||||
id_console_out_val & ~io.console.rdy |
|
||||
id_div_val & ~io.dpath.div_rdy |
|
||||
io.dpath.div_result_val |
|
||||
@ -448,8 +438,8 @@ class rocketCtrl extends Component
|
||||
|
||||
io.dpath.killf := take_pc | ~io.imem.resp_val;
|
||||
io.dpath.killd := ctrl_killd.toBool;
|
||||
io.dpath.killx := replay_mem.toBool;
|
||||
io.dpath.killm := replay_mem.toBool;
|
||||
io.dpath.killx := kill_ex.toBool;
|
||||
io.dpath.killm := kill_mem.toBool;
|
||||
|
||||
io.dpath.ren2 := id_ren2.toBool;
|
||||
io.dpath.ren1 := id_ren1.toBool;
|
||||
|
@ -76,23 +76,28 @@ class rocketDpath extends Component
|
||||
val ex_wdata = Wire() { Bits() };
|
||||
|
||||
// memory definitions
|
||||
val mem_reg_pc = Reg(resetVal = UFix(0,32));
|
||||
val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
|
||||
val mem_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
|
||||
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
||||
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||
val mem_reg_pc = Reg(resetVal = UFix(0,32));
|
||||
val mem_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
|
||||
val mem_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||
val mem_reg_wdata = Reg(resetVal = Bits(0,64));
|
||||
val mem_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
||||
val mem_reg_pcr = Reg(resetVal = Bits(0,64));
|
||||
val mem_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
|
||||
val mem_reg_ctrl_eret = Reg(resetVal = Bool(false));
|
||||
val mem_reg_ctrl_exception = Reg(resetVal = Bool(false));
|
||||
val mem_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||
val mem_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
||||
val mem_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
||||
val mem_reg_ctrl_exception = Reg(resetVal = Bool(false));
|
||||
|
||||
// writeback definitions
|
||||
val wb_reg_pc = Reg(resetVal = UFix(0,32));
|
||||
val wb_reg_pc_plus4 = Reg(resetVal = UFix(0,32));
|
||||
val wb_reg_waddr = Reg(resetVal = UFix(0,5));
|
||||
val wb_reg_wdata = Reg(resetVal = Bits(0,64));
|
||||
val wb_reg_ctrl_ll_wb = Reg(resetVal = Bool(false));
|
||||
val wb_reg_raddr2 = Reg(resetVal = UFix(0,5));
|
||||
val wb_reg_ctrl_cause = Reg(resetVal = UFix(0,5));
|
||||
val wb_reg_ctrl_eret = Reg(resetVal = Bool(false));
|
||||
val wb_reg_ctrl_exception = Reg(resetVal = Bool(false));
|
||||
val wb_reg_ctrl_wen = Reg(resetVal = Bool(false));
|
||||
val wb_reg_ctrl_wen_pcr = Reg(resetVal = Bool(false));
|
||||
|
||||
@ -125,7 +130,7 @@ class rocketDpath extends Component
|
||||
Mux(io.ctrl.sel_pc === PC_BR, ex_branch_target,
|
||||
Mux(io.ctrl.sel_pc === PC_J, ex_branch_target,
|
||||
Mux(io.ctrl.sel_pc === PC_JR, ex_jr_target.toUFix,
|
||||
Mux(io.ctrl.sel_pc === PC_PCR, ex_pcr(31,0).toUFix,
|
||||
Mux(io.ctrl.sel_pc === PC_PCR, mem_reg_pcr(31,0).toUFix,
|
||||
Mux(io.ctrl.sel_pc === PC_MEM, mem_reg_pc,
|
||||
Mux(io.ctrl.sel_pc === PC_MEM4, mem_reg_pc_plus4,
|
||||
UFix(0, 32))))))))));
|
||||
@ -336,10 +341,10 @@ class rocketDpath extends Component
|
||||
pcr.io.host.from ^^ io.host.from;
|
||||
pcr.io.host.to ^^ io.host.to;
|
||||
|
||||
pcr.io.eret := ex_reg_ctrl_eret;
|
||||
pcr.io.exception := ex_reg_ctrl_exception;
|
||||
pcr.io.cause := ex_reg_ctrl_cause;
|
||||
pcr.io.pc := ex_reg_pc;
|
||||
// pcr.io.eret := ex_reg_ctrl_eret;
|
||||
// pcr.io.exception := ex_reg_ctrl_exception;
|
||||
// pcr.io.cause := ex_reg_ctrl_cause;
|
||||
// pcr.io.pc := ex_reg_pc;
|
||||
|
||||
io.ctrl.status := pcr.io.status;
|
||||
io.debug.error_mode := pcr.io.debug.error_mode;
|
||||
@ -363,17 +368,21 @@ class rocketDpath extends Component
|
||||
// memory stage
|
||||
mem_reg_pc <== ex_reg_pc;
|
||||
mem_reg_pc_plus4 <== ex_reg_pc_plus4;
|
||||
mem_reg_pcr <== ex_pcr;
|
||||
mem_reg_waddr <== ex_reg_waddr;
|
||||
mem_reg_wdata <== ex_wdata;
|
||||
mem_reg_ctrl_ll_wb <== ex_reg_ctrl_ll_wb;
|
||||
mem_reg_raddr2 <== ex_reg_raddr2;
|
||||
mem_reg_ctrl_cause <== ex_reg_ctrl_cause;
|
||||
|
||||
when (io.ctrl.killx) {
|
||||
mem_reg_ctrl_eret <== Bool(false);
|
||||
mem_reg_ctrl_wen <== Bool(false);
|
||||
mem_reg_ctrl_wen_pcr <== Bool(false);
|
||||
mem_reg_ctrl_exception <== Bool(false);
|
||||
}
|
||||
otherwise {
|
||||
mem_reg_ctrl_eret <== ex_reg_ctrl_eret;
|
||||
mem_reg_ctrl_wen <== ex_reg_ctrl_wen;
|
||||
mem_reg_ctrl_wen_pcr <== ex_reg_ctrl_wen_pcr;
|
||||
mem_reg_ctrl_exception <== ex_reg_ctrl_exception;
|
||||
@ -384,14 +393,7 @@ class rocketDpath extends Component
|
||||
// for load/use hazard detection (load byte/halfword)
|
||||
io.ctrl.mem_waddr := mem_reg_waddr;
|
||||
|
||||
// moved to earlier in file
|
||||
// val mem_dmem_resp_data_w =
|
||||
// Mux(io.dmem.resp_pos(2).toBool, io.dmem.resp_data(63, 32), io.dmem.resp_data(31, 0));
|
||||
//
|
||||
// val mem_dmem_resp_data =
|
||||
// Mux(io.dmem.resp_type === MT_D, io.dmem.resp_data,
|
||||
// Mux(io.dmem.resp_type === MT_W, Cat(Fill(32, mem_dmem_resp_data_w(31)), mem_dmem_resp_data_w)),
|
||||
// Cat(UFix(0,32), mem_dmem_resp_data_w));
|
||||
// 32/64 bit load handling (moved to earlier in file)
|
||||
|
||||
// writeback stage
|
||||
r_dmem_resp_val <== io.dmem.resp_val;
|
||||
@ -400,12 +402,14 @@ class rocketDpath extends Component
|
||||
r_dmem_resp_type <== dmem_resp_type;
|
||||
r_dmem_resp_data <== mem_dmem_resp_data;
|
||||
|
||||
wb_reg_pc <== mem_reg_pc;
|
||||
wb_reg_pc_plus4 <== mem_reg_pc_plus4;
|
||||
wb_reg_waddr <== mem_reg_waddr;
|
||||
wb_reg_wdata <== mem_reg_wdata;
|
||||
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
|
||||
wb_reg_raddr2 <== mem_reg_raddr2;
|
||||
wb_reg_pc <== mem_reg_pc;
|
||||
wb_reg_waddr <== mem_reg_waddr;
|
||||
wb_reg_wdata <== mem_reg_wdata;
|
||||
wb_reg_ctrl_ll_wb <== mem_reg_ctrl_ll_wb;
|
||||
wb_reg_raddr2 <== mem_reg_raddr2;
|
||||
wb_reg_ctrl_cause <== mem_reg_ctrl_cause;
|
||||
wb_reg_ctrl_eret <== mem_reg_ctrl_eret;
|
||||
wb_reg_ctrl_exception <== mem_reg_ctrl_exception;
|
||||
|
||||
when (io.ctrl.killm) {
|
||||
wb_reg_ctrl_wen <== Bool(false);
|
||||
@ -416,21 +420,7 @@ class rocketDpath extends Component
|
||||
wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr;
|
||||
}
|
||||
|
||||
// crossbar/sign extension for 8/16 bit loads
|
||||
// val dmem_resp_data_h =
|
||||
// Mux(r_dmem_resp_pos(1).toBool, r_dmem_resp_data(31, 16), r_dmem_resp_data(15, 0));
|
||||
// val dmem_resp_data_b =
|
||||
// Mux(r_dmem_resp_pos(0).toBool, dmem_resp_data_h(15, 8), dmem_resp_data_h(7, 0));
|
||||
//
|
||||
// val dmem_resp_data_final =
|
||||
// Mux(r_dmem_resp_type === MT_B, Cat(Fill(56, dmem_resp_data_b(7)), dmem_resp_data_b),
|
||||
// Mux(r_dmem_resp_type === MT_BU, Cat(UFix(0, 56), dmem_resp_data_b),
|
||||
// Mux(r_dmem_resp_type === MT_H, Cat(Fill(48, dmem_resp_data_h(15)), dmem_resp_data_h),
|
||||
// Mux(r_dmem_resp_type === MT_HU, Cat(UFix(0, 48), dmem_resp_data_h),
|
||||
// Mux((r_dmem_resp_type === MT_W) ||
|
||||
// (r_dmem_resp_type === MT_WU) ||
|
||||
// (r_dmem_resp_type === MT_D), r_dmem_resp_data,
|
||||
// UFix(0,64))))));
|
||||
// crossbar/sign extension for 8/16 bit loads (moved to earlier in file)
|
||||
|
||||
// regfile write
|
||||
rfile.io.w0.addr := wb_reg_waddr;
|
||||
@ -454,6 +444,11 @@ class rocketDpath extends Component
|
||||
pcr.io.w.en := wb_reg_ctrl_wen_pcr;
|
||||
pcr.io.w.data := wb_reg_wdata;
|
||||
|
||||
pcr.io.eret := wb_reg_ctrl_eret;
|
||||
pcr.io.exception := wb_reg_ctrl_exception;
|
||||
pcr.io.cause := wb_reg_ctrl_cause;
|
||||
pcr.io.pc := wb_reg_pc;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user