diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index 9d7d4484..777a8de8 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -157,6 +157,16 @@ object Constants val PCR_K0 = UFix(24, 5); val PCR_K1 = UFix(25, 5); + // definition of bits in PCR status reg + val SR_ET = 0; // enable traps + val SR_EF = 1; // enable floating point + val SR_EV = 2; // enable vector unit + val SR_PS = 4; // mode stack bit + val SR_S = 5; // user/supervisor mode + val SR_UX = 6; // 64 bit user mode + val SR_SX = 7; // 64 bit supervisor mode + val SR_VM = 16; // VM enable + val COREID = 0; val NUMCORES = 1; val PADDR_BITS = 40; diff --git a/rocket/src/main/scala/ctrl.scala b/rocket/src/main/scala/ctrl.scala index 3aff5072..0fa03d4a 100644 --- a/rocket/src/main/scala/ctrl.scala +++ b/rocket/src/main/scala/ctrl.scala @@ -326,7 +326,7 @@ class rocketCtrl extends Component val jr_taken = (ex_reg_br_type === BR_JR); val j_taken = (ex_reg_br_type === BR_J); - io.dmem.req_val := ex_reg_mem_val && ~io.dpath.killx; + io.dmem.req_val := ex_reg_mem_val; // && ~io.dpath.killx; io.dmem.req_cmd := ex_reg_mem_cmd; io.dmem.req_type := ex_reg_mem_type; @@ -407,15 +407,15 @@ class rocketCtrl extends Component // replay execute stage PC when the D$ is blocked, when the D$ misses, and for privileged instructions val replay_ex = (ex_reg_mem_val && !io.dmem.req_rdy) || io.dmem.resp_miss || mem_reg_privileged; - // replay mem stage PC on a DTLB miss val replay_mem = io.dtlb_miss; +// val replay_mem = Bool(false); val kill_ex = replay_ex || replay_mem; - val kill_mem = mem_exception || io.dtlb_miss; + val kill_mem = mem_exception || replay_mem; io.dpath.sel_pc := - Mux(mem_exception, PC_EVEC, // exception Mux(replay_mem, PC_MEM, // dtlb miss + Mux(mem_exception, PC_EVEC, // exception Mux(mem_reg_eret, PC_PCR, // eret instruction Mux(replay_ex, PC_EX, // D$ blocked, D$ miss, privileged inst Mux(!ex_reg_btb_hit && br_taken, PC_BR, // mispredicted taken branch @@ -513,7 +513,7 @@ class rocketCtrl extends Component io.dpath.killf := take_pc | ~io.imem.resp_val; io.dpath.killd := ctrl_killd.toBool; - io.dpath.killx := kill_ex.toBool || kill_mem.toBool; + io.dpath.killx := kill_ex.toBool; io.dpath.killm := kill_mem.toBool; io.dpath.mem_load := mem_reg_mem_val && (mem_reg_mem_cmd === M_XRD); diff --git a/rocket/src/main/scala/dpath_util.scala b/rocket/src/main/scala/dpath_util.scala index 2ef560d0..1c10abf3 100644 --- a/rocket/src/main/scala/dpath_util.scala +++ b/rocket/src/main/scala/dpath_util.scala @@ -135,15 +135,15 @@ class rocketDpathPCR extends Component when (!io.exception && !io.eret && io.w.en) { when (io.w.addr === PCR_STATUS) { - reg_status_vm <== io.w.data(16).toBool; + reg_status_vm <== io.w.data(SR_VM).toBool; reg_status_im <== io.w.data(15,8); - reg_status_sx <== io.w.data(7).toBool; - reg_status_ux <== io.w.data(6).toBool; - reg_status_s <== io.w.data(5).toBool; - reg_status_ps <== io.w.data(4).toBool; - reg_status_ev <== HAVE_VEC && io.w.data(2).toBool; - reg_status_ef <== HAVE_FPU && io.w.data(1).toBool; - reg_status_et <== io.w.data(0).toBool; + reg_status_sx <== io.w.data(SR_SX).toBool; + reg_status_ux <== io.w.data(SR_UX).toBool; + reg_status_s <== io.w.data(SR_S).toBool; + reg_status_ps <== io.w.data(SR_PS).toBool; + reg_status_ev <== HAVE_VEC && io.w.data(SR_EV).toBool; + reg_status_ef <== HAVE_FPU && io.w.data(SR_EF).toBool; + reg_status_et <== io.w.data(SR_ET).toBool; } when (io.w.addr === PCR_EPC) { reg_epc <== io.w.data(VADDR_BITS-1,0).toUFix; } when (io.w.addr === PCR_BADVADDR) { reg_badvaddr <== io.w.data(VADDR_BITS-1,0).toUFix; } diff --git a/rocket/src/main/scala/dtlb.scala b/rocket/src/main/scala/dtlb.scala index d27ffdc8..006d54a6 100644 --- a/rocket/src/main/scala/dtlb.scala +++ b/rocket/src/main/scala/dtlb.scala @@ -45,8 +45,8 @@ class rocketDTLB(entries: Int) extends Component val req_vpn = io.cpu.req_addr(VADDR_BITS-1,PGIDX_BITS); val req_idx = io.cpu.req_addr(PGIDX_BITS-1,0); - val req_load = io.cpu.req_val && (io.cpu.req_cmd === M_XRD); - val req_store = io.cpu.req_val && (io.cpu.req_cmd === M_XWR); + val req_load = (io.cpu.req_cmd === M_XRD); + val req_store = (io.cpu.req_cmd === M_XWR); // val req_amo = io.cpu.req_cmd(3).toBool; val lookup_tag = Cat(io.cpu.req_asid, req_vpn); @@ -61,11 +61,12 @@ class rocketDTLB(entries: Int) extends Component tag_cam.io.write := io.ptw.resp_val; tag_cam.io.write_tag := r_refill_tag; tag_cam.io.write_addr := r_refill_waddr; - val tag_hit_addr = tag_cam.io.hit_addr; + val tag_hit_addr = tag_cam.io.hit_addr; // extract fields from status register - val status_mode = io.cpu.status(6).toBool; // user/supervisor mode - val status_vm = io.cpu.status(16).toBool // virtual memory enable + val status_s = io.cpu.status(SR_S).toBool; // user/supervisor mode + val status_u = !status_s; + val status_vm = io.cpu.status(SR_VM).toBool // virtual memory enable // extract fields from PT permission bits val ptw_perm_ur = io.ptw.resp_perm(1); @@ -80,7 +81,7 @@ class rocketDTLB(entries: Int) extends Component val sw_array = Reg(resetVal = Bits(0, entries)); // supervisor execute permission when (io.ptw.resp_val) { ur_array <== ur_array.bitSet(r_refill_waddr, ptw_perm_ur); - uw_array <== ur_array.bitSet(r_refill_waddr, ptw_perm_uw); + uw_array <== uw_array.bitSet(r_refill_waddr, ptw_perm_uw); sr_array <== sr_array.bitSet(r_refill_waddr, ptw_perm_sr); sw_array <== sw_array.bitSet(r_refill_waddr, ptw_perm_sw); } @@ -89,7 +90,7 @@ class rocketDTLB(entries: Int) extends Component // bits to 0 so the next access will cause an exception when (io.ptw.resp_err) { ur_array <== ur_array.bitSet(r_refill_waddr, Bool(false)); - uw_array <== ur_array.bitSet(r_refill_waddr, Bool(false)); + uw_array <== uw_array.bitSet(r_refill_waddr, Bool(false)); sr_array <== sr_array.bitSet(r_refill_waddr, Bool(false)); sw_array <== sw_array.bitSet(r_refill_waddr, Bool(false)); } @@ -102,10 +103,13 @@ class rocketDTLB(entries: Int) extends Component val repl_waddr = Mux(invalid_entry, ie_addr, repl_count).toUFix; - val tag_hit = io.cpu.req_val && tag_cam.io.hit; - val lookup_miss = (state === s_ready) && status_vm && !tag_hit; - - when (lookup_miss) { + val lookup_hit = (state === s_ready) && io.cpu.req_val && tag_cam.io.hit; + val lookup_miss = (state === s_ready) && io.cpu.req_val && !tag_cam.io.hit; + + val tlb_hit = status_vm && lookup_hit; + val tlb_miss = status_vm && lookup_miss; + + when (tlb_miss) { r_refill_tag <== lookup_tag; r_refill_waddr <== repl_waddr; when (!invalid_entry) { @@ -113,19 +117,20 @@ class rocketDTLB(entries: Int) extends Component } } + // FIXME: add check for out of range physical addresses (>MEMSIZE) io.cpu.xcpt_ld := - status_vm && tag_hit && req_load && - !((status_mode && sw_array(tag_hit_addr).toBool) || - (!status_mode && uw_array(tag_hit_addr).toBool)); + tlb_hit && req_load && + ((status_s && !sr_array(tag_hit_addr).toBool) || + (status_u && !ur_array(tag_hit_addr).toBool)); io.cpu.xcpt_st := - status_vm && tag_hit && req_store && - !((status_mode && sr_array(tag_hit_addr).toBool) || - (!status_mode && ur_array(tag_hit_addr).toBool)); + tlb_hit && req_store && + ((status_s && !sw_array(tag_hit_addr).toBool) || + (status_u && !uw_array(tag_hit_addr).toBool)); io.cpu.req_rdy := (state === s_ready); - io.cpu.resp_miss := lookup_miss; - io.cpu.resp_val := Mux(status_vm, tag_hit, io.cpu.req_val); + io.cpu.resp_miss := tlb_miss; + io.cpu.resp_val := Mux(status_vm, lookup_hit, io.cpu.req_val); io.cpu.resp_addr := Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx), io.cpu.req_addr(PADDR_BITS-1,0)).toUFix; @@ -136,7 +141,7 @@ class rocketDTLB(entries: Int) extends Component // control state machine switch (state) { is (s_ready) { - when (status_vm && io.cpu.req_val && !tag_hit) { + when (tlb_miss) { state <== s_request; } } diff --git a/rocket/src/main/scala/itlb.scala b/rocket/src/main/scala/itlb.scala index 55620a28..8068a30f 100644 --- a/rocket/src/main/scala/itlb.scala +++ b/rocket/src/main/scala/itlb.scala @@ -113,8 +113,9 @@ class rocketITLB(entries: Int) extends Component val tag_hit_addr = tag_cam.io.hit_addr; // extract fields from status register - val status_mode = io.cpu.status(6).toBool; // user/supervisor mode - val status_vm = io.cpu.status(16).toBool // virtual memory enable + val status_s = io.cpu.status(SR_S).toBool; // user/supervisor mode + val status_u = !status_s; + val status_vm = io.cpu.status(SR_VM).toBool // virtual memory enable // extract fields from PT permission bits val ptw_perm_ux = io.ptw.resp_perm(0); @@ -143,10 +144,13 @@ class rocketITLB(entries: Int) extends Component val repl_waddr = Mux(invalid_entry, ie_addr, repl_count).toUFix; - val tag_hit = io.cpu.req_val && tag_cam.io.hit; - val lookup_miss = (state === s_ready) && status_vm && !tag_hit; + val lookup_hit = (state === s_ready) && io.cpu.req_val && tag_cam.io.hit; + val lookup_miss = (state === s_ready) && io.cpu.req_val && !tag_cam.io.hit; + + val tlb_hit = status_vm && lookup_hit; + val tlb_miss = status_vm && lookup_miss; - when (lookup_miss) { + when (tlb_miss) { r_refill_tag <== lookup_tag; r_refill_waddr <== repl_waddr; when (!invalid_entry) { @@ -154,25 +158,25 @@ class rocketITLB(entries: Int) extends Component } } - val itlb_exception = - tag_hit && - !((status_mode && sx_array(tag_hit_addr).toBool) || - (!status_mode && ux_array(tag_hit_addr).toBool)); + // FIXME: add test for out of range physical addresses (> MEMSIZE) + io.cpu.exception := + tlb_hit && + ((status_s && !sx_array(tag_hit_addr).toBool) || + (status_u && !ux_array(tag_hit_addr).toBool)); io.cpu.req_rdy := (state === s_ready); - io.cpu.resp_val := Mux(status_vm, tag_hit, io.cpu.req_val); + io.cpu.resp_val := Mux(status_vm, lookup_hit, io.cpu.req_val); io.cpu.resp_addr := Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx), io.cpu.req_addr(PADDR_BITS-1,0)).toUFix; - io.cpu.exception := status_vm && itlb_exception; io.ptw.req_val := (state === s_request); io.ptw.req_vpn := r_refill_tag(VPN_BITS-1,0); - + // control state machine switch (state) { is (s_ready) { - when (status_vm && !tag_hit) { + when (tlb_miss) { state <== s_request; } } diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index 524984e5..64cdb76d 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -25,7 +25,7 @@ class rocketDmemArbiter extends Component io.ptw.req_rdy := io.mem.req_rdy; io.cpu.req_rdy := io.mem.req_rdy && !io.ptw.req_val; - io.cpu.resp_miss := io.mem.resp_miss; // FIXME + io.cpu.resp_miss := io.mem.resp_miss && !io.mem.resp_tag(11).toBool; io.cpu.resp_val := io.mem.resp_val && !io.mem.resp_tag(11).toBool; io.ptw.resp_val := io.mem.resp_val && io.mem.resp_tag(11).toBool;