use replay to handle I$ misses
this eliminates a long path in the fetch stage
This commit is contained in:
parent
1a7bfd4350
commit
4807d7222b
@ -290,10 +290,10 @@ class rocketCtrl extends Component
|
|||||||
*/
|
*/
|
||||||
));
|
));
|
||||||
|
|
||||||
val if_reg_xcpt_ma_inst = Reg(io.dpath.xcpt_ma_inst);
|
val if_reg_xcpt_ma_inst = Reg(io.dpath.xcpt_ma_inst, resetVal = Bool(false));
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
io.imem.req_val := !io.dpath.xcpt_ma_inst;
|
io.imem.req_val := Bool(true)
|
||||||
|
|
||||||
val id_int_val :: id_br_type :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_sel_alu1 :: id_fn_dw :: id_fn_alu :: csremainder = cs;
|
val id_int_val :: id_br_type :: id_renx2 :: id_renx1 :: id_sel_alu2 :: id_sel_alu1 :: id_fn_dw :: id_fn_alu :: csremainder = cs;
|
||||||
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_div_fn :: id_wen :: id_sel_wa :: id_sel_wb :: id_ren_pcr :: id_wen_pcr :: id_irq :: id_sync :: id_eret :: id_syscall :: id_privileged :: Nil = csremainder;
|
val id_mem_val :: id_mem_cmd :: id_mem_type :: id_mul_val :: id_mul_fn :: id_div_val :: id_div_fn :: id_wen :: id_sel_wa :: id_sel_wb :: id_ren_pcr :: id_wen_pcr :: id_irq :: id_sync :: id_eret :: id_syscall :: id_privileged :: Nil = csremainder;
|
||||||
@ -326,6 +326,7 @@ class rocketCtrl extends Component
|
|||||||
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));
|
||||||
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 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()};
|
||||||
@ -344,6 +345,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 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));
|
||||||
@ -356,6 +358,7 @@ class rocketCtrl extends Component
|
|||||||
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_replay = Reg(resetVal = Bool(false));
|
val mem_reg_replay = Reg(resetVal = Bool(false));
|
||||||
val mem_reg_kill_dmem = Reg(resetVal = Bool(false));
|
val mem_reg_kill_dmem = Reg(resetVal = Bool(false));
|
||||||
|
val mem_reg_icmiss = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
val wb_reg_inst_di = Reg(resetVal = Bool(false));
|
val wb_reg_inst_di = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_inst_ei = Reg(resetVal = Bool(false));
|
val wb_reg_inst_ei = Reg(resetVal = Bool(false));
|
||||||
@ -364,6 +367,8 @@ class rocketCtrl extends Component
|
|||||||
val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false));
|
val wb_reg_badvaddr_wen = Reg(resetVal = Bool(false));
|
||||||
val wb_reg_cause = Reg(){UFix()};
|
val wb_reg_cause = Reg(){UFix()};
|
||||||
|
|
||||||
|
val take_pc = Wire() { Bool() };
|
||||||
|
|
||||||
when (!io.dpath.stalld) {
|
when (!io.dpath.stalld) {
|
||||||
when (io.dpath.killf) {
|
when (io.dpath.killf) {
|
||||||
id_reg_xcpt_ma_inst <== Bool(false);
|
id_reg_xcpt_ma_inst <== Bool(false);
|
||||||
@ -375,6 +380,7 @@ class rocketCtrl extends Component
|
|||||||
id_reg_xcpt_itlb <== io.xcpt_itlb;
|
id_reg_xcpt_itlb <== io.xcpt_itlb;
|
||||||
id_reg_btb_hit <== io.dpath.btb_hit;
|
id_reg_btb_hit <== io.dpath.btb_hit;
|
||||||
}
|
}
|
||||||
|
id_reg_icmiss <== !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)
|
||||||
@ -397,6 +403,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);
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
ex_reg_br_type <== id_br_type;
|
ex_reg_br_type <== id_br_type;
|
||||||
@ -415,6 +422,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_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;
|
||||||
@ -462,6 +470,7 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_xcpt_privileged <== Bool(false);
|
mem_reg_xcpt_privileged <== Bool(false);
|
||||||
mem_reg_xcpt_fpu <== Bool(false);
|
mem_reg_xcpt_fpu <== Bool(false);
|
||||||
mem_reg_xcpt_syscall <== Bool(false);
|
mem_reg_xcpt_syscall <== Bool(false);
|
||||||
|
mem_reg_icmiss <== Bool(false);
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
mem_reg_div_mul_val <== ex_reg_div_mul_val;
|
mem_reg_div_mul_val <== ex_reg_div_mul_val;
|
||||||
@ -477,6 +486,7 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
|
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
|
||||||
mem_reg_xcpt_fpu <== ex_reg_xcpt_fpu;
|
mem_reg_xcpt_fpu <== ex_reg_xcpt_fpu;
|
||||||
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
|
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
|
||||||
|
mem_reg_icmiss <== ex_reg_icmiss;
|
||||||
}
|
}
|
||||||
mem_reg_mem_cmd <== ex_reg_mem_cmd;
|
mem_reg_mem_cmd <== ex_reg_mem_cmd;
|
||||||
mem_reg_mem_type <== ex_reg_mem_type;
|
mem_reg_mem_type <== ex_reg_mem_type;
|
||||||
@ -550,7 +560,7 @@ class rocketCtrl extends Component
|
|||||||
io.dpath.badvaddr_wen := wb_reg_badvaddr_wen;
|
io.dpath.badvaddr_wen := wb_reg_badvaddr_wen;
|
||||||
|
|
||||||
// replay mem stage PC on a DTLB miss
|
// replay mem stage PC on a DTLB miss
|
||||||
val mem_hazard = io.dtlb_miss || io.dmem.resp_nack;
|
val mem_hazard = io.dtlb_miss || io.dmem.resp_nack || mem_reg_icmiss;
|
||||||
val mem_kill_dmem = io.dtlb_miss || mem_exception || mem_reg_kill_dmem;
|
val mem_kill_dmem = io.dtlb_miss || mem_exception || mem_reg_kill_dmem;
|
||||||
val replay_mem = mem_hazard || mem_reg_replay;
|
val replay_mem = mem_hazard || mem_reg_replay;
|
||||||
val kill_mem = mem_hazard || mem_exception;
|
val kill_mem = mem_hazard || mem_exception;
|
||||||
@ -560,7 +570,7 @@ class rocketCtrl extends Component
|
|||||||
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 = mem_exception || mem_reg_eret || replay_mem
|
||||||
val take_pc = take_pc_ex || take_pc_mem
|
take_pc <== take_pc_ex || take_pc_mem
|
||||||
|
|
||||||
// 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
|
||||||
@ -583,12 +593,7 @@ class rocketCtrl extends Component
|
|||||||
|
|
||||||
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.stallf :=
|
io.dpath.stallf := io.dpath.stalld;
|
||||||
~take_pc &
|
|
||||||
(
|
|
||||||
~io.imem.resp_val |
|
|
||||||
io.dpath.stalld
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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 =
|
||||||
|
@ -11,7 +11,6 @@ class ioImem(view: List[String] = null) extends Bundle (view)
|
|||||||
val invalidate = Bool('input);
|
val invalidate = Bool('input);
|
||||||
val itlb_miss = Bool('input);
|
val itlb_miss = Bool('input);
|
||||||
val req_val = Bool('input);
|
val req_val = Bool('input);
|
||||||
val req_rdy = Bool('output);
|
|
||||||
val req_idx = Bits(PGIDX_BITS, 'input);
|
val req_idx = Bits(PGIDX_BITS, 'input);
|
||||||
val req_ppn = Bits(PPN_BITS, 'input);
|
val req_ppn = Bits(PPN_BITS, 'input);
|
||||||
val resp_data = Bits(32, 'output);
|
val resp_data = Bits(32, 'output);
|
||||||
@ -60,15 +59,16 @@ class rocketICacheDM(lines: Int) extends Component {
|
|||||||
val r_cpu_req_idx = Reg { Bits(width = PGIDX_BITS) }
|
val r_cpu_req_idx = Reg { Bits(width = PGIDX_BITS) }
|
||||||
val r_cpu_req_ppn = Reg { Bits(width = PPN_BITS) }
|
val r_cpu_req_ppn = Reg { Bits(width = PPN_BITS) }
|
||||||
val r_cpu_req_val = Reg(resetVal = Bool(false));
|
val r_cpu_req_val = Reg(resetVal = Bool(false));
|
||||||
val r_rdy = Reg(io.cpu.req_rdy)
|
|
||||||
|
val rdy = Wire() { Bool() }
|
||||||
|
|
||||||
when (io.cpu.req_val && io.cpu.req_rdy) {
|
when (io.cpu.req_val && rdy) {
|
||||||
r_cpu_req_idx <== io.cpu.req_idx;
|
r_cpu_req_idx <== io.cpu.req_idx;
|
||||||
}
|
}
|
||||||
when (state === s_ready && r_cpu_req_val && !io.cpu.itlb_miss) {
|
when (state === s_ready && r_cpu_req_val && !io.cpu.itlb_miss) {
|
||||||
r_cpu_req_ppn <== io.cpu.req_ppn;
|
r_cpu_req_ppn <== io.cpu.req_ppn;
|
||||||
}
|
}
|
||||||
when (io.cpu.req_rdy) {
|
when (rdy) {
|
||||||
r_cpu_req_val <== io.cpu.req_val;
|
r_cpu_req_val <== io.cpu.req_val;
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
@ -112,8 +112,8 @@ class rocketICacheDM(lines: Int) extends Component {
|
|||||||
val data_array_rdata = data_array.rw(data_addr, io.mem.resp_data, io.mem.resp_val);
|
val data_array_rdata = data_array.rw(data_addr, io.mem.resp_data, io.mem.resp_val);
|
||||||
|
|
||||||
// output signals
|
// output signals
|
||||||
io.cpu.resp_val := !io.cpu.itlb_miss && (state === s_ready) && r_rdy && r_cpu_req_val && tag_valid && tag_match;
|
io.cpu.resp_val := !io.cpu.itlb_miss && (state === s_ready) && Reg(rdy) && r_cpu_req_val && tag_valid && tag_match;
|
||||||
io.cpu.req_rdy := !io.cpu.itlb_miss && (state === s_ready) && (!r_cpu_req_val || (tag_valid && tag_match));
|
rdy <== !io.cpu.itlb_miss && (state === s_ready) && (!r_cpu_req_val || (tag_valid && tag_match));
|
||||||
io.cpu.resp_data := data_array_rdata >> Cat(r_cpu_req_idx(offsetmsb-rf_cnt_bits,offsetlsb), UFix(0, log2up(databits))).toUFix
|
io.cpu.resp_data := data_array_rdata >> Cat(r_cpu_req_idx(offsetmsb-rf_cnt_bits,offsetlsb), UFix(0, log2up(databits))).toUFix
|
||||||
io.mem.req_val := (state === s_request);
|
io.mem.req_val := (state === s_request);
|
||||||
io.mem.req_addr := Cat(r_cpu_req_ppn, r_cpu_req_idx(indexmsb,indexlsb)).toUFix
|
io.mem.req_addr := Cat(r_cpu_req_ppn, r_cpu_req_idx(indexmsb,indexlsb)).toUFix
|
||||||
|
@ -37,9 +37,9 @@ class Top() extends Component {
|
|||||||
object top_main {
|
object top_main {
|
||||||
def main(args: Array[String]) = {
|
def main(args: Array[String]) = {
|
||||||
// Can turn off --debug and --vcd when done with debugging to improve emulator performance
|
// Can turn off --debug and --vcd when done with debugging to improve emulator performance
|
||||||
// val cpu_args = args ++ Array("--target-dir", "generated-src","--debug","--vcd");
|
val cpu_args = args ++ Array("--target-dir", "generated-src","--debug","--vcd");
|
||||||
// val cpu_args = args ++ Array("--target-dir", "generated-src", "--debug");
|
// val cpu_args = args ++ Array("--target-dir", "generated-src", "--debug");
|
||||||
val cpu_args = args ++ Array("--target-dir", "generated-src");
|
// val cpu_args = args ++ Array("--target-dir", "generated-src");
|
||||||
// Set variables based off of command flags
|
// Set variables based off of command flags
|
||||||
// for(a <- args) {
|
// for(a <- args) {
|
||||||
// a match {
|
// a match {
|
||||||
|
Loading…
Reference in New Issue
Block a user