From 089033fc39919c2005084c5be468811ec0f64992 Mon Sep 17 00:00:00 2001 From: ZhangZifei <1773908404@qq.com> Date: Wed, 5 Aug 2020 22:57:04 +0800 Subject: [PATCH] TLB: try to connect TLB/PTW into outer module(still syntax bug) Current: itlb(not impl) in frontend dtlb in memend csr in backend ptw in XSCore(parallel with 'frontend/memend/backend') Next: move ptw into memend --- src/main/scala/xiangshan/XSCore.scala | 9 +++ .../scala/xiangshan/mem/MemPipeline.scala | 6 +- src/main/scala/xiangshan/mem/cache/dtlb.scala | 71 +++++++++++-------- src/main/scala/xiangshan/mem/cache/ptw.scala | 39 +++++----- 4 files changed, 72 insertions(+), 53 deletions(-) diff --git a/src/main/scala/xiangshan/XSCore.scala b/src/main/scala/xiangshan/XSCore.scala index ec1ee3415..a5bae80f1 100644 --- a/src/main/scala/xiangshan/XSCore.scala +++ b/src/main/scala/xiangshan/XSCore.scala @@ -220,9 +220,18 @@ class XSCore extends XSModule { val front = Module(new Frontend) val backend = Module(new Backend) val mem = Module(new Memend) + val ptw = Module(new PTW) front.io.backend <> backend.io.frontend mem.io.backend <> backend.io.mem + ptw.io.csr <> DontCare // TODO + ptw.io.mem <> DontCare // TODO + ptw.io.tlb(0) <> mem.io.tlb.ptw + ptw.io.tlb(1) <> DontCare + ptw.io.csr <> DontCare + mem.io.tlb.csr <> DontCare // TODO + mem.io.tlb.issQue <> DontCare // TODO + backend.io.memMMU.imem <> DontCare diff --git a/src/main/scala/xiangshan/mem/MemPipeline.scala b/src/main/scala/xiangshan/mem/MemPipeline.scala index 47becf350..c9ffa391e 100644 --- a/src/main/scala/xiangshan/mem/MemPipeline.scala +++ b/src/main/scala/xiangshan/mem/MemPipeline.scala @@ -30,6 +30,7 @@ class Memend extends XSModule { val io = IO(new Bundle{ val backend = new MemToBackendIO val dmem = new SimpleBusUC(userBits = (new DcacheUserBundle).getWidth) + val tlb = new TlbEndIO }) // io <> DontCare @@ -37,10 +38,11 @@ class Memend extends XSModule { val lsu = Module(new Lsu) val dcache = Module(new Dcache) // val mshq = Module(new MSHQ) - val dtlb = Module(new FakeDtlb) + // val dtlb = Module(new FakeDtlb) + val dtlb = Module(new DTLB) dcache.io := DontCare - dtlb.io := DontCare + dtlb.io.end <> io.tlb // mshq.io := DontCare lsu.io.ldin <> io.backend.ldin diff --git a/src/main/scala/xiangshan/mem/cache/dtlb.scala b/src/main/scala/xiangshan/mem/cache/dtlb.scala index 5fae639d5..ac123190a 100644 --- a/src/main/scala/xiangshan/mem/cache/dtlb.scala +++ b/src/main/scala/xiangshan/mem/cache/dtlb.scala @@ -176,16 +176,24 @@ class TlbCsrIO extends TlbBundle { val mxr = Bool() val sum = Bool() }) + val sfence = Valid(new Bundle { + val rs1 = Bool() + val rs2 = Bool() + val addr = UInt(VAddrBits.W) + }) } -class DtlbIO extends TlbBundle { - val lsu = new DtlbToLsuIO +class TlbEndIO extends TlbBundle { val ptw = new TlbPtwIO val issQue = new TlbIssQueIO - val sfence = Flipped(ValidIO(new SfenceBundle)) val csr = Flipped(new TlbCsrIO) } +class DtlbIO extends TlbBundle { + val lsu = new DtlbToLsuIO + val end = new TlbEndIO +} + class FakeDtlb extends TlbModule { val io = IO(new DtlbIO) // Dtlb has 4 ports: 2 for load, 2 for store @@ -201,15 +209,19 @@ class FakeDtlb extends TlbModule { class DTLB extends TlbModule { val io = IO(new DtlbIO) - val req = io.lsu.req - val resp = io.lsu.resp - val valid = req.map(_.valid) - val sfence = io.sfence - val satp = io.csr.satp - - val reqAddr = io.lsu.req.map(_.bits.vaddr.asTypeOf(vaBundle2)) - val cmd = io.lsu.req.map(_.bits.cmd) - + val req = io.lsu.req + val resp = io.lsu.resp + + val sfence = io.end.csr.sfence + val satp = io.end.csr.satp + val priv = io.end.csr.priv + val issQue = io.end.issQue + val ptw = io.end.ptw + + val reqAddr = req.map(_.bits.vaddr.asTypeOf(vaBundle2)) + val cmd = req.map(_.bits.cmd) + val valid = req.map(_.valid) + val v = RegInit(VecInit(Seq.fill(TlbEntrySize)(false.B)).asUInt) val entry = Reg(Vec(TlbEntrySize, new TlbEntry)) // val g = entry.map(_.perm.g) // g is not used, for asid is not used @@ -227,13 +239,13 @@ class DTLB extends TlbModule { // resp for(i <- 0 until TLBWidth) { - // io.lsu.req(i).ready := io.resp(i).ready // true.B // ValidIO - io.lsu.resp(i).valid := valid(i) && hit(i) - io.lsu.resp(i).bits.paddr := Cat(hitppn(i), reqAddr(i).off) - io.lsu.resp(i).bits.miss := ~hit(i) - io.lsu.resp(i).bits.excp.pf.ld := excp_tmp - io.lsu.resp(i).bits.excp.pf.st := excp_tmp - io.lsu.resp(i).bits.excp.pf.instr := excp_tmp + // req(i).ready := resp(i).ready // true.B // ValidIO + resp(i).valid := valid(i) && hit(i) + resp(i).bits.paddr := Cat(hitppn(i), reqAddr(i).off) + resp(i).bits.miss := ~hit(i) + resp(i).bits.excp.pf.ld := excp_tmp + resp(i).bits.excp.pf.st := excp_tmp + resp(i).bits.excp.pf.instr := excp_tmp } // sfence (flush) @@ -260,33 +272,32 @@ class DTLB extends TlbModule { switch (state) { is (state_idle) { for(i <- TLBWidth-1 to 0 by -1) { - when (!hit(i) && io.ptw.req.fire()) { + when (!hit(i) && ptw.req.fire()) { state := state_wait - io.ptw.req.valid := true.B - io.ptw.req.bits.vpn := reqAddr(i).vpn + ptw.req.valid := true.B + ptw.req.bits.vpn := reqAddr(i).vpn } - assert(!io.ptw.resp.valid) + assert(!ptw.resp.valid) } } is (state_wait) { - io.ptw.resp.ready := true.B - when (io.ptw.resp.fire()) { + ptw.resp.ready := true.B + when (ptw.resp.fire()) { state := state_idle } } } // refill - val ptwResp = io.ptw.resp - val refill = ptwResp.fire() + val refill = ptw.resp.fire() val refillIdx = LFSR64()(log2Up(TlbEntrySize)-1,0) when (refill) { v := v | (1.U << refillIdx) - entry(refillIdx) := ptwResp.bits + entry(refillIdx) := ptw.resp.bits } // issQue - io.issQue.miss := (~VecInit(hit).asUInt).asBools - io.issQue.missCanIss := io.ptw.resp.fire() // one cycle fire + issQue.miss := (~VecInit(hit).asUInt).asBools + issQue.missCanIss := ptw.resp.fire() // one cycle fire } diff --git a/src/main/scala/xiangshan/mem/cache/ptw.scala b/src/main/scala/xiangshan/mem/cache/ptw.scala index 9432e8689..eaeec4a53 100644 --- a/src/main/scala/xiangshan/mem/cache/ptw.scala +++ b/src/main/scala/xiangshan/mem/cache/ptw.scala @@ -69,19 +69,11 @@ class PtwResp extends PtwBundle { } class PtwIO extends PtwBundle { - val req = Vec(PtwWidth, Flipped(Decoupled(new PtwReq))) - val resp = Vec(PtwWidth, Decoupled(new PtwResp)) - val sfence = Flipped(ValidIO(new SfenceBundle)) + val tlb = Vec(PtwWidth, Flipped(new TlbPtwIO)) val csr = Flipped(new TlbCsrIO) val mem = new SimpleBusUC(addrBits = PAddrBits) // Use Dcache temp } -// class SeperateValidSyncReadMem extends Module { -// val io = - -// val ram = SyncReadMem() -// } - object ValidHold { def apply(infire: Bool, outfire: Bool, flush: Bool = false.B ) = { val valid = RegInit(false.B) @@ -107,17 +99,22 @@ class PTW extends PtwModule { // io <> DontCare - val arb = Module(new Arbiter(io.req(0).bits.cloneType, PtwWidth)) - arb.io.in <> io.req + val req_t = io.tlb.map(_.req) + val arb = Module(new Arbiter(req_t(0).bits.cloneType, PtwWidth)) + arb.io.in <> req_t val arbChosen = RegEnable(arb.io.chosen, arb.io.out.fire()) val req = RegEnable(arb.io.out.bits, arb.io.out.fire()) - val valid = ValidHold(arb.io.out.fire(), io.resp(arbChosen).fire()) + val resp = io.tlb.map(_.resp) + + val valid = ValidHold(arb.io.out.fire(), resp(arbChosen).fire()) val validOneCycle = OneCycleValid(arb.io.out.fire()) - arb.io.out.ready := !valid || io.resp(arbChosen).fire() + arb.io.out.ready := !valid || resp(arbChosen).fire() + + val mem = io.mem + val satp = io.csr.satp + val sfence = io.csr.sfence + val priv = io.csr.priv - val mem = io.mem - val csr = io.csr - val sfence = io.sfence val memRdata = mem.resp.bits.rdata // two level: l2-tlb-cache && pde/pte-cache @@ -154,7 +151,7 @@ class PTW extends PtwModule { } // ptwl1 - val l1addr = MakeAddr(csr.satp.ppn, getVpnn(req.vpn, 2)) + val l1addr = MakeAddr(satp.ppn, getVpnn(req.vpn, 2)) val (l1Hit, l1HitData) = { // TODO: add excp // 16 terms may casue long latency, so divide it into 2 stage, like l2tlb val hitVecT = ptwl1.map(_.hit(l1addr)) @@ -256,10 +253,10 @@ class PTW extends PtwModule { // resp val level = 0.U // FIXME for(i <- 0 until PtwWidth) { - io.resp(i).valid := valid && arbChosen===i.U && ((state === state_tlb && tlbHit) || - (state === state_wait3 && mem.resp.fire()))// TODO: add resp valid logic - io.resp(i).bits.tlb := Mux(state === state_tlb, tlbHitData, - new TlbEntry().genTlbEntry(memRdata, level, req.vpn)) + resp(i).valid := valid && arbChosen===i.U && ((state === state_tlb && tlbHit) || + (state === state_wait3 && mem.resp.fire()))// TODO: add resp valid logic + resp(i).bits.tlb := Mux(state === state_tlb, tlbHitData, + new TlbEntry().genTlbEntry(memRdata, level, req.vpn)) } // sfence -- GitLab