1
0

more cache fixes, more test harness debug output

This commit is contained in:
Rimas Avizienis 2011-11-13 23:32:18 -08:00
parent 67c7e7e28f
commit 9d3471a569
4 changed files with 100 additions and 27 deletions

View File

@ -81,6 +81,77 @@ class rocketCtrl extends Component
{
val io = new ioCtrlAll();
val fp =
ListLookup(io.dpath.inst,
List(Bool(false)),
Array(
FMOVZ -> List(Bool(true)),
FMOVN -> List(Bool(true)),
FADD_S -> List(Bool(true)),
FSUB_S -> List(Bool(true)),
FMUL_S -> List(Bool(true)),
FDIV_S -> List(Bool(true)),
FSQRT_S -> List(Bool(true)),
FSGNJ_S -> List(Bool(true)),
FSGNJN_S -> List(Bool(true)),
FSGNJX_S -> List(Bool(true)),
FADD_D -> List(Bool(true)),
FSUB_D -> List(Bool(true)),
FMUL_D -> List(Bool(true)),
FDIV_D -> List(Bool(true)),
FSQRT_D -> List(Bool(true)),
FSGNJ_D -> List(Bool(true)),
FSGNJN_D -> List(Bool(true)),
FSGNJX_D -> List(Bool(true)),
FCVT_L_S -> List(Bool(true)),
FCVT_LU_S -> List(Bool(true)),
FCVT_W_S -> List(Bool(true)),
FCVT_WU_S -> List(Bool(true)),
FCVT_L_D -> List(Bool(true)),
FCVT_LU_D -> List(Bool(true)),
FCVT_W_D -> List(Bool(true)),
FCVT_WU_D -> List(Bool(true)),
FCVT_S_L -> List(Bool(true)),
FCVT_S_LU -> List(Bool(true)),
FCVT_S_W -> List(Bool(true)),
FCVT_S_WU -> List(Bool(true)),
FCVT_D_L -> List(Bool(true)),
FCVT_D_LU -> List(Bool(true)),
FCVT_D_W -> List(Bool(true)),
FCVT_D_WU -> List(Bool(true)),
FCVT_S_D -> List(Bool(true)),
FCVT_D_S -> List(Bool(true)),
FEQ_S -> List(Bool(true)),
FLT_S -> List(Bool(true)),
FLE_S -> List(Bool(true)),
FEQ_D -> List(Bool(true)),
FLT_D -> List(Bool(true)),
FLE_D -> List(Bool(true)),
FMIN_S -> List(Bool(true)),
FMAX_S -> List(Bool(true)),
FMIN_D -> List(Bool(true)),
FMAX_D -> List(Bool(true)),
MFTX_S -> List(Bool(true)),
MFTX_D -> List(Bool(true)),
MFFSR -> List(Bool(true)),
MXTF_S -> List(Bool(true)),
MXTF_D -> List(Bool(true)),
MTFSR -> List(Bool(true)),
FLW -> List(Bool(true)),
FLD -> List(Bool(true)),
FSW -> List(Bool(true)),
FSD -> List(Bool(true)),
FMADD_S -> List(Bool(true)),
FMSUB_S -> List(Bool(true)),
FNMSUB_S -> List(Bool(true)),
FNMADD_S -> List(Bool(true)),
FMADD_D -> List(Bool(true)),
FMSUB_D -> List(Bool(true)),
FNMSUB_D -> List(Bool(true)),
FNMADD_D -> List(Bool(true))
));
val id_fp_val :: Nil = fp;
val xpr64 = Y;
val cs =
ListLookup(io.dpath.inst,
@ -198,7 +269,6 @@ class rocketCtrl extends Component
val if_reg_xcpt_ma_inst = Reg(io.dpath.xcpt_ma_inst);
// FIXME
// io.imem.req_val := io.host.start && !io.dpath.xcpt_ma_inst;
io.imem.req_val := io.host.start && !io.dpath.xcpt_ma_inst;
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;
@ -254,15 +324,14 @@ class rocketCtrl extends Component
val ex_reg_xcpt_itlb = Reg(resetVal = Bool(false));
val ex_reg_xcpt_illegal = 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 mem_reg_xcpt_ma_inst = Reg(resetVal = Bool(false));
val mem_reg_xcpt_itlb = Reg(resetVal = Bool(false));
val mem_reg_xcpt_illegal = Reg(resetVal = Bool(false));
val mem_reg_xcpt_privileged = Reg(resetVal = Bool(false));
// val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false));
val mem_reg_xcpt_fpu = Bool(false); // FIXME: trap on unimplemented FPU instructions
val mem_reg_xcpt_fpu = Reg(resetVal = Bool(false));
val mem_reg_xcpt_syscall = Reg(resetVal = Bool(false));
when (!io.dpath.stalld) {
@ -278,6 +347,8 @@ class rocketCtrl extends Component
}
}
val illegal_inst = !id_int_val.toBool && !id_fp_val.toBool;
when (reset.toBool || io.dpath.killd) {
ex_reg_br_type <== BR_N;
ex_reg_btb_hit <== Bool(false);
@ -292,7 +363,7 @@ class rocketCtrl extends Component
ex_reg_xcpt_itlb <== Bool(false);
ex_reg_xcpt_illegal <== 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);
}
otherwise {
@ -307,9 +378,9 @@ class rocketCtrl extends Component
ex_reg_xcpt_ma_inst <== id_reg_xcpt_ma_inst;
ex_reg_xcpt_itlb <== id_reg_xcpt_itlb;
ex_reg_xcpt_illegal <== ~id_int_val.toBool;
ex_reg_xcpt_illegal <== illegal_inst;
ex_reg_xcpt_privileged <== (id_privileged & ~io.dpath.status(5)).toBool;
// ex_reg_xcpt_fpu <== Bool(false);
ex_reg_xcpt_fpu <== id_fp_val.toBool;
ex_reg_xcpt_syscall <== id_syscall.toBool;
}
@ -354,7 +425,7 @@ class rocketCtrl extends Component
mem_reg_xcpt_itlb <== Bool(false);
mem_reg_xcpt_illegal <== 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);
}
otherwise {
@ -369,7 +440,7 @@ class rocketCtrl extends Component
mem_reg_xcpt_itlb <== ex_reg_xcpt_itlb;
mem_reg_xcpt_illegal <== ex_reg_xcpt_illegal;
mem_reg_xcpt_privileged <== ex_reg_xcpt_privileged;
// mem_reg_xcpt_fpu <== Bool(false);
mem_reg_xcpt_fpu <== ex_reg_xcpt_fpu;
mem_reg_xcpt_syscall <== ex_reg_xcpt_syscall;
}

