From e1f9dc2c1ffc59a86a50a28b7aa28ef283ccf825 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 3 May 2012 02:29:09 -0700 Subject: [PATCH] generalize page table walker also, don't instantiate vitlb when !HAVE_VEC --- rocket/src/main/scala/cpu.scala | 10 ++--- rocket/src/main/scala/ptw.scala | 68 +++++++++++--------------------- rocket/src/main/scala/util.scala | 9 +++-- 3 files changed, 34 insertions(+), 53 deletions(-) diff --git a/rocket/src/main/scala/cpu.scala b/rocket/src/main/scala/cpu.scala index dda9fc81..d1842e21 100644 --- a/rocket/src/main/scala/cpu.scala +++ b/rocket/src/main/scala/cpu.scala @@ -22,8 +22,7 @@ class rocketProc(resetSignal: Bool = null) extends Component(resetSignal) val dtlb = new rocketDTLB(DTLB_ENTRIES); val itlb = new rocketITLB(ITLB_ENTRIES); - val vitlb = new rocketITLB(VITLB_ENTRIES) - val ptw = new rocketPTW(); + val ptw = new rocketPTW(if (HAVE_VEC) 3 else 2) val arb = new rocketHellaCacheArbiter(DCACHE_PORTS) var vu: vu = null @@ -92,9 +91,8 @@ class rocketProc(resetSignal: Bool = null) extends Component(resetSignal) // 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) - ptw.io.dtlb <> dtlb.io.ptw; - ptw.io.itlb <> itlb.io.ptw; - ptw.io.vitlb <> vitlb.io.ptw + ptw.io.requestor(0) <> itlb.io.ptw + ptw.io.requestor(1) <> dtlb.io.ptw ptw.io.ptbr := dpath.io.ptbr; arb.io.requestor(DMEM_PTW) <> ptw.io.mem arb.io.mem <> io.dmem @@ -146,6 +144,8 @@ class rocketProc(resetSignal: Bool = null) extends Component(resetSignal) dpath.io.vec_ctrl <> ctrl.io.vec_dpath // hooking up vector I$ + val vitlb = new rocketITLB(VITLB_ENTRIES) + ptw.io.requestor(2) <> vitlb.io.ptw vitlb.io.cpu.invalidate := dpath.io.ptbr_wen vitlb.io.cpu.status := dpath.io.ctrl.status vitlb.io.cpu.req_val := vu.io.imem_req.valid diff --git a/rocket/src/main/scala/ptw.scala b/rocket/src/main/scala/ptw.scala index 8e5bd4b2..38364c85 100644 --- a/rocket/src/main/scala/ptw.scala +++ b/rocket/src/main/scala/ptw.scala @@ -71,18 +71,16 @@ class rocketHellaCacheArbiter(n: Int) extends Component } } -class ioPTW extends Bundle +class ioPTW(n: Int) extends Bundle { - val itlb = (new ioTLB_PTW).flip - val dtlb = (new ioTLB_PTW).flip - val vitlb = (new ioTLB_PTW).flip + val requestor = Vec(n) { new ioTLB_PTW }.flip val mem = new ioHellaCache val ptbr = UFix(PADDR_BITS, INPUT) } -class rocketPTW extends Component +class rocketPTW(n: Int) extends Component { - val io = new ioPTW + val io = new ioPTW(n) val levels = 3 val bitsPerLevel = VPN_BITS/levels @@ -101,29 +99,20 @@ class rocketPTW extends Component val vpn_idxs = (1 until levels).map(i => r_req_vpn((levels-i)*bitsPerLevel-1, (levels-i-1)*bitsPerLevel)) val vpn_idx = (2 until levels).foldRight(vpn_idxs(0))((i,j) => Mux(count === UFix(i-1), vpn_idxs(i-1), j)) - val req_val = io.itlb.req_val || io.dtlb.req_val || io.vitlb.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; - val req_vitlb_val = io.vitlb.req_val && !io.itlb.req_val && !io.dtlb.req_val - - when ((state === s_ready) && req_itlb_val) { - r_req_vpn := io.itlb.req_vpn; - r_req_dest := Bits(0) - req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.itlb.req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3)) + + val req_rdy = state === s_ready + var req_val = Bool(false) + for (r <- io.requestor) { + r.req_rdy := req_rdy && !req_val + req_val = req_val || r.req_val } + val req_dest = PriorityEncoder(io.requestor.map(_.req_val)) + val req_vpn = io.requestor.slice(0, n-1).foldRight(io.requestor(n-1).req_vpn)((r, v) => Mux(r.req_val, r.req_vpn, v)) - when ((state === s_ready) && req_dtlb_val) { - r_req_vpn := io.dtlb.req_vpn; - r_req_dest := Bits(1) - req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.dtlb.req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3)) - } - - when ((state === s_ready) && req_vitlb_val) { - r_req_vpn := io.vitlb.req_vpn; - r_req_dest := Bits(2) - req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.vitlb.req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3)) + when (state === s_ready && req_val) { + r_req_vpn := req_vpn + r_req_dest := req_dest + req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3)) } val dmem_resp_val = Reg(io.mem.resp.valid, resetVal = Bool(false)) @@ -145,26 +134,17 @@ class rocketPTW extends Component val resp_ptd = io.mem.resp.bits.data_subword(1,0) === Bits(1) val resp_pte = io.mem.resp.bits.data_subword(1,0) === Bits(2) - - io.itlb.req_rdy := (state === s_ready) - io.dtlb.req_rdy := (state === s_ready) && !io.itlb.req_val - io.vitlb.req_rdy := (state === s_ready) && !io.itlb.req_val && !io.dtlb.req_val - io.itlb.resp_val := r_req_dest === Bits(0) && resp_val - io.dtlb.resp_val := r_req_dest === Bits(1) && resp_val - io.vitlb.resp_val := r_req_dest === Bits(2) && resp_val - io.itlb.resp_err := r_req_dest === Bits(0) && resp_err - io.dtlb.resp_err := r_req_dest === Bits(1) && resp_err - io.vitlb.resp_err := r_req_dest === Bits(2) && resp_err - io.itlb.resp_perm := r_resp_perm - io.dtlb.resp_perm := r_resp_perm - io.vitlb.resp_perm:= r_resp_perm val resp_ppns = (0 until levels-1).map(i => Cat(r_resp_ppn(PPN_BITS-1, VPN_BITS-bitsPerLevel*(i+1)), r_req_vpn(VPN_BITS-1-bitsPerLevel*(i+1), 0))) val resp_ppn = (0 until levels-1).foldRight(r_resp_ppn)((i,j) => Mux(count === UFix(i), resp_ppns(i), j)) - - io.itlb.resp_ppn := resp_ppn; - io.dtlb.resp_ppn := resp_ppn; - io.vitlb.resp_ppn := resp_ppn; + + for (i <- 0 until io.requestor.size) { + val me = r_req_dest === UFix(i) + io.requestor(i).resp_val := resp_val && me + io.requestor(i).resp_err := resp_err && me + io.requestor(i).resp_perm := r_resp_perm + io.requestor(i).resp_ppn := resp_ppn + } // control state machine switch (state) { diff --git a/rocket/src/main/scala/util.scala b/rocket/src/main/scala/util.scala index 87d17c1f..d83ce82e 100644 --- a/rocket/src/main/scala/util.scala +++ b/rocket/src/main/scala/util.scala @@ -256,13 +256,14 @@ class LockingArbiter[T <: Data](n: Int)(data: => T) extends Component { object PriorityEncoder { - def apply(in: Bits): UFix = doApply(in, 0) - def doApply(in: Bits, n: Int = 0): UFix = { - if (n >= in.getWidth-1) + def doit(in: Seq[Bits], n: Int): UFix = { + if (n >= in.size-1) UFix(n) else - Mux(in(n), UFix(n), doApply(in, n+1)) + Mux(in(n), UFix(n), doit(in, n+1)) } + def apply(in: Seq[Bits]): UFix = doit(in, 0) + def apply(in: Bits): UFix = apply((0 until in.getWidth).map(in(_))) } object PriorityEncoderOH