more tlb/ptw fixes
This commit is contained in:
parent
6664af3bc0
commit
62407b4668
@ -45,16 +45,15 @@ class rocketProc extends Component
|
|||||||
val ctrl = new rocketCtrl();
|
val ctrl = new rocketCtrl();
|
||||||
val dpath = new rocketDpath();
|
val dpath = new rocketDpath();
|
||||||
|
|
||||||
val dtlb = new rocketDTLB(ITLB_ENTRIES);
|
val dtlb = new rocketDTLB(DTLB_ENTRIES);
|
||||||
val itlb = new rocketITLB(ITLB_ENTRIES);
|
val itlb = new rocketITLB(ITLB_ENTRIES);
|
||||||
val ptw = new rocketPTW();
|
val ptw = new rocketPTW();
|
||||||
val arb = new rocketDmemArbiter();
|
val arb = new rocketDmemArbiter();
|
||||||
|
|
||||||
ctrl.io.dpath <> dpath.io.ctrl;
|
ctrl.io.dpath <> dpath.io.ctrl;
|
||||||
// ctrl.io.dmem ^^ io.dmem;
|
|
||||||
ctrl.io.host.start ^^ io.host.start;
|
ctrl.io.host.start ^^ io.host.start;
|
||||||
|
// ctrl.io.dmem ^^ io.dmem;
|
||||||
// ctrl.io.imem ^^ io.imem;
|
// ctrl.io.imem ^^ io.imem;
|
||||||
|
|
||||||
// dpath.io.dmem ^^ io.dmem;
|
// dpath.io.dmem ^^ io.dmem;
|
||||||
// dpath.io.imem.req_addr ^^ io.imem.req_addr;
|
// dpath.io.imem.req_addr ^^ io.imem.req_addr;
|
||||||
dpath.io.imem.resp_data ^^ io.imem.resp_data;
|
dpath.io.imem.resp_data ^^ io.imem.resp_data;
|
||||||
@ -63,7 +62,7 @@ class rocketProc extends Component
|
|||||||
|
|
||||||
// FIXME: make this less verbose
|
// FIXME: make this less verbose
|
||||||
// connect ITLB to I$, ctrl, dpath
|
// connect ITLB to I$, ctrl, dpath
|
||||||
itlb.io.cpu.invalidate := Bool(false);
|
itlb.io.cpu.invalidate := Bool(false); // FIXME
|
||||||
itlb.io.cpu.status := dpath.io.ctrl.status;
|
itlb.io.cpu.status := dpath.io.ctrl.status;
|
||||||
itlb.io.cpu.req_val := ctrl.io.imem.req_val;
|
itlb.io.cpu.req_val := ctrl.io.imem.req_val;
|
||||||
itlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
|
itlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
|
||||||
@ -74,9 +73,18 @@ class rocketProc extends Component
|
|||||||
ctrl.io.imem.resp_val := io.imem.resp_val;
|
ctrl.io.imem.resp_val := io.imem.resp_val;
|
||||||
ctrl.io.itlb_xcpt := itlb.io.cpu.exception;
|
ctrl.io.itlb_xcpt := itlb.io.cpu.exception;
|
||||||
|
|
||||||
|
// connect DTLB to D$ arbiter, ctrl+dpath
|
||||||
|
dtlb.io.cpu.invalidate := Bool(false); // FIXME
|
||||||
|
dtlb.io.cpu.status := dpath.io.ctrl.status;
|
||||||
|
dtlb.io.cpu.req_val := ctrl.io.dmem.req_val;
|
||||||
|
dtlb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
|
||||||
|
dtlb.io.cpu.req_asid := Bits(0,ASID_BITS); // FIXME: connect to PCR
|
||||||
|
dtlb.io.cpu.req_addr := dpath.io.dmem.req_addr;
|
||||||
|
ctrl.io.dtlb_xcpt := dtlb.io.cpu.exception;
|
||||||
|
|
||||||
// connect page table walker to TLBs, page table base register (from PCR)
|
// connect page table walker to TLBs, page table base register (from PCR)
|
||||||
// and D$ arbiter (selects between requests from pipeline and PTW, PTW has priority)
|
// and D$ arbiter (selects between requests from pipeline and PTW, PTW has priority)
|
||||||
|
ptw.io.dtlb <> dtlb.io.ptw;
|
||||||
ptw.io.itlb <> itlb.io.ptw;
|
ptw.io.itlb <> itlb.io.ptw;
|
||||||
ptw.io.ptbr := dpath.io.ptbr;
|
ptw.io.ptbr := dpath.io.ptbr;
|
||||||
arb.io.ptw <> ptw.io.dmem;
|
arb.io.ptw <> ptw.io.dmem;
|
||||||
@ -84,19 +92,31 @@ class rocketProc extends Component
|
|||||||
|
|
||||||
// FIXME: make this less verbose
|
// FIXME: make this less verbose
|
||||||
// connect arbiter to ctrl+dpath
|
// connect arbiter to ctrl+dpath
|
||||||
arb.io.cpu.req_val := ctrl.io.dmem.req_val;
|
arb.io.cpu.req_val := dtlb.io.cpu.resp_val;
|
||||||
arb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
|
arb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
|
||||||
arb.io.cpu.req_type := ctrl.io.dmem.req_type;
|
arb.io.cpu.req_type := ctrl.io.dmem.req_type;
|
||||||
arb.io.cpu.req_addr := dpath.io.dmem.req_addr;
|
arb.io.cpu.req_addr := dtlb.io.cpu.resp_addr;
|
||||||
arb.io.cpu.req_data := dpath.io.dmem.req_data;
|
arb.io.cpu.req_data := dpath.io.dmem.req_data;
|
||||||
arb.io.cpu.req_tag := dpath.io.dmem.req_tag;
|
arb.io.cpu.req_tag := dpath.io.dmem.req_tag;
|
||||||
ctrl.io.dmem.req_rdy := arb.io.cpu.req_rdy;
|
ctrl.io.dmem.req_rdy := dtlb.io.cpu.req_rdy && arb.io.cpu.req_rdy;
|
||||||
ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss;
|
ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss;
|
||||||
ctrl.io.dmem.resp_val := arb.io.cpu.resp_val;
|
|
||||||
dpath.io.dmem.resp_val := arb.io.cpu.resp_val;
|
dpath.io.dmem.resp_val := arb.io.cpu.resp_val;
|
||||||
dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
|
dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
|
||||||
dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
|
dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
|
||||||
|
|
||||||
|
// arb.io.cpu.req_val := ctrl.io.dmem.req_val;
|
||||||
|
// arb.io.cpu.req_cmd := ctrl.io.dmem.req_cmd;
|
||||||
|
// arb.io.cpu.req_type := ctrl.io.dmem.req_type;
|
||||||
|
// arb.io.cpu.req_addr := dpath.io.dmem.req_addr;
|
||||||
|
// arb.io.cpu.req_data := dpath.io.dmem.req_data;
|
||||||
|
// arb.io.cpu.req_tag := dpath.io.dmem.req_tag;
|
||||||
|
// ctrl.io.dmem.req_rdy := arb.io.cpu.req_rdy;
|
||||||
|
// ctrl.io.dmem.resp_miss := arb.io.cpu.resp_miss;
|
||||||
|
// ctrl.io.dmem.resp_val := arb.io.cpu.resp_val;
|
||||||
|
// dpath.io.dmem.resp_val := arb.io.cpu.resp_val;
|
||||||
|
// dpath.io.dmem.resp_tag := arb.io.cpu.resp_tag;
|
||||||
|
// dpath.io.dmem.resp_data := arb.io.cpu.resp_data;
|
||||||
|
|
||||||
// FIXME: console disconnected
|
// FIXME: console disconnected
|
||||||
// io.console.bits := dpath.io.dpath.rs1(7,0);
|
// io.console.bits := dpath.io.dpath.rs1(7,0);
|
||||||
io.console.bits := Bits(0,8);
|
io.console.bits := Bits(0,8);
|
||||||
|
@ -33,10 +33,13 @@ class ioCtrlDpath extends Bundle()
|
|||||||
val sel_wb = UFix(3, 'output);
|
val sel_wb = UFix(3, 'output);
|
||||||
val ren_pcr = Bool('output);
|
val ren_pcr = Bool('output);
|
||||||
val wen_pcr = Bool('output);
|
val wen_pcr = Bool('output);
|
||||||
|
// FIXME: move exception handling stuff (generating cause value, etc)
|
||||||
|
// from EX stage of dpath to MEM stage of control
|
||||||
val xcpt_illegal = Bool('output);
|
val xcpt_illegal = Bool('output);
|
||||||
val xcpt_privileged = Bool('output);
|
val xcpt_privileged = Bool('output);
|
||||||
val xcpt_fpu = Bool('output);
|
val xcpt_fpu = Bool('output);
|
||||||
val xcpt_syscall = Bool('output);
|
val xcpt_syscall = Bool('output);
|
||||||
|
// val xcpt_dtlb = Bool('output);
|
||||||
val xcpt_itlb = Bool('output);
|
val xcpt_itlb = Bool('output);
|
||||||
val eret = Bool('output);
|
val eret = Bool('output);
|
||||||
val mem_load = Bool('output);
|
val mem_load = Bool('output);
|
||||||
@ -68,6 +71,7 @@ class ioCtrlAll extends Bundle()
|
|||||||
val imem = new ioImem(List("req_val", "req_rdy", "resp_val")).flip();
|
val imem = new ioImem(List("req_val", "req_rdy", "resp_val")).flip();
|
||||||
val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "resp_miss")).flip();
|
val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "resp_miss")).flip();
|
||||||
val host = new ioHost(List("start"));
|
val host = new ioHost(List("start"));
|
||||||
|
val dtlb_xcpt = Bool('input);
|
||||||
val itlb_xcpt = Bool('input);
|
val itlb_xcpt = Bool('input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +241,7 @@ class rocketCtrl extends Component
|
|||||||
val ex_reg_mem_type = Reg(){UFix(width = 3)};
|
val ex_reg_mem_type = Reg(){UFix(width = 3)};
|
||||||
val ex_reg_eret = Reg(resetVal = Bool(false));
|
val ex_reg_eret = Reg(resetVal = Bool(false));
|
||||||
val ex_reg_privileged = Reg(resetVal = Bool(false));
|
val ex_reg_privileged = Reg(resetVal = Bool(false));
|
||||||
// val id_reg_itlb_xcpt = Reg(resetVal = Bool(false));
|
// val ex_reg_itlb_xcpt = Reg(resetVal = Bool(false));
|
||||||
|
|
||||||
when (!io.dpath.stalld) {
|
when (!io.dpath.stalld) {
|
||||||
when (io.dpath.killf) {
|
when (io.dpath.killf) {
|
||||||
@ -343,8 +347,10 @@ class rocketCtrl extends Component
|
|||||||
|
|
||||||
io.dpath.mem_load := mem_cmd_load;
|
io.dpath.mem_load := mem_cmd_load;
|
||||||
|
|
||||||
|
// FIXME: dtlb exception handling broken, need to move cause value generation
|
||||||
|
// to mem stage. also should probably move it from dpath to ctrl
|
||||||
io.dpath.sel_pc :=
|
io.dpath.sel_pc :=
|
||||||
Mux(io.dpath.exception || mem_reg_eret, PC_PCR,
|
Mux(io.dpath.exception || io.dtlb_xcpt, PC_PCR,
|
||||||
Mux(replay_ex || replay_mem || mem_reg_privileged, PC_EX,
|
Mux(replay_ex || replay_mem || mem_reg_privileged, PC_EX,
|
||||||
Mux(!ex_reg_btb_hit && br_taken, PC_BR,
|
Mux(!ex_reg_btb_hit && br_taken, PC_BR,
|
||||||
Mux(ex_reg_btb_hit && !br_taken, PC_EX4,
|
Mux(ex_reg_btb_hit && !br_taken, PC_EX4,
|
||||||
|
@ -5,6 +5,16 @@ import Node._;
|
|||||||
import Constants._
|
import Constants._
|
||||||
import Instructions._
|
import Instructions._
|
||||||
|
|
||||||
|
class ioDpathDmem extends Bundle()
|
||||||
|
{
|
||||||
|
val req_addr = UFix(VADDR_BITS, 'output);
|
||||||
|
val req_tag = UFix(5, 'output);
|
||||||
|
val req_data = Bits(64, 'output);
|
||||||
|
val resp_val = Bool('input);
|
||||||
|
val resp_tag = Bits(13, 'input); // FIXME: MSB is ignored
|
||||||
|
val resp_data = Bits(64, 'input);
|
||||||
|
}
|
||||||
|
|
||||||
class ioDpathImem extends Bundle()
|
class ioDpathImem extends Bundle()
|
||||||
{
|
{
|
||||||
val req_addr = UFix(VADDR_BITS, 'output);
|
val req_addr = UFix(VADDR_BITS, 'output);
|
||||||
@ -16,7 +26,8 @@ class ioDpathAll extends Bundle()
|
|||||||
val host = new ioHost();
|
val host = new ioHost();
|
||||||
val ctrl = new ioCtrlDpath().flip();
|
val ctrl = new ioCtrlDpath().flip();
|
||||||
val debug = new ioDebug();
|
val debug = new ioDebug();
|
||||||
val dmem = new ioDmem(List("req_addr", "req_data", "req_tag", "resp_val", "resp_tag", "resp_data")).flip();
|
// val dmem = new ioDmem(List("req_addr", "req_data", "req_tag", "resp_val", "resp_tag", "resp_data")).flip();
|
||||||
|
val dmem = new ioDpathDmem();
|
||||||
val imem = new ioDpathImem();
|
val imem = new ioDpathImem();
|
||||||
val ptbr = UFix(PADDR_BITS, 'output);
|
val ptbr = UFix(PADDR_BITS, 'output);
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ class rocketDTLB(entries: Int) extends Component
|
|||||||
|
|
||||||
val req_vpn = io.cpu.req_addr(VADDR_BITS-1,PGIDX_BITS);
|
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_idx = io.cpu.req_addr(PGIDX_BITS-1,0);
|
||||||
val req_load = (io.cpu.req_cmd === M_XRD);
|
val req_load = io.cpu.req_val && (io.cpu.req_cmd === M_XRD);
|
||||||
val req_store = (io.cpu.req_cmd === M_XWR);
|
val req_store = io.cpu.req_val && (io.cpu.req_cmd === M_XWR);
|
||||||
// val req_amo = io.cpu.req_cmd(3).toBool;
|
// val req_amo = io.cpu.req_cmd(3).toBool;
|
||||||
|
|
||||||
val lookup_tag = Cat(io.cpu.req_asid, req_vpn);
|
val lookup_tag = Cat(io.cpu.req_asid, req_vpn);
|
||||||
@ -65,10 +65,8 @@ class rocketDTLB(entries: Int) extends Component
|
|||||||
val status_vm = io.cpu.status(16).toBool // virtual memory enable
|
val status_vm = io.cpu.status(16).toBool // virtual memory enable
|
||||||
|
|
||||||
// extract fields from PT permission bits
|
// extract fields from PT permission bits
|
||||||
// val ptw_perm_ux = io.ptw.resp_perm(0);
|
|
||||||
val ptw_perm_ur = io.ptw.resp_perm(1);
|
val ptw_perm_ur = io.ptw.resp_perm(1);
|
||||||
val ptw_perm_uw = io.ptw.resp_perm(2);
|
val ptw_perm_uw = io.ptw.resp_perm(2);
|
||||||
// val ptw_perm_sx = io.ptw.resp_perm(3);
|
|
||||||
val ptw_perm_sr = io.ptw.resp_perm(4);
|
val ptw_perm_sr = io.ptw.resp_perm(4);
|
||||||
val ptw_perm_sw = io.ptw.resp_perm(5);
|
val ptw_perm_sw = io.ptw.resp_perm(5);
|
||||||
|
|
||||||
@ -135,11 +133,10 @@ class rocketDTLB(entries: Int) extends Component
|
|||||||
|
|
||||||
io.cpu.req_rdy := (state === s_ready);
|
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, tag_hit, io.cpu.req_val);
|
||||||
// io.cpu.resp_ppn := Mux(status_vm, io.cpu.req_vpn(PPN_BITS-1, 0), tag_ram(tag_hit_addr));
|
|
||||||
io.cpu.resp_addr :=
|
io.cpu.resp_addr :=
|
||||||
Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx),
|
Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx),
|
||||||
io.cpu.req_addr(PADDR_BITS-1,0)).toUFix;
|
io.cpu.req_addr(PADDR_BITS-1,0)).toUFix;
|
||||||
io.cpu.exception := dtlb_exception;
|
io.cpu.exception := status_vm && dtlb_exception;
|
||||||
|
|
||||||
io.ptw.req_val := (state === s_request);
|
io.ptw.req_val := (state === s_request);
|
||||||
io.ptw.req_vpn := r_refill_tag(VPN_BITS-1,0);
|
io.ptw.req_vpn := r_refill_tag(VPN_BITS-1,0);
|
||||||
|
@ -62,11 +62,9 @@ class ioITLB_CPU(view: List[String] = null) extends Bundle(view)
|
|||||||
val req_val = Bool('input);
|
val req_val = Bool('input);
|
||||||
val req_rdy = Bool('output);
|
val req_rdy = Bool('output);
|
||||||
val req_asid = Bits(ASID_BITS, 'input);
|
val req_asid = Bits(ASID_BITS, 'input);
|
||||||
// val req_vpn = Bits(VPN_BITS, 'input);
|
|
||||||
val req_addr = UFix(VADDR_BITS, 'input);
|
val req_addr = UFix(VADDR_BITS, 'input);
|
||||||
// lookup responses
|
// lookup responses
|
||||||
val resp_val = Bool('output);
|
val resp_val = Bool('output);
|
||||||
// val resp_ppn = Bits(PPN_BITS, 'output);
|
|
||||||
val resp_addr = UFix(PADDR_BITS, 'output);
|
val resp_addr = UFix(PADDR_BITS, 'output);
|
||||||
val exception = Bool('output);
|
val exception = Bool('output);
|
||||||
}
|
}
|
||||||
@ -155,13 +153,12 @@ class rocketITLB(entries: Int) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
val itlb_exception =
|
val itlb_exception =
|
||||||
tag_hit &&
|
io.cpu.req_val && tag_hit &&
|
||||||
((status_mode && !sx_array(tag_hit_addr).toBool) ||
|
((status_mode && !sx_array(tag_hit_addr).toBool) ||
|
||||||
(!status_mode && !ux_array(tag_hit_addr).toBool));
|
(!status_mode && !ux_array(tag_hit_addr).toBool));
|
||||||
|
|
||||||
io.cpu.req_rdy := (state === s_ready);
|
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, tag_hit, io.cpu.req_val);
|
||||||
// io.cpu.resp_ppn := Mux(status_vm, io.cpu.req_vpn(PPN_BITS-1, 0), tag_ram(tag_hit_addr));
|
|
||||||
io.cpu.resp_addr :=
|
io.cpu.resp_addr :=
|
||||||
Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx),
|
Mux(status_vm, Cat(tag_ram(tag_hit_addr), req_idx),
|
||||||
io.cpu.req_addr(PADDR_BITS-1,0)).toUFix;
|
io.cpu.req_addr(PADDR_BITS-1,0)).toUFix;
|
||||||
|
@ -32,14 +32,15 @@ class rocketDmemArbiter extends Component
|
|||||||
|
|
||||||
io.ptw.resp_data := io.mem.resp_data;
|
io.ptw.resp_data := io.mem.resp_data;
|
||||||
io.cpu.resp_data := io.mem.resp_data;
|
io.cpu.resp_data := io.mem.resp_data;
|
||||||
io.cpu.resp_tag := io.mem.resp_tag;
|
// io.cpu.resp_tag := io.mem.resp_tag(11,0);
|
||||||
|
io.cpu.resp_tag := io.mem.resp_tag; // to get rid of warning, MSB of tag is ignored in dpath
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ioPTW extends Bundle
|
class ioPTW extends Bundle
|
||||||
{
|
{
|
||||||
val itlb = new ioTLB_PTW().flip();
|
val itlb = new ioTLB_PTW().flip();
|
||||||
// val dtlb = new ioTLB_PTW.flip();
|
val dtlb = new ioTLB_PTW().flip();
|
||||||
val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "req_addr", "resp_data", "resp_val")).flip();
|
val dmem = new ioDmem(List("req_val", "req_rdy", "req_cmd", "req_type", "req_addr", "resp_data", "resp_val")).flip();
|
||||||
val ptbr = UFix(PADDR_BITS, 'input);
|
val ptbr = UFix(PADDR_BITS, 'input);
|
||||||
}
|
}
|
||||||
@ -52,17 +53,31 @@ class rocketPTW extends Component
|
|||||||
val state = Reg(resetVal = s_ready);
|
val state = Reg(resetVal = s_ready);
|
||||||
|
|
||||||
val r_req_vpn = Reg(resetVal = Bits(0,VPN_BITS));
|
val r_req_vpn = Reg(resetVal = Bits(0,VPN_BITS));
|
||||||
|
val r_req_dest = Reg(resetVal = Bool(false)); // 0 = ITLB, 1 = DTLB
|
||||||
|
|
||||||
val req_addr = Reg(resetVal = UFix(0,PPN_BITS+PGIDX_BITS));
|
val req_addr = Reg(resetVal = UFix(0,PPN_BITS+PGIDX_BITS));
|
||||||
val r_resp_ppn = Reg(resetVal = Bits(0,PPN_BITS));
|
val r_resp_ppn = Reg(resetVal = Bits(0,PPN_BITS));
|
||||||
val r_resp_perm = Reg(resetVal = Bits(0,PERM_BITS));
|
val r_resp_perm = Reg(resetVal = Bits(0,PERM_BITS));
|
||||||
|
|
||||||
val vpn_idx = Mux(state === s_l2_wait, r_req_vpn(9,0), r_req_vpn(19,10));
|
val vpn_idx = Mux(state === s_l2_wait, r_req_vpn(9,0), r_req_vpn(19,10));
|
||||||
|
val req_val = io.itlb.req_val || io.dtlb.req_val;
|
||||||
|
|
||||||
when ((state === s_ready) && io.itlb.req_val) {
|
// give ITLB requests priority over DTLB requests
|
||||||
|
val req_itlb_val = io.itlb.req_val;
|
||||||
|
val req_dtlb_val = io.dtlb.req_val && !io.itlb.req_val;
|
||||||
|
|
||||||
|
when ((state === s_ready) && req_itlb_val) {
|
||||||
r_req_vpn <== io.itlb.req_vpn;
|
r_req_vpn <== io.itlb.req_vpn;
|
||||||
|
r_req_dest <== Bool(false);
|
||||||
req_addr <== Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.itlb.req_vpn(VPN_BITS-1,VPN_BITS-10)).toUFix;
|
req_addr <== Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.itlb.req_vpn(VPN_BITS-1,VPN_BITS-10)).toUFix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when ((state === s_ready) && req_dtlb_val) {
|
||||||
|
r_req_vpn <== io.dtlb.req_vpn;
|
||||||
|
r_req_dest <== Bool(true);
|
||||||
|
req_addr <== Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.dtlb.req_vpn(VPN_BITS-1,VPN_BITS-10)).toUFix;
|
||||||
|
}
|
||||||
|
|
||||||
when (io.dmem.resp_val) {
|
when (io.dmem.resp_val) {
|
||||||
req_addr <== Cat(io.dmem.resp_data(PADDR_BITS-1, PGIDX_BITS), vpn_idx).toUFix;
|
req_addr <== Cat(io.dmem.resp_data(PADDR_BITS-1, PGIDX_BITS), vpn_idx).toUFix;
|
||||||
r_resp_perm <== io.dmem.resp_data(9,4);
|
r_resp_perm <== io.dmem.resp_data(9,4);
|
||||||
@ -78,22 +93,33 @@ class rocketPTW extends Component
|
|||||||
io.dmem.req_type := MT_D;
|
io.dmem.req_type := MT_D;
|
||||||
io.dmem.req_addr := req_addr;
|
io.dmem.req_addr := req_addr;
|
||||||
|
|
||||||
io.itlb.req_rdy := (state === s_ready);
|
val resp_val = (state === s_done) || (state === s_l1_fake) || (state === s_l2_fake);
|
||||||
io.itlb.resp_val := (state === s_done) || (state === s_l1_fake) || (state === s_l2_fake);
|
val resp_err = (state === s_error);
|
||||||
io.itlb.resp_err := (state === s_error);
|
|
||||||
io.itlb.resp_perm := r_resp_perm;
|
|
||||||
io.itlb.resp_ppn :=
|
|
||||||
Mux(state === s_l1_fake, Cat(r_resp_ppn(PPN_BITS-1, PPN_BITS-7), r_req_vpn(VPN_BITS-11, 0)),
|
|
||||||
Mux(state === s_l2_fake, Cat(r_resp_ppn(PPN_BITS-1, PPN_BITS-17), r_req_vpn(VPN_BITS-21, 0)),
|
|
||||||
r_resp_ppn));
|
|
||||||
|
|
||||||
val resp_ptd = (io.dmem.resp_data(1,0) === Bits(1,2));
|
val resp_ptd = (io.dmem.resp_data(1,0) === Bits(1,2));
|
||||||
val resp_pte = (io.dmem.resp_data(1,0) === Bits(2,2));
|
val resp_pte = (io.dmem.resp_data(1,0) === Bits(2,2));
|
||||||
|
|
||||||
|
io.dtlb.req_rdy := (state === s_ready) && !io.itlb.req_val;
|
||||||
|
io.itlb.req_rdy := (state === s_ready);
|
||||||
|
io.dtlb.resp_val := r_req_dest && resp_val;
|
||||||
|
io.itlb.resp_val := !r_req_dest && resp_val;
|
||||||
|
io.dtlb.resp_err := r_req_dest && resp_err;
|
||||||
|
io.itlb.resp_err := !r_req_dest && resp_err;
|
||||||
|
io.dtlb.resp_perm := r_resp_perm;
|
||||||
|
io.itlb.resp_perm := r_resp_perm;
|
||||||
|
|
||||||
|
val resp_ppn =
|
||||||
|
Mux(state === s_l1_fake, Cat(r_resp_ppn(PPN_BITS-1, PPN_BITS-7), r_req_vpn(VPN_BITS-11, 0)),
|
||||||
|
Mux(state === s_l2_fake, Cat(r_resp_ppn(PPN_BITS-1, PPN_BITS-17), r_req_vpn(VPN_BITS-21, 0)),
|
||||||
|
r_resp_ppn));
|
||||||
|
|
||||||
|
io.dtlb.resp_ppn := resp_ppn;
|
||||||
|
io.itlb.resp_ppn := resp_ppn;
|
||||||
|
|
||||||
// control state machine
|
// control state machine
|
||||||
switch (state) {
|
switch (state) {
|
||||||
is (s_ready) {
|
is (s_ready) {
|
||||||
when (io.itlb.req_val) {
|
when (req_val) {
|
||||||
state <== s_l1_req;
|
state <== s_l1_req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user