1
0

fix WAW hazard handling

This commit is contained in:
Andrew Waterman 2012-01-02 00:25:11 -08:00
parent eb657dd250
commit ffe23a1ee8
6 changed files with 37 additions and 51 deletions

View File

@ -103,6 +103,7 @@ class rocketProc extends Component
ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss; ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss;
ctrl.io.dmem.resp_nack := arb.io.cpu.resp_nack; ctrl.io.dmem.resp_nack := arb.io.cpu.resp_nack;
dpath.io.dmem.resp_val := arb.io.cpu.resp_val; dpath.io.dmem.resp_val := arb.io.cpu.resp_val;
dpath.io.dmem.resp_replay := io.dmem.resp_replay;
dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag; dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
dpath.io.dmem.resp_data := arb.io.cpu.resp_data; dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
dpath.io.dmem.resp_data_subword := io.dmem.resp_data_subword; dpath.io.dmem.resp_data_subword := io.dmem.resp_data_subword;

View File

@ -302,10 +302,7 @@ class rocketCtrl extends Component
val id_raddr2 = io.dpath.inst(21,17); val id_raddr2 = io.dpath.inst(21,17);
val id_raddr1 = io.dpath.inst(26,22); val id_raddr1 = io.dpath.inst(26,22);
val id_waddr = io.dpath.inst(31,27); val id_waddr = Mux(id_sel_wa === WA_RA, RA, io.dpath.inst(31,27));
val id_ren2 = id_renx2.toBool;
val id_ren1 = id_renx1.toBool;
val id_console_out_val = id_wen_pcr.toBool && (id_raddr2 === PCR_CONSOLE); val id_console_out_val = id_wen_pcr.toBool && (id_raddr2 === PCR_CONSOLE);
@ -329,7 +326,6 @@ class rocketCtrl extends Component
val id_stall_raddr2 = sboard.io.stalla; val id_stall_raddr2 = sboard.io.stalla;
val id_stall_raddr1 = sboard.io.stallb; val id_stall_raddr1 = sboard.io.stallb;
val id_stall_waddr = sboard.io.stallc; val id_stall_waddr = sboard.io.stallc;
val id_stall_ra = sboard.io.stallra;
val id_reg_btb_hit = Reg(resetVal = Bool(false)); val id_reg_btb_hit = Reg(resetVal = Bool(false));
val id_reg_xcpt_itlb = Reg(resetVal = Bool(false)); val id_reg_xcpt_itlb = Reg(resetVal = Bool(false));
@ -581,62 +577,50 @@ class rocketCtrl extends Component
io.dpath.stalld io.dpath.stalld
); );
// check for loads and amos in execute and mem stages to detect load/use hazards // stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage.
val ex_mem_cmd_load = val ex_mem_cmd_load =
ex_reg_mem_val && ((ex_reg_mem_cmd === M_XRD) || ex_reg_mem_cmd(3).toBool); ex_reg_mem_val && ((ex_reg_mem_cmd === M_XRD) || ex_reg_mem_cmd(3).toBool);
val data_hazard_ex =
(ex_mem_cmd_load || ex_reg_div_mul_val) &&
((id_renx1.toBool && (id_raddr1 === io.dpath.ex_waddr)) ||
(id_renx2.toBool && (id_raddr2 === io.dpath.ex_waddr)) ||
(id_wen.toBool && (id_waddr === io.dpath.ex_waddr)));
val lu_stall_ex = // stall for RAW/WAW hazards on LB/LH and mul/div in memory stage.
ex_mem_cmd_load && // stall for WAW-but-not-RAW hazards on LW/LD/AMO.
((id_ren1 && (id_raddr1 === io.dpath.ex_waddr)) || val mem_mem_cmd_load =
(id_ren2 && (id_raddr2 === io.dpath.ex_waddr))); mem_reg_mem_val && ((mem_reg_mem_cmd === M_XRD) || mem_reg_mem_cmd(3).toBool);
val mem_mem_cmd_load_bh = val mem_mem_cmd_load_bh =
mem_reg_mem_val && mem_mem_cmd_load &&
(mem_reg_mem_cmd === M_XRD) &&
((mem_reg_mem_type === MT_B) || ((mem_reg_mem_type === MT_B) ||
(mem_reg_mem_type === MT_BU) || (mem_reg_mem_type === MT_BU) ||
(mem_reg_mem_type === MT_H) || (mem_reg_mem_type === MT_H) ||
(mem_reg_mem_type === MT_HU)); (mem_reg_mem_type === MT_HU));
val raw_hazard_mem =
(id_renx1.toBool && (id_raddr1 === io.dpath.mem_waddr)) ||
(id_renx2.toBool && (id_raddr2 === io.dpath.mem_waddr));
val waw_hazard_mem =
(id_wen.toBool && (id_waddr === io.dpath.mem_waddr));
val data_hazard_mem =
(mem_mem_cmd_load_bh || mem_reg_div_mul_val) && (raw_hazard_mem || waw_hazard_mem) ||
mem_mem_cmd_load && (!raw_hazard_mem && waw_hazard_mem)
val lu_stall_mem = // stall for RAW/WAW hazards on load/AMO misses and mul/div in writeback.
mem_mem_cmd_load_bh && val data_hazard_wb =
((id_ren1 && (id_raddr1 === io.dpath.mem_waddr)) || (dcache_miss || wb_reg_div_mul_val) &&
(id_ren2 && (id_raddr2 === io.dpath.mem_waddr))); ((id_renx1.toBool && (id_raddr1 === io.dpath.wb_waddr)) ||
(id_renx2.toBool && (id_raddr2 === io.dpath.wb_waddr)) ||
(id_wen.toBool && (id_waddr === io.dpath.wb_waddr)));
val lu_stall_wb = val data_hazard = data_hazard_ex || data_hazard_mem || data_hazard_wb;
dcache_miss &&
((id_ren1 && (id_raddr1 === io.dpath.wb_waddr)) ||
(id_ren2 && (id_raddr2 === io.dpath.wb_waddr)));
val lu_stall = lu_stall_ex || lu_stall_mem || lu_stall_wb;
// check for divide and multiply instructions in ex,mem,wb stages
val dm_stall_ex =
ex_reg_div_mul_val &&
((id_ren1 && (id_raddr1 === io.dpath.ex_waddr)) ||
(id_ren2 && (id_raddr2 === io.dpath.ex_waddr)));
val dm_stall_mem =
mem_reg_div_mul_val &&
((id_ren1 && (id_raddr1 === io.dpath.mem_waddr)) ||
(id_ren2 && (id_raddr2 === io.dpath.mem_waddr)));
val dm_stall_wb =
wb_reg_div_mul_val &&
((id_ren1 && (id_raddr1 === io.dpath.wb_waddr)) ||
(id_ren2 && (id_raddr2 === io.dpath.wb_waddr)));
val dm_stall = dm_stall_ex || dm_stall_mem || dm_stall_wb;
val ctrl_stalld = val ctrl_stalld =
!take_pc && !take_pc &&
( (
dm_stall || data_hazard ||
lu_stall || id_renx2.toBool && id_stall_raddr2 ||
id_ren2 && id_stall_raddr2 || id_renx1.toBool && id_stall_raddr1 ||
id_ren1 && id_stall_raddr1 || id_wen.toBool && id_stall_waddr ||
(id_sel_wa === WA_RD) && id_stall_waddr ||
(id_sel_wa === WA_RA) && id_stall_ra ||
id_mem_val.toBool && !(io.dmem.req_rdy && io.dtlb_rdy) || id_mem_val.toBool && !(io.dmem.req_rdy && io.dtlb_rdy) ||
((id_sync === SYNC_D) || (id_sync === SYNC_I)) && !io.dmem.req_rdy || ((id_sync === SYNC_D) || (id_sync === SYNC_I)) && !io.dmem.req_rdy ||
id_console_out_val && !io.console.rdy || id_console_out_val && !io.console.rdy ||
@ -662,8 +646,8 @@ class rocketCtrl extends Component
io.dpath.killm := kill_mem; io.dpath.killm := kill_mem;
io.dpath.mem_load := mem_reg_mem_val && ((mem_reg_mem_cmd === M_XRD) || mem_reg_mem_cmd(3).toBool); io.dpath.mem_load := mem_reg_mem_val && ((mem_reg_mem_cmd === M_XRD) || mem_reg_mem_cmd(3).toBool);
io.dpath.ren2 := id_ren2; io.dpath.ren2 := id_renx2.toBool;
io.dpath.ren1 := id_ren1; io.dpath.ren1 := id_renx1.toBool;
io.dpath.sel_alu2 := id_sel_alu2; io.dpath.sel_alu2 := id_sel_alu2;
io.dpath.sel_alu1 := id_sel_alu1.toBool; io.dpath.sel_alu1 := id_sel_alu1.toBool;
io.dpath.fn_dw := id_fn_dw.toBool; io.dpath.fn_dw := id_fn_dw.toBool;

View File

@ -18,7 +18,6 @@ class ioCtrlSboard extends Bundle()
val stalla = Bool('output); val stalla = Bool('output);
val stallb = Bool('output); val stallb = Bool('output);
val stallc = Bool('output); val stallc = Bool('output);
val stallra = Bool('output);
} }
class rocketCtrlSboard extends Component class rocketCtrlSboard extends Component
@ -34,7 +33,6 @@ class rocketCtrlSboard extends Component
io.stalla := reg_busy(io.raddra).toBool; io.stalla := reg_busy(io.raddra).toBool;
io.stallb := reg_busy(io.raddrb).toBool; io.stallb := reg_busy(io.raddrb).toBool;
io.stallc := reg_busy(io.raddrc).toBool; io.stallc := reg_busy(io.raddrc).toBool;
io.stallra := reg_busy(RA).toBool;
} }
class ioCtrlCnt extends Bundle() class ioCtrlCnt extends Bundle()

