From eeb076b060d79c94748a63105a34497488cdf747 Mon Sep 17 00:00:00 2001 From: Liphen Date: Wed, 3 Jan 2024 16:17:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0tlb=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chisel/playground/src/Core.scala | 8 ++- chisel/playground/src/CpuConfig.scala | 6 ++ chisel/playground/src/cache/DCache.scala | 26 ++----- chisel/playground/src/cache/ICache.scala | 32 ++++----- chisel/playground/src/cache/mmu/DTlb.scala | 33 +++++++++ chisel/playground/src/cache/mmu/DTlbL1.scala | 28 -------- chisel/playground/src/cache/mmu/ITlb.scala | 39 +++++++++++ chisel/playground/src/cache/mmu/ITlbL1.scala | 27 -------- chisel/playground/src/cache/mmu/TlbL2.scala | 22 ++++++ chisel/playground/src/defines/Bundles.scala | 5 +- .../playground/src/defines/TlbBundles.scala | 67 +++++++++++++------ .../src/pipeline/execute/fu/Csr.scala | 8 +++ 12 files changed, 183 insertions(+), 118 deletions(-) create mode 100644 chisel/playground/src/cache/mmu/DTlb.scala delete mode 100644 chisel/playground/src/cache/mmu/DTlbL1.scala create mode 100644 chisel/playground/src/cache/mmu/ITlb.scala delete mode 100644 chisel/playground/src/cache/mmu/ITlbL1.scala create mode 100644 chisel/playground/src/cache/mmu/TlbL2.scala diff --git a/chisel/playground/src/Core.scala b/chisel/playground/src/Core.scala index 19d095c..fbf9d7b 100644 --- a/chisel/playground/src/Core.scala +++ b/chisel/playground/src/Core.scala @@ -13,6 +13,8 @@ import pipeline.memory._ import pipeline.writeback._ import ctrl._ import cache.mmu._ +import cache.mmu.DTlb +import cache.mmu.ITlb class Core(implicit val cpuConfig: CpuConfig) extends Module { val io = IO(new Bundle { @@ -35,14 +37,16 @@ class Core(implicit val cpuConfig: CpuConfig) extends Module { val memoryUnit = Module(new MemoryUnit()).io val writeBackStage = Module(new WriteBackStage()).io val writeBackUnit = Module(new WriteBackUnit()).io - val itlbL1 = Module(new ITlbL1()).io - val dtlbL1 = Module(new DTlbL1()).io + val itlbL1 = Module(new ITlb()).io + val dtlbL1 = Module(new DTlb()).io itlbL1.addr := fetchUnit.iCache.pc itlbL1.cache <> io.inst.tlb + itlbL1.csr <> csr.tlb dtlbL1.addr := memoryUnit.dataMemory.out.addr dtlbL1.cache <> io.data.tlb + dtlbL1.csr <> csr.tlb ctrl.decoderUnit <> decoderUnit.ctrl ctrl.executeUnit <> executeUnit.ctrl diff --git a/chisel/playground/src/CpuConfig.scala b/chisel/playground/src/CpuConfig.scala index 01ba764..1571e8d 100644 --- a/chisel/playground/src/CpuConfig.scala +++ b/chisel/playground/src/CpuConfig.scala @@ -24,10 +24,16 @@ case class CpuConfig( val branchPredictor: String = "adaptive" // adaptive, global ) +/* BPU 的配置文件 */ case class BranchPredictorConfig( val bhtDepth: Int = 5, val phtDepth: Int = 6) +/* TLB L2 的配置文件 */ +case class TLBConfig( + nindex: Int = 16, + nway: Int = 2) + case class CacheConfig( cacheType: String = "icache" // icache, dcache ) extends Sv39Const { diff --git a/chisel/playground/src/cache/DCache.scala b/chisel/playground/src/cache/DCache.scala index 9913fb1..4b49170 100644 --- a/chisel/playground/src/cache/DCache.scala +++ b/chisel/playground/src/cache/DCache.scala @@ -74,8 +74,8 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo }) // * fsm * // - val s_idle :: s_uncached :: s_fence :: s_replace :: s_wait :: Nil = Enum(5) - val state = RegInit(s_idle) + val s_idle :: s_uncached :: s_fence :: s_replace :: s_wait :: s_tlb_refill :: Nil = Enum(6) + val state = RegInit(s_idle) // ========================================================== // | tag | index | offset | @@ -94,9 +94,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo // else // 0.U - val tlb_fill = RegInit(false.B) - io.cpu.tlb.fill := tlb_fill - // axi信号中size的宽度,对于cached段,size为3位 val cached_size = log2Ceil(AXI_DATA_WID / 8) val cached_len = (nbank - 1) @@ -150,7 +147,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo val bank_replication = RegInit(VecInit(Seq.fill(nbank)(0.U(XLEN.W)))) // 是否使用exe的地址进行提前访存 - val use_next_addr = (state === s_idle && !tlb_fill) || (state === s_wait) + val use_next_addr = (state === s_idle) || (state === s_wait) val do_replace = RegInit(false.B) // replace index 表示行的索引 val replace_index = io.cpu.addr(indexWidth + offsetWidth - 1, offsetWidth) @@ -179,7 +176,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo val select_way = tag_compare_valid(1) val dcache_stall = Mux( - state === s_idle && !tlb_fill, + state === s_idle, Mux( io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.translation_ok), @@ -227,7 +224,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo io.cpu.tlb.translation_ok // 页表有效 replace_wstrb(j)(i) := Mux( - tag_compare_valid(i) && io.cpu.en && io.cpu.wen.orR && !io.cpu.tlb.uncached && state === s_idle && !tlb_fill, + tag_compare_valid(i) && io.cpu.en && io.cpu.wen.orR && !io.cpu.tlb.uncached && state === s_idle, wstrb(j)(i), Fill(AXI_STRB_WID, burst.wstrb(i)(j)) ) @@ -288,20 +285,11 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo switch(state) { is(s_idle) { - when(tlb_fill) { - tlb_fill := false.B - when(!io.cpu.tlb.hit) { - state := s_wait - } - }.elsewhen(io.cpu.en) { + when(io.cpu.en) { when(addr_err) { acc_err := true.B }.elsewhen(!io.cpu.tlb.translation_ok) { - when(io.cpu.tlb.tlb1_ok) { - state := s_wait - }.otherwise { - tlb_fill := true.B - } + state := s_tlb_refill }.elsewhen(io.cpu.tlb.uncached) { when(io.cpu.wen.orR) { when(writeFifo.io.enq.ready) { diff --git a/chisel/playground/src/cache/ICache.scala b/chisel/playground/src/cache/ICache.scala index 71d1734..056c3e7 100644 --- a/chisel/playground/src/cache/ICache.scala +++ b/chisel/playground/src/cache/ICache.scala @@ -75,16 +75,15 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo val bank_index = io.cpu.addr(0)(offsetWidth - 1, bankOffsetWidth) val bank_offset = io.cpu.addr(0)(bankOffsetWidth - 1, log2Ceil(INST_WID / 8)) // PC低2位必定是0 - val tlb_fill = RegInit(false.B) // * fsm * // - val s_idle :: s_uncached :: s_replace :: s_wait :: s_fence :: Nil = Enum(5) - val state = RegInit(s_idle) + val s_idle :: s_uncached :: s_replace :: s_wait :: s_fence :: s_tlb_refill :: Nil = Enum(6) + val state = RegInit(s_idle) // nway 路,每路 nindex 行,每行 nbank 个 bank,每行的nbank共用一个valid val valid = RegInit(VecInit(Seq.fill(nway)(VecInit(Seq.fill(nindex)(false.B))))) // * should choose next addr * // - val use_next_addr = (state === s_idle && !tlb_fill) || (state === s_wait) + val use_next_addr = (state === s_idle) || (state === s_wait) // 读取一个cache条目中的所有bank行 val data = Wire(Vec(nway, Vec(nbank, Vec(instBlocksPerBank, UInt(AXI_DATA_WID.W))))) @@ -95,10 +94,6 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo val tag_wstrb = RegInit(VecInit(Seq.fill(nway)(false.B))) val tag_wdata = RegInit(0.U(tagWidth.W)) - // * itlb * // - when(tlb_fill) { tlb_fill := false.B } - io.cpu.tlb.fill := tlb_fill - // * lru * //// TODO:检查lru的正确性,增加可拓展性,目前只支持两路的cache val lru = RegInit(VecInit(Seq.fill(nindex)(false.B))) @@ -176,8 +171,8 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo } for { i <- 0 until instFetchNum } { - io.cpu.inst_valid(i) := Mux(state === s_idle && !tlb_fill, inst_valid(i), rdata_in_wait(i).valid) && io.cpu.req - io.cpu.inst(i) := Mux(state === s_idle && !tlb_fill, inst(i), rdata_in_wait(i).inst) + io.cpu.inst_valid(i) := Mux(state === s_idle, inst_valid(i), rdata_in_wait(i).valid) && io.cpu.req + io.cpu.inst(i) := Mux(state === s_idle, inst(i), rdata_in_wait(i).inst) } for { i <- 0 until nway } { @@ -191,7 +186,7 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo tagBram.io.wdata := tag_wdata } - io.cpu.icache_stall := Mux(state === s_idle && !tlb_fill, (!cache_hit_available && io.cpu.req), state =/= s_wait) + io.cpu.icache_stall := Mux(state === s_idle, (!cache_hit_available && io.cpu.req), state =/= s_wait) val ar = RegInit(0.U.asTypeOf(new AR())) val arvalid = RegInit(false.B) @@ -211,20 +206,14 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo switch(state) { is(s_idle) { - when(tlb_fill) { - when(!io.cpu.tlb.hit) { - state := s_wait - rdata_in_wait(0).inst := 0.U - rdata_in_wait(0).valid := true.B - } - }.elsewhen(io.cpu.req) { + when(io.cpu.req) { when(addr_err) { acc_err := true.B state := s_wait rdata_in_wait(0).inst := 0.U rdata_in_wait(0).valid := true.B }.elsewhen(!io.cpu.tlb.translation_ok) { - tlb_fill := true.B + state := s_tlb_refill }.elsewhen(io.cpu.tlb.uncached) { state := s_uncached ar.addr := io.cpu.tlb.paddr @@ -303,6 +292,11 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo state := s_idle } } + is(s_tlb_refill) { + when(io.cpu.tlb.hit_L2){ + state := s_idle + } + } } // * fence * // diff --git a/chisel/playground/src/cache/mmu/DTlb.scala b/chisel/playground/src/cache/mmu/DTlb.scala new file mode 100644 index 0000000..8a3d53a --- /dev/null +++ b/chisel/playground/src/cache/mmu/DTlb.scala @@ -0,0 +1,33 @@ +package cache.mmu + +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ +import cpu.CacheConfig +import cpu.pipeline.execute.CsrTlb + +class Tlb_DCache extends Bundle { + val cacheConfig = CacheConfig("dcache") + + val uncached = Output(Bool()) + val translation_ok = Output(Bool()) + val hit_L2 = Output(Bool()) + val ptag = Output(UInt(cacheConfig.tagWidth.W)) + val paddr = Output(UInt(PADDR_WID.W)) +} + +class DTlb extends Module with Sv39Const { + val io = IO(new Bundle { + val addr = Input(UInt(XLEN.W)) + val cache = new Tlb_DCache() + val csr = Flipped(new CsrTlb()) + }) + + io.cache.uncached := AddressSpace.isMMIO(io.addr) + io.cache.translation_ok := true.B + io.cache.hit_L2 := true.B + io.cache.ptag := io.addr(PADDR_WID - 1, offsetLen) + io.cache.paddr := Cat(io.cache.ptag, io.addr(offsetLen - 1, 0)) + +} diff --git a/chisel/playground/src/cache/mmu/DTlbL1.scala b/chisel/playground/src/cache/mmu/DTlbL1.scala deleted file mode 100644 index 285c02a..0000000 --- a/chisel/playground/src/cache/mmu/DTlbL1.scala +++ /dev/null @@ -1,28 +0,0 @@ -package cache.mmu - -import chisel3._ -import chisel3.util._ -import cpu.defines._ -import cpu.defines.Const._ -import cpu.CacheConfig - -class DTlbL1 extends Module { - val io = IO(new Bundle { - val cache = new Tlb_DCache() - val addr = Input(UInt(XLEN.W)) - }) - - val cacheConfig = CacheConfig("dcache") - - io.cache.uncached := AddressSpace.isMMIO(io.addr) - io.cache.translation_ok := true.B - io.cache.hit := true.B - io.cache.tlb1_ok := true.B - io.cache.ptag := io.addr(PADDR_WID - 1, cacheConfig.offsetWidth + cacheConfig.indexWidth) - io.cache.paddr := Cat(io.cache.ptag, io.addr(cacheConfig.offsetWidth + cacheConfig.indexWidth - 1, 0)) - - println("----------------------------------------") - println("DTlbL1") - println("tag from " + (PADDR_WID - 1) + " to " + (cacheConfig.offsetWidth + cacheConfig.indexWidth)) - println("----------------------------------------") -} diff --git a/chisel/playground/src/cache/mmu/ITlb.scala b/chisel/playground/src/cache/mmu/ITlb.scala new file mode 100644 index 0000000..b5dd13a --- /dev/null +++ b/chisel/playground/src/cache/mmu/ITlb.scala @@ -0,0 +1,39 @@ +package cache.mmu + +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ +import cpu.CacheConfig +import cpu.pipeline.execute.CsrTlb + +class Tlb_ICache extends Bundle { + val cacheConfig = CacheConfig("icache") + + val uncached = Output(Bool()) + val translation_ok = Output(Bool()) + val hit_L2 = Output(Bool()) + val ptag = Output(UInt(cacheConfig.tagWidth.W)) + val paddr = Output(UInt(PADDR_WID.W)) +} + +class ITlb extends Module with Sv39Const with HasCSRConst { + val io = IO(new Bundle { + val addr = Input(UInt(XLEN.W)) + val cache = new Tlb_ICache() + val csr = Flipped(new CsrTlb()) + // val tlbL2 = Flipped(new TlbL2_TlbL1()) + }) + + val satp = WireInit(io.csr.satp) + val mode = WireInit(io.csr.mode) + + val vm_enabled = (satp.asTypeOf(satpBundle).mode === 8.U) && (mode < ModeM) + + io.cache.uncached := AddressSpace.isMMIO(io.addr) + io.cache.translation_ok := !vm_enabled + io.cache.hit_L2 := true.B + io.cache.ptag := Mux(vm_enabled, DontCare, io.addr(PADDR_WID - 1, offsetLen)) + io.cache.paddr := Cat(io.cache.ptag, io.addr(offsetLen - 1, 0)) + +} diff --git a/chisel/playground/src/cache/mmu/ITlbL1.scala b/chisel/playground/src/cache/mmu/ITlbL1.scala deleted file mode 100644 index c2effbb..0000000 --- a/chisel/playground/src/cache/mmu/ITlbL1.scala +++ /dev/null @@ -1,27 +0,0 @@ -package cache.mmu - -import chisel3._ -import chisel3.util._ -import cpu.defines._ -import cpu.defines.Const._ -import cpu.CacheConfig - -class ITlbL1 extends Module { - val io = IO(new Bundle { - val addr = Input(UInt(XLEN.W)) - val cache = new Tlb_ICache() - }) - - val cacheConfig = CacheConfig("icache") - - io.cache.uncached := AddressSpace.isMMIO(io.addr) - io.cache.translation_ok := true.B - io.cache.hit := true.B - io.cache.ptag := io.addr(PADDR_WID - 1, cacheConfig.offsetWidth + cacheConfig.indexWidth) - io.cache.paddr := Cat(io.cache.ptag, io.addr(cacheConfig.offsetWidth + cacheConfig.indexWidth - 1, 0)) - - println("----------------------------------------") - println("ITlbL1") - println("tag from " + (PADDR_WID - 1) + " to " + (cacheConfig.offsetWidth + cacheConfig.indexWidth)) - println("----------------------------------------") -} diff --git a/chisel/playground/src/cache/mmu/TlbL2.scala b/chisel/playground/src/cache/mmu/TlbL2.scala new file mode 100644 index 0000000..8881637 --- /dev/null +++ b/chisel/playground/src/cache/mmu/TlbL2.scala @@ -0,0 +1,22 @@ +package cache.mmu + +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ +import cpu.TLBConfig + +class TlbL2_TlbL1 extends Bundle { + val page_fault = Output(Bool()) +} + +class TlbL2 extends Module with HasTlbConst { + val io = IO(new Bundle { + val itlb = new TlbL2_TlbL1() + val dtlb = new TlbL2_TlbL1() + }) + + // tlb l2 + val tlb = RegInit(VecInit(Seq.fill(nindex)(VecInit(Seq.fill(nway)(0.U.asTypeOf(tlbBundle)))))) + +} diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index 9bd1971..60ce5a4 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -5,6 +5,7 @@ import chisel3.util._ import cpu.defines._ import cpu.defines.Const._ import cpu.CpuConfig +import cache.mmu class ExceptionInfo extends Bundle { val exception = Vec(EXC_WID, Bool()) @@ -120,7 +121,7 @@ class Cache_ICache(implicit val cpuConfig: CpuConfig) extends Bundle { val icache_stall = Input(Bool()) // icache_stall // tlb - val tlb = new Tlb_ICache() + val tlb = new mmu.Tlb_ICache() } // cpu to dcache @@ -139,7 +140,7 @@ class Cache_DCache extends Bundle { val acc_err = Input(Bool()) val dcache_ready = Input(Bool()) - val tlb = new Tlb_DCache() + val tlb = new mmu.Tlb_DCache() } // axi diff --git a/chisel/playground/src/defines/TlbBundles.scala b/chisel/playground/src/defines/TlbBundles.scala index 6073292..7cc8eec 100644 --- a/chisel/playground/src/defines/TlbBundles.scala +++ b/chisel/playground/src/defines/TlbBundles.scala @@ -4,6 +4,7 @@ import chisel3._ import chisel3.util._ import cpu.defines.Const._ import cpu.CacheConfig +import cpu.TLBConfig trait Sv39Const extends CoreParameter { val PAddrBits = PADDR_WID @@ -114,27 +115,51 @@ trait Sv39Const extends CoreParameter { } -class Tlb_ICache extends Bundle { - val cacheConfig = CacheConfig("icache") +trait HasTlbConst extends Sv39Const { + val tlbConfig = TLBConfig() - val fill = Input(Bool()) - val uncached = Output(Bool()) + val maskLen = vpn0Len + vpn1Len // 18 + val metaLen = vpnLen + asidLen + maskLen + flagLen // 27 + 16 + 18 + 8 = 69, is asid necessary + val dataLen = ppnLen + PAddrBits // + val tlbLen = metaLen + dataLen + val nway = tlbConfig.nway + val nindex = tlbConfig.nindex + val indexWid = log2Up(nindex) + val tagWid = vpnLen - indexWid - val translation_ok = Output(Bool()) - val hit = Output(Bool()) - val ptag = Output(UInt(cacheConfig.tagWidth.W)) - val paddr = Output(UInt(PADDR_WID.W)) -} - -class Tlb_DCache extends Bundle { - val cacheConfig = CacheConfig("dcache") - - val fill = Input(Bool()) - val uncached = Output(Bool()) - val tlb1_ok = Output(Bool()) - - val translation_ok = Output(Bool()) - val hit = Output(Bool()) - val ptag = Output(UInt(cacheConfig.tagWidth.W)) - val paddr = Output(UInt(PADDR_WID.W)) + def vaddrTlbBundle = new Bundle { + val tag = UInt(tagWid.W) + val index = UInt(indexWid.W) + val off = UInt(offsetLen.W) + } + + def metaBundle = new Bundle { + val vpn = UInt(vpnLen.W) + val asid = UInt(asidLen.W) + val mask = UInt(maskLen.W) // to support super page + val flag = UInt(flagLen.W) + } + + def dataBundle = new Bundle { + val ppn = UInt(ppnLen.W) + val pteaddr = UInt(PAddrBits.W) // pte addr, used to write back pte when flag changes (flag.d, flag.v) + } + + def tlbBundle = new Bundle { + val vpn = UInt(vpnLen.W) + val asid = UInt(asidLen.W) + val mask = UInt(maskLen.W) + val flag = UInt(flagLen.W) + val ppn = UInt(ppnLen.W) + val pteaddr = UInt(PAddrBits.W) + } + + def tlbBundle2 = new Bundle { + val meta = UInt(metaLen.W) + val data = UInt(dataLen.W) + } + + def getIndex(vaddr: UInt): UInt = { + vaddr.asTypeOf(vaddrTlbBundle).index + } } diff --git a/chisel/playground/src/pipeline/execute/fu/Csr.scala b/chisel/playground/src/pipeline/execute/fu/Csr.scala index a63855c..fc4286c 100644 --- a/chisel/playground/src/pipeline/execute/fu/Csr.scala +++ b/chisel/playground/src/pipeline/execute/fu/Csr.scala @@ -47,12 +47,18 @@ class CsrDecoderUnit extends Bundle { val interrupt = Output(UInt(INT_WID.W)) } +class CsrTlb extends Bundle { + val satp = Output(UInt(XLEN.W)) + val mode = Output(Priv()) +} + class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst { val io = IO(new Bundle { val ext_int = Input(new ExtInterrupt()) val decoderUnit = new CsrDecoderUnit() val executeUnit = new CsrExecuteUnit() val memoryUnit = new CsrMemoryUnit() + val tlb = new CsrTlb() }) // 目前的csr只支持64位 @@ -407,6 +413,8 @@ class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst { ret_target := sepc(VADDR_WID - 1, 0) } + io.tlb.mode := mode + io.tlb.satp := satp io.decoderUnit.mode := mode io.executeUnit.out.ex := io.executeUnit.in.ex io.executeUnit.out.ex.exception(illegalInstr) :=