refactor: 重构tlb

This commit is contained in:
Liphen 2024-01-13 13:13:31 +08:00
parent ff91db660f
commit 6ca4ffcd86
9 changed files with 77 additions and 123 deletions

View File

@ -12,9 +12,7 @@ import pipeline.execute._
import pipeline.memory._
import pipeline.writeback._
import ctrl._
import cache.mmu._
import cache.mmu.DTlb
import cache.mmu.ITlb
import icache.mmu.Tlb
class Core(implicit val cpuConfig: CpuConfig) extends Module {
val io = IO(new Bundle {
@ -37,16 +35,11 @@ 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 ITlb()).io
val dtlbL1 = Module(new DTlb()).io
val tlb = Module(new Tlb()).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
tlb.icache <> io.inst.tlb
tlb.dcache <> io.data.tlb
tlb.csr <> csr.tlb
ctrl.decodeUnit <> decodeUnit.ctrl
ctrl.executeUnit <> executeUnit.ctrl

View File

@ -179,7 +179,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
state === s_idle,
Mux(
io.cpu.en,
(cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.translation_ok),
(cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.l1_hit),
io.cpu.fence_i || fence
),
state =/= s_wait
@ -190,6 +190,8 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
io.cpu.rdata := Mux(state === s_wait, saved_rdata, data(bank_index)(select_way))
io.cpu.tlb.addr := io.cpu.addr
val bank_raddr = Mux(state === s_fence, dirty_index, Mux(use_next_addr, exe_index, replace_index))
val tag_raddr = Mux(state === s_fence, dirty_index, tag_rindex)
@ -221,7 +223,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
tag_compare_valid(i) :=
tag(i) === io.cpu.tlb.ptag && // tag相同
valid(replace_index)(i) && // cache行有效位为真
io.cpu.tlb.translation_ok // 页表有效
io.cpu.tlb.l1_hit // 页表有效
replace_wstrb(j)(i) := Mux(
tag_compare_valid(i) && io.cpu.en && io.cpu.wen.orR && !io.cpu.tlb.uncached && state === s_idle,
@ -288,7 +290,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
when(io.cpu.en) {
when(addr_err) {
acc_err := true.B
}.elsewhen(!io.cpu.tlb.translation_ok) {
}.elsewhen(!io.cpu.tlb.l1_hit) {
state := s_tlb_refill
}.elsewhen(io.cpu.tlb.uncached) {
when(io.cpu.wen.orR) {

View File

@ -109,7 +109,7 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
// * cache hit * //
val tag_compare_valid = VecInit(Seq.tabulate(nway)(i => tag(i) === io.cpu.tlb.ptag && valid(i)(replace_index)))
val cache_hit = tag_compare_valid.contains(true.B)
val cache_hit_available = cache_hit && io.cpu.tlb.translation_ok && !io.cpu.tlb.uncached
val cache_hit_available = cache_hit && io.cpu.tlb.l1_hit && !io.cpu.tlb.uncached
val select_way = tag_compare_valid(1) // 1路命中时值为10路命中时值为0 //TODO:支持更多路数
// 将一个 bank 中的指令分成 instFetchNum 每份 INST_WID bit
@ -187,6 +187,7 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
}
io.cpu.icache_stall := Mux(state === s_idle, (!cache_hit_available && io.cpu.req), state =/= s_wait)
io.cpu.tlb.addr := io.cpu.addr(0)
val ar = RegInit(0.U.asTypeOf(new AR()))
val arvalid = RegInit(false.B)
@ -212,7 +213,7 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
state := s_wait
rdata_in_wait(0).inst := 0.U
rdata_in_wait(0).valid := true.B
}.elsewhen(!io.cpu.tlb.translation_ok) {
}.elsewhen(!io.cpu.tlb.l1_hit) {
state := s_tlb_refill
}.elsewhen(io.cpu.tlb.uncached) {
state := s_uncached
@ -292,11 +293,7 @@ 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
}
}
is(s_tlb_refill) {}
}
// * fence * //

View File

@ -1,33 +0,0 @@
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, pageOffsetLen)
io.cache.paddr := Cat(io.cache.ptag, io.addr(pageOffsetLen - 1, 0))
}

View File

@ -1,40 +0,0 @@
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 HasTlbConst 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)
val itlb = RegInit(0.U.asTypeOf(tlbBundle))
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, pageOffsetLen))
io.cache.paddr := Cat(io.cache.ptag, io.addr(pageOffsetLen - 1, 0))
}

View File