View File

@ -21,6 +21,7 @@ class ioDmem(view: List[String] = null) extends Bundle(view) {
val resp_miss = Bool('output); val resp_miss = Bool('output);
val resp_nack = Bool('output); val resp_nack = Bool('output);
val resp_val = Bool('output); val resp_val = Bool('output);
val resp_replay = Bool('output);
val resp_data = Bits(64, 'output); val resp_data = Bits(64, 'output);
val resp_data_subword = Bits(64, 'output); val resp_data_subword = Bits(64, 'output);
val resp_tag = Bits(DCACHE_TAG_BITS, 'output); val resp_tag = Bits(DCACHE_TAG_BITS, 'output);

View File

@ -11,6 +11,7 @@ class ioDpathDmem extends Bundle()
val req_tag = UFix(CPU_TAG_BITS, 'output); val req_tag = UFix(CPU_TAG_BITS, 'output);
val req_data = Bits(64, 'output); val req_data = Bits(64, 'output);
val resp_val = Bool('input); val resp_val = Bool('input);
val resp_replay = Bool('input);
val resp_tag = Bits(CPU_TAG_BITS, 'input); val resp_tag = Bits(CPU_TAG_BITS, 'input);
val resp_data = Bits(64, 'input); val resp_data = Bits(64, 'input);
val resp_data_subword = Bits(64, 'input); val resp_data_subword = Bits(64, 'input);

View File

@ -770,6 +770,7 @@ class HellaCache(lines: Int) extends Component {
io.cpu.req_rdy := flusher.io.req.ready && !(r_cpu_req_val_ && r_req_flush) && !pending_fence io.cpu.req_rdy := flusher.io.req.ready && !(r_cpu_req_val_ && r_req_flush) && !pending_fence
io.cpu.resp_nack := r_cpu_req_val_ && !io.cpu.req_kill && nack io.cpu.resp_nack := r_cpu_req_val_ && !io.cpu.req_kill && nack
io.cpu.resp_val := (tag_hit && !nack_hit && r_req_read) || replayer.io.cpu_resp_val io.cpu.resp_val := (tag_hit && !nack_hit && r_req_read) || replayer.io.cpu_resp_val
io.cpu.resp_replay := replayer.io.cpu_resp_val
io.cpu.resp_miss := tag_miss && !nack_miss && r_req_read io.cpu.resp_miss := tag_miss && !nack_miss && r_req_read
io.cpu.resp_tag := Mux(replayer.io.cpu_resp_val, replayer.io.cpu_resp_tag, r_cpu_req_tag) io.cpu.resp_tag := Mux(replayer.io.cpu_resp_val, replayer.io.cpu_resp_tag, r_cpu_req_tag)
io.cpu.resp_data := loadgen.io.dout io.cpu.resp_data := loadgen.io.dout