增加tlb相关常量定义

This commit is contained in:
Liphen 2024-01-03 16:17:36 +08:00
parent 78ca79384e
commit eeb076b060
12 changed files with 183 additions and 118 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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 * //

View File

@ -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))
}

View File

@ -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("----------------------------------------")
}

View File

@ -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))
}

View File

@ -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("----------------------------------------")
}

View File

@ -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))))))
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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) :=