@ -0,0 +1,55 @@
package icache.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 addr = Input(UInt(XLEN.W))
val uncached = Output(Bool())
val l1_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 addr = Input(UInt(XLEN.W))
val uncached = Output(Bool())
val l1_hit = Output(Bool())
val ptag = Output(UInt(cacheConfig.tagWidth.W))
val paddr = Output(UInt(PADDR_WID.W))
}
class Tlb extends Module with HasTlbConst with HasCSRConst {
val io = IO(new Bundle {
val icache = new Tlb_ICache()
val dcache = new Tlb_DCache()
val csr = Flipped(new CsrTlb())
})
val satp = WireInit(io.csr.satp)
val mode = WireInit(io.csr.mode)
val vm_enabled = (satp.asTypeOf(satpBundle).mode === 8.U) && (mode < ModeM)
val itlb = RegInit(0.U.asTypeOf(tlbBundle))
val l1_hit = itlb.asid === satp.asTypeOf(satpBundle).asid
io.icache.uncached := AddressSpace.isMMIO(io.icache.addr)
io.icache.l1_hit := !vm_enabled
io.icache.ptag := Mux(vm_enabled, DontCare, io.icache.addr(PADDR_WID - 1, pageOffsetLen))
io.icache.paddr := Cat(io.icache.ptag, io.icache.addr(pageOffsetLen - 1, 0))
io.dcache.uncached := AddressSpace.isMMIO(io.dcache.addr)
io.dcache.l1_hit := !vm_enabled
io.dcache.ptag := Mux(vm_enabled, DontCare, io.dcache.addr(PADDR_WID - 1, pageOffsetLen))
io.dcache.paddr := Cat(io.dcache.ptag, io.dcache.addr(pageOffsetLen - 1, 0))
}

View File

@ -1,22 +0,0 @@
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,7 +5,8 @@ import chisel3.util._
import cpu.defines._
import cpu.defines.Const._
import cpu.CpuConfig
import cache.mmu
import icache.mmu.Tlb_ICache
import icache.mmu.Tlb_DCache
class ExceptionInfo extends Bundle {
val exception = Vec(EXC_WID, Bool())
@ -121,7 +122,7 @@ class Cache_ICache(implicit val cpuConfig: CpuConfig) extends Bundle {
val icache_stall = Input(Bool()) // icache_stall
// tlb
val tlb = new mmu.Tlb_ICache()
val tlb = new Tlb_ICache()
}
// cpu to dcache
@ -140,7 +141,7 @@ class Cache_DCache extends Bundle {
val acc_err = Input(Bool())
val dcache_ready = Input(Bool())
val tlb = new mmu.Tlb_DCache()
val tlb = new Tlb_DCache()
}
// axi

View File

@ -439,7 +439,7 @@ TODO仿真结构
#[
#set enum(numbering: "a")
+ 选择需要实现的指令中的一条,按照你自己的理解,逐步介绍其数据通路设计的思路以及实现过程
+ 尝试自己绘制一幅属于自己的数据通路图。(注意:以后数据通路的添加都需要在该图上继续增加。因此打一个好的地基很重要,现在偷懒之后还是需要补的。
+ 尝试自己绘制一幅属于自己的数据通路图。(注意:以后数据通路的添加都需要在该图上继续增加,因此打一个好的地基很重要,现在偷懒之后还是需要补的!
+ TODO增加更多内容
]
@ -453,10 +453,11 @@ TODO仿真结构
= 思考与探索
+ RISC-V 指令集是定长指令集吗?(否,实现 C 拓展后会有压缩指令
+ RISC-V 指令集是定长指令集吗?(是变长指令集riscv-spec-20191213的第8页有详细描述
+ RV64 和 RV32 的 R 型运算指令是否有区别?(指令格式无区别,但运算数据的长度有区别)
+ SLT 和 SLTU 这类比较指令的实现是为了什么目的,比如是为了实现什么样的目标才有了这类指令?(方便实现大数计算的进位操作)
+ SLL、SRL 和 SRA 这三条指令在 src2 高 63 至 6 位不全为 0 的时候,指令的执行结果是什么?(手册规定只需要看 src2 低 6 位即可,高位忽略)
+ RISC-V 的运算指令有进行运算结果的溢出判断吗,为什么要这样设计?可以对比 MIPS 指令集进行说明(无溢出判断,相比 MIPS 少了 ADDU 等不判断溢出的指令,应该是为了节省指令编码空间,况且溢出判断可以用软件实现)
+ 为什么并不是所有的R型计算指令都有对应的字指令
+ 谈谈你在实验中碰到了哪些问题?又是如何解决的?
+ 请问差分测试框架只有这些debug信号就够了吗假如有的指令不写回通用寄存器堆呢这时框架又该如何发现问题即使是跳转指令或是访存指令当时未写回寄存器堆但仍然会影响之后的指令执行结果只是我们发现问题的时间晚了一些但不影响问题的发现
+ 谈谈你在实验中碰到了哪些问题?又是如何解决的?