dcache loads working - 1/2 cycle load/use delay depending on load type
This commit is contained in:
parent
2b67eee683
commit
3b3d988fde
@ -51,6 +51,7 @@ class ioCtrlDpath extends Bundle()
|
||||
val div_result_val = Bool('input);
|
||||
val mul_result_val = Bool('input);
|
||||
val ex_waddr = UFix(5,'input); // write addr from execute stage
|
||||
val mem_waddr = UFix(5,'input); // write addr from memory stage
|
||||
val exception = Bool('input);
|
||||
val status = Bits(8, 'input);
|
||||
val sboard_set = Bool('input);
|
||||
@ -337,23 +338,44 @@ class rocketCtrl extends Component
|
||||
);
|
||||
|
||||
// check for loads in execute stage to detect load/use hazards
|
||||
val lu_stall_raddr1 =
|
||||
ex_reg_mem_val &&
|
||||
(ex_reg_mem_cmd === M_XRD) &&
|
||||
|
||||
val ex_mem_cmd_load = ex_reg_mem_val && (ex_reg_mem_cmd === M_XRD);
|
||||
|
||||
val lu_stall_raddr1_ex =
|
||||
ex_mem_cmd_load &&
|
||||
id_ren1.toBool &&
|
||||
(id_raddr1 === io.dpath.ex_waddr);
|
||||
|
||||
val lu_stall_raddr2 =
|
||||
ex_reg_mem_val &&
|
||||
(ex_reg_mem_cmd === M_XRD) &&
|
||||
val lu_stall_raddr2_ex =
|
||||
ex_mem_cmd_load &&
|
||||
id_ren2.toBool &&
|
||||
(id_raddr2 === io.dpath.ex_waddr);
|
||||
|
||||
val mem_mem_cmd_load_bh =
|
||||
mem_reg_mem_val &&
|
||||
(mem_reg_mem_cmd === M_XRD) &&
|
||||
((mem_reg_mem_type === MT_B) ||
|
||||
(mem_reg_mem_type === MT_BU) ||
|
||||
(mem_reg_mem_type === MT_H) ||
|
||||
(mem_reg_mem_type === MT_HU));
|
||||
|
||||
val lu_stall_raddr1_mem =
|
||||
mem_mem_cmd_load_bh &&
|
||||
id_ren1.toBool &&
|
||||
(id_raddr1 === io.dpath.mem_waddr);
|
||||
|
||||
val lu_stall_raddr2_mem =
|
||||
mem_mem_cmd_load_bh &&
|
||||
id_ren2.toBool &&
|
||||
(id_raddr2 === io.dpath.mem_waddr);
|
||||
|
||||
val ctrl_stalld =
|
||||
~take_pc &
|
||||
(
|
||||
lu_stall_raddr1 |
|
||||
lu_stall_raddr2 |
|
||||
lu_stall_raddr1_ex |
|
||||
lu_stall_raddr2_ex |
|
||||
lu_stall_raddr1_mem |
|
||||
lu_stall_raddr2_mem |
|
||||
id_ren2 & id_stall_raddr2 |
|
||||
id_ren1 & id_stall_raddr1 |
|
||||
(id_sel_wa === WA_RD) && id_stall_waddr |
|
||||
|
@ -306,7 +306,8 @@ class rocketDCacheDM_1C(lines: Int, addrbits: Int) extends Component {
|
||||
}
|
||||
|
||||
// tag array
|
||||
val tag_we = (state === s_resolve_miss);
|
||||
// val tag_we = (state === s_resolve_miss);
|
||||
val tag_we = (state === s_refill) && io.mem.req_rdy && (rr_count === UFix(3,2));
|
||||
val tag_waddr = r_cpu_req_addr(indexmsb, indexlsb).toUFix;
|
||||
val tag_wdata = r_cpu_req_addr(tagmsb, taglsb);
|
||||
val tag_array = Mem(lines, tag_we, tag_waddr, tag_wdata);
|
||||
|
@ -103,7 +103,7 @@ class rocketDpath extends Component
|
||||
val r_dmem_resp_val = Reg(resetVal = Bool(false));
|
||||
val r_dmem_resp_waddr = Reg(resetVal = UFix(0,5));
|
||||
val r_dmem_resp_pos = Reg(resetVal = UFix(0,3));
|
||||
val r_dmem_resp_type = Reg(resetVal = UFix(0,3));
|
||||
val r_dmem_resp_type = Reg(resetVal = Bits(0,3));
|
||||
val r_dmem_resp_data = Reg(resetVal = Bits(0,64));
|
||||
|
||||
// instruction fetch stage
|
||||
@ -181,22 +181,52 @@ class rocketDpath extends Component
|
||||
Mux(io.ctrl.sel_wa === WA_RA, RA,
|
||||
UFix(0, 5)))));
|
||||
|
||||
// moved this here to avoid having to do forward declaration
|
||||
// TODO: cleanup
|
||||
|
||||
val dmem_resp_pos = io.dmem.resp_tag(7,5).toUFix;
|
||||
val dmem_resp_type = io.dmem.resp_tag(10,8);
|
||||
|
||||
val mem_dmem_resp_data_w =
|
||||
Mux(dmem_resp_pos(2).toBool, io.dmem.resp_data(63, 32), io.dmem.resp_data(31, 0));
|
||||
|
||||
val mem_dmem_resp_data =
|
||||
Mux(dmem_resp_type === MT_D, io.dmem.resp_data,
|
||||
Mux(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)));
|
||||
|
||||
// crossbar/sign extension for 8/16 bit loads (in writeback stage)
|
||||
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))))));
|
||||
|
||||
// bypass muxes
|
||||
val id_rs1 =
|
||||
Mux(io.ctrl.div_wb, div_result,
|
||||
Mux(io.ctrl.mul_wb, mul_result,
|
||||
Mux(id_raddr1 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr1 === ex_reg_waddr, ex_wdata,
|
||||
Mux(id_raddr1 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr1 === mem_reg_waddr, mem_reg_wdata,
|
||||
Mux(id_raddr1 != UFix(0, 5) && io.ctrl.mem_load && id_raddr1 === mem_reg_waddr, io.dmem.resp_data,
|
||||
Mux(id_raddr1 != UFix(0, 5) && r_dmem_resp_val && id_raddr1 === r_dmem_resp_waddr, r_dmem_resp_data,
|
||||
Mux(id_raddr1 != UFix(0, 5) && io.ctrl.mem_load && id_raddr1 === mem_reg_waddr, mem_dmem_resp_data,
|
||||
Mux(id_raddr1 != UFix(0, 5) && r_dmem_resp_val && id_raddr1 === r_dmem_resp_waddr, dmem_resp_data_final,
|
||||
Mux(id_raddr1 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr1 === wb_reg_waddr, wb_reg_wdata,
|
||||
id_rdata1)))))));
|
||||
|
||||
val id_rs2 =
|
||||
Mux(id_raddr2 != UFix(0, 5) && ex_reg_ctrl_wen && id_raddr2 === ex_reg_waddr, ex_wdata,
|
||||
Mux(id_raddr2 != UFix(0, 5) && mem_reg_ctrl_wen && id_raddr2 === mem_reg_waddr, mem_reg_wdata,
|
||||
Mux(id_raddr2 != UFix(0, 5) && io.ctrl.mem_load && id_raddr2 === mem_reg_waddr, io.dmem.resp_data,
|
||||
Mux(id_raddr2 != UFix(0, 5) && r_dmem_resp_val && id_raddr2 === r_dmem_resp_waddr, r_dmem_resp_data,
|
||||
Mux(id_raddr2 != UFix(0, 5) && io.ctrl.mem_load && id_raddr2 === mem_reg_waddr, mem_dmem_resp_data,
|
||||
Mux(id_raddr2 != UFix(0, 5) && r_dmem_resp_val && id_raddr2 === r_dmem_resp_waddr, dmem_resp_data_final,
|
||||
Mux(id_raddr2 != UFix(0, 5) && wb_reg_ctrl_wen && id_raddr2 === wb_reg_waddr, wb_reg_wdata,
|
||||
id_rdata2)))));
|
||||
|
||||
@ -210,8 +240,6 @@ class rocketDpath extends Component
|
||||
UFix(0,5)))));
|
||||
|
||||
io.ctrl.inst := id_reg_inst;
|
||||
// io.ctrl.rs1 := id_rs1;
|
||||
// io.ctrl.rs2 := id_rs2;
|
||||
|
||||
// execute stage
|
||||
ex_reg_pc <== id_reg_pc;
|
||||
@ -359,13 +387,24 @@ class rocketDpath extends Component
|
||||
|
||||
// exception signal to control (for NPC select)
|
||||
io.ctrl.exception := mem_reg_ctrl_exception;
|
||||
|
||||
// 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));
|
||||
|
||||
// writeback stage
|
||||
r_dmem_resp_val <== io.dmem.resp_val;
|
||||
r_dmem_resp_waddr <== io.dmem.resp_tag(4,0).toUFix;
|
||||
r_dmem_resp_pos <== io.dmem.resp_tag(7,5).toUFix;
|
||||
r_dmem_resp_type <== io.dmem.resp_tag(10,8).toUFix;
|
||||
r_dmem_resp_data <== io.dmem.resp_data;
|
||||
r_dmem_resp_pos <== dmem_resp_pos;
|
||||
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;
|
||||
@ -387,23 +426,21 @@ class rocketDpath extends Component
|
||||
wb_reg_ctrl_wen_pcr <== mem_reg_ctrl_wen_pcr;
|
||||
}
|
||||
|
||||
// crossbar/sign extension for 8/16/32 bit loads
|
||||
val dmem_resp_data_w =
|
||||
Mux(r_dmem_resp_pos(2).toBool, r_dmem_resp_data(63, 32), r_dmem_resp_data(31, 0));
|
||||
val dmem_resp_data_h =
|
||||
Mux(r_dmem_resp_pos(1).toBool, dmem_resp_data_w(31, 16), dmem_resp_data_w(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, Cat(Fill(32, dmem_resp_data_w(31)), dmem_resp_data_w),
|
||||
Mux(r_dmem_resp_type === MT_WU, Cat(UFix(0, 32), dmem_resp_data_w),
|
||||
Mux(r_dmem_resp_type === MT_D, r_dmem_resp_data,
|
||||
UFix(0, 64))))))));
|
||||
// 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))))));
|
||||
|
||||
// regfile write
|
||||
rfile.io.w0.addr := wb_reg_waddr;
|
||||
|
Loading…
Reference in New Issue
Block a user