generalize page table walker
also, don't instantiate vitlb when !HAVE_VEC
This commit is contained in:
		@@ -22,8 +22,7 @@ class rocketProc(resetSignal: Bool = null) extends Component(resetSignal)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  val dtlb  = new rocketDTLB(DTLB_ENTRIES);
 | 
					  val dtlb  = new rocketDTLB(DTLB_ENTRIES);
 | 
				
			||||||
  val itlb  = new rocketITLB(ITLB_ENTRIES);
 | 
					  val itlb  = new rocketITLB(ITLB_ENTRIES);
 | 
				
			||||||
  val vitlb = new rocketITLB(VITLB_ENTRIES)
 | 
					  val ptw   = new rocketPTW(if (HAVE_VEC) 3 else 2)
 | 
				
			||||||
  val ptw   = new rocketPTW();
 | 
					 | 
				
			||||||
  val arb   = new rocketHellaCacheArbiter(DCACHE_PORTS)
 | 
					  val arb   = new rocketHellaCacheArbiter(DCACHE_PORTS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var vu: vu = null
 | 
					  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)
 | 
					  // 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.requestor(0)     <> itlb.io.ptw
 | 
				
			||||||
  ptw.io.itlb             <> itlb.io.ptw;
 | 
					  ptw.io.requestor(1)     <> dtlb.io.ptw
 | 
				
			||||||
  ptw.io.vitlb            <> vitlb.io.ptw
 | 
					 | 
				
			||||||
  ptw.io.ptbr             := dpath.io.ptbr;
 | 
					  ptw.io.ptbr             := dpath.io.ptbr;
 | 
				
			||||||
  arb.io.requestor(DMEM_PTW) <> ptw.io.mem
 | 
					  arb.io.requestor(DMEM_PTW) <> ptw.io.mem
 | 
				
			||||||
  arb.io.mem             <> io.dmem
 | 
					  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
 | 
					    dpath.io.vec_ctrl <> ctrl.io.vec_dpath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // hooking up vector I$
 | 
					    // 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.invalidate := dpath.io.ptbr_wen
 | 
				
			||||||
    vitlb.io.cpu.status     := dpath.io.ctrl.status
 | 
					    vitlb.io.cpu.status     := dpath.io.ctrl.status
 | 
				
			||||||
    vitlb.io.cpu.req_val    := vu.io.imem_req.valid  
 | 
					    vitlb.io.cpu.req_val    := vu.io.imem_req.valid  
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 requestor = Vec(n) { new ioTLB_PTW }.flip
 | 
				
			||||||
  val dtlb  = (new ioTLB_PTW).flip
 | 
					 | 
				
			||||||
  val vitlb = (new ioTLB_PTW).flip
 | 
					 | 
				
			||||||
  val mem   = new ioHellaCache
 | 
					  val mem   = new ioHellaCache
 | 
				
			||||||
  val ptbr  = UFix(PADDR_BITS, INPUT)
 | 
					  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 levels = 3
 | 
				
			||||||
  val bitsPerLevel = VPN_BITS/levels
 | 
					  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_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 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_rdy = state === s_ready
 | 
				
			||||||
  val req_itlb_val = io.itlb.req_val;
 | 
					  var req_val = Bool(false)
 | 
				
			||||||
  val req_dtlb_val = io.dtlb.req_val && !io.itlb.req_val;
 | 
					  for (r <- io.requestor) {
 | 
				
			||||||
  val req_vitlb_val = io.vitlb.req_val && !io.itlb.req_val && !io.dtlb.req_val
 | 
					    r.req_rdy := req_rdy && !req_val
 | 
				
			||||||
  
 | 
					    req_val = req_val || r.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_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) {
 | 
					  when (state === s_ready && req_val) {
 | 
				
			||||||
    r_req_vpn  := io.dtlb.req_vpn;
 | 
					    r_req_vpn := req_vpn
 | 
				
			||||||
    r_req_dest := Bits(1)
 | 
					    r_req_dest := req_dest
 | 
				
			||||||
    req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), io.dtlb.req_vpn(VPN_BITS-1,VPN_BITS-bitsPerLevel), Bits(0,3))
 | 
					    req_addr := Cat(io.ptbr(PADDR_BITS-1,PGIDX_BITS), 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))
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val dmem_resp_val = Reg(io.mem.resp.valid, resetVal = Bool(false))
 | 
					  val dmem_resp_val = Reg(io.mem.resp.valid, resetVal = Bool(false))
 | 
				
			||||||
@@ -146,25 +135,16 @@ class rocketPTW extends Component
 | 
				
			|||||||
  val resp_ptd = io.mem.resp.bits.data_subword(1,0) === Bits(1)
 | 
					  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)
 | 
					  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_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))
 | 
					  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;
 | 
					  for (i <- 0 until io.requestor.size) {
 | 
				
			||||||
  io.dtlb.resp_ppn  := resp_ppn;
 | 
					    val me = r_req_dest === UFix(i)
 | 
				
			||||||
  io.vitlb.resp_ppn := resp_ppn;
 | 
					    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
 | 
					  // control state machine
 | 
				
			||||||
  switch (state) {
 | 
					  switch (state) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -256,13 +256,14 @@ class LockingArbiter[T <: Data](n: Int)(data: => T) extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
object PriorityEncoder
 | 
					object PriorityEncoder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  def apply(in: Bits): UFix = doApply(in, 0)
 | 
					  def doit(in: Seq[Bits], n: Int): UFix = {
 | 
				
			||||||
  def doApply(in: Bits, n: Int = 0): UFix = {
 | 
					    if (n >= in.size-1)
 | 
				
			||||||
    if (n >= in.getWidth-1)
 | 
					 | 
				
			||||||
      UFix(n)
 | 
					      UFix(n)
 | 
				
			||||||
    else
 | 
					    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
 | 
					object PriorityEncoderOH
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user