diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 2277ad4a..3eb1b374 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -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; } diff --git a/rocket/src/main/scala/dcache.scala b/rocket/src/main/scala/dcache.scala index 863c0855..d71b2155 100644 --- a/rocket/src/main/scala/dcache.scala +++ b/rocket/src/main/scala/dcache.scala @@ -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) { diff --git a/rocket/src/main/scala/dtlb.scala b/rocket/src/main/scala/dtlb.scala index 2d4089e9..90e1088b 100644 --- a/rocket/src/main/scala/dtlb.scala +++ b/rocket/src/main/scala/dtlb.scala @@ -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 && diff --git a/rocket/src/main/scala/itlb.scala b/rocket/src/main/scala/itlb.scala index b6e82faf..dcfb0efb 100644 --- a/rocket/src/main/scala/itlb.scala +++ b/rocket/src/main/scala/itlb.scala @@ -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 &&