checkpoint
This commit is contained in:
parent
f86d5b1334
commit
e4fa94aa27
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user