View File

@ -15,7 +15,6 @@ class ioDmem(view: List[String] = null) extends Bundle(view) {
val req_type = Bits(3, 'input);
val req_idx = Bits(PGIDX_BITS, 'input);
val req_ppn = Bits(PPN_BITS, 'input);
// val req_addr = UFix(PADDR_BITS, 'input);
val req_data = Bits(64, 'input);
val req_tag = Bits(5, 'input);
val xcpt_ma_ld = Bool('output); // misaligned load
@ -203,6 +202,7 @@ class rocketDCacheDM(lines: Int) extends Component {
val req_store = (io.cpu.req_cmd === M_XWR);
val req_load = (io.cpu.req_cmd === M_XRD) || (io.cpu.req_cmd === M_PRD);
val req_flush = (io.cpu.req_cmd === M_FLA);
val r_req_load = (r_cpu_req_cmd === M_XRD) || (r_cpu_req_cmd === M_PRD);
val r_req_store = (r_cpu_req_cmd === M_XWR);
val r_req_flush = (r_cpu_req_cmd === M_FLA);
@ -243,7 +243,7 @@ class rocketDCacheDM(lines: Int) extends Component {
Mux((state === s_ready), io.cpu.req_idx(PGIDX_BITS-1,offsetbits),
r_cpu_req_idx(PGIDX_BITS-1,offsetbits)).toUFix;
val tag_we =
((state === s_refill) && io.mem.req_rdy && (rr_count === UFix(3,2))) ||
((state === s_refill) && io.mem.resp_val && (rr_count === UFix(3,2))) ||
((state === s_resolve_miss) && r_req_flush);
val tag_array = new rocketSRAMsp(lines, tagbits);
@ -268,15 +268,20 @@ class rocketDCacheDM(lines: Int) extends Component {
val vb_rdata = Reg(vb_array(tag_addr).toBool);
val tag_valid = r_cpu_req_val && vb_rdata;
val tag_match = (tag_rdata === io.cpu.req_ppn);
val tag_hit = tag_valid && tag_match;
val miss = r_cpu_req_val && (!vb_rdata || !tag_match);
// load/store addresses conflict if they are to any part of the same 64 bit word
val addr_match = (r_cpu_req_idx(PGIDX_BITS-1,offsetlsb) === p_store_idx(PGIDX_BITS-1,offsetlsb));
val ldst_conflict = r_cpu_req_val && r_req_load && p_store_valid && addr_match;
val ldst_conflict = tag_valid && tag_match && r_req_load && p_store_valid && addr_match;
val store_hit = r_cpu_req_val && !io.cpu.dtlb_miss && tag_hit && r_req_store ;
// write the pending store data when the cache is idle, when the next command isn't a load
// or when there's a load to the same address (in which case there's a 2 cycle delay:
// once cycle to write the store data and another to read the data back)
val drain_store = !io.cpu.dtlb_miss && p_store_valid && (!io.cpu.req_val || req_store || ldst_conflict);
// once cycle to write the store data and another to read the data back)
val drain_store =
((store_hit || p_store_valid) && (!io.cpu.req_val || req_store || req_flush)) ||
(p_store_valid && (miss || ldst_conflict));
// write pending store data from a store which missed
// after the cache line refill has completed
@ -290,12 +295,10 @@ class rocketDCacheDM(lines: Int) extends Component {
p_store_idx <== io.cpu.req_idx;
p_store_data <== io.cpu.req_data;
p_store_type <== io.cpu.req_type;
p_store_valid <== Bool(true);
}
// cancel store if there's a DTLB miss
when (r_cpu_req_val && r_req_store && io.cpu.dtlb_miss)
{
p_store_valid <== Bool(false);
when (store_hit && !drain_store) {
p_store_valid <== Bool(true);
}
when (drain_store) {
p_store_valid <== Bool(false);
@ -341,13 +344,12 @@ class rocketDCacheDM(lines: Int) extends Component {
// signal a load miss when the data isn't present in the cache and when it's in the pending store data register
// (causes the cache to block for 2 cycles and the load instruction is replayed)
val hit = tag_valid && tag_match;
val load_miss = !io.cpu.dtlb_miss && (state === s_ready) && r_cpu_req_val && r_req_load && (!hit || (p_store_valid && addr_match));
val load_miss = !io.cpu.dtlb_miss && (state === s_ready) && r_cpu_req_val && r_req_load && (!tag_hit || (p_store_valid && addr_match));
// output signals
// busy when there's a load to the same address as a pending store, or on a cache miss, or when executing a flush
io.cpu.req_rdy := !io.cpu.dtlb_miss && (state === s_ready) && !ldst_conflict && (!r_cpu_req_val || (hit && !r_req_flush));
io.cpu.resp_val := !io.cpu.dtlb_miss && ((state === s_ready) && hit && r_req_load && !(p_store_valid && addr_match)) ||
io.cpu.req_rdy := (state === s_ready) && !io.cpu.dtlb_miss && !ldst_conflict && (!r_cpu_req_val || (tag_hit && !r_req_flush));
io.cpu.resp_val := !io.cpu.dtlb_miss && ((state === s_ready) && tag_hit && r_req_load && !(p_store_valid && addr_match)) ||
((state === s_resolve_miss) && r_req_flush) ||
r_cpu_resp_val;
@ -386,7 +388,7 @@ class rocketDCacheDM(lines: Int) extends Component {
when (ldst_conflict) {
state <== s_replay_load;
}
when (!r_cpu_req_val || (hit && !r_req_flush)) {
when (!r_cpu_req_val || (tag_hit && !r_req_flush)) {
state <== s_ready;
}
when (tag_valid & tag_dirty) {

View File

@ -136,7 +136,7 @@ class rocketDTLB(entries: Int) extends Component
}
// exception check
val outofrange = (io.cpu.resp_ppn > UFix(MEMSIZE_PAGES, PPN_BITS));
val outofrange = !tlb_miss && (io.cpu.resp_ppn > UFix(MEMSIZE_PAGES, PPN_BITS));
val access_fault_ld =
tlb_hit && req_load &&

View File

@ -170,7 +170,7 @@ class rocketITLB(entries: Int) extends Component
}
// exception check
val outofrange = (io.cpu.resp_ppn > UFix(MEMSIZE_PAGES, PPN_BITS));
val outofrange = !tlb_miss && (io.cpu.resp_ppn > UFix(MEMSIZE_PAGES, PPN_BITS));
val access_fault =
tlb_hit &&