搭了下itlb的框架
This commit is contained in:
parent
6ca4ffcd86
commit
07490e0f13
|
@ -21,7 +21,8 @@ case class CpuConfig(
|
|||
val instFifoDepth: Int = 8, // 指令缓存深度
|
||||
val mulClockNum: Int = 2, // 乘法器的时钟周期数
|
||||
val divClockNum: Int = 8, // 除法器的时钟周期数
|
||||
val branchPredictor: String = "adaptive" // adaptive, global
|
||||
val branchPredictor: String = "adaptive", // adaptive, global
|
||||
val tlbEntries: Int = 16 // TLB的条目数
|
||||
)
|
||||
|
||||
/* BPU 的配置文件 */
|
||||
|
@ -29,11 +30,6 @@ 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 {
|
||||
|
|
|
@ -53,8 +53,8 @@ class CacheAXIInterface extends Module {
|
|||
ar_sel_lock := true.B
|
||||
ar_sel_val := ar_sel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
io.axi.ar.bits.id := Cat(0.U(3.W), ar_sel)
|
||||
io.axi.ar.bits.addr := Mux(ar_sel, io.dcache.ar.bits.addr, io.icache.ar.bits.addr)
|
||||
io.axi.ar.bits.len := Mux(ar_sel, io.dcache.ar.bits.len, io.icache.ar.bits.len)
|
||||
|
|
|
@ -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.l1_hit),
|
||||
(cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.hit),
|
||||
io.cpu.fence_i || fence
|
||||
),
|
||||
state =/= s_wait
|
||||
|
@ -223,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.l1_hit // 页表有效
|
||||
io.cpu.tlb.hit // 页表有效
|
||||
|
||||
replace_wstrb(j)(i) := Mux(
|
||||
tag_compare_valid(i) && io.cpu.en && io.cpu.wen.orR && !io.cpu.tlb.uncached && state === s_idle,
|
||||
|
@ -290,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.l1_hit) {
|
||||
}.elsewhen(!io.cpu.tlb.hit) {
|
||||
state := s_tlb_refill
|
||||
}.elsewhen(io.cpu.tlb.uncached) {
|
||||
when(io.cpu.wen.orR) {
|
||||
|
@ -482,6 +482,9 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
state := s_idle
|
||||
}
|
||||
}
|
||||
is(s_tlb_refill) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
println("----------------------------------------")
|
||||
|
|
|
@ -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.l1_hit && !io.cpu.tlb.uncached
|
||||
val cache_hit_available = cache_hit && io.cpu.tlb.hit && !io.cpu.tlb.uncached
|
||||
val select_way = tag_compare_valid(1) // 1路命中时值为1,0路命中时值为0 //TODO:支持更多路数
|
||||
|
||||
// 将一个 bank 中的指令分成 instFetchNum 份,每份 INST_WID bit
|
||||
|
@ -213,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.l1_hit) {
|
||||
}.elsewhen(!io.cpu.tlb.hit) {
|
||||
state := s_tlb_refill
|
||||
}.elsewhen(io.cpu.tlb.uncached) {
|
||||
state := s_uncached
|
||||
|
@ -293,7 +293,9 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
state := s_idle
|
||||
}
|
||||
}
|
||||
is(s_tlb_refill) {}
|
||||
is(s_tlb_refill) {
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
|
||||
// * fence * //
|
||||
|
|
|
@ -6,50 +6,216 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CacheConfig
|
||||
import cpu.pipeline.execute.CsrTlb
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Tlb_ICache extends Bundle {
|
||||
val cacheConfig = CacheConfig("icache")
|
||||
val addr = Input(UInt(XLEN.W))
|
||||
class Tlb_Cache extends Bundle with Sv39Const {
|
||||
val addr = Input(UInt(XLEN.W))
|
||||
val complete_single_request = Input(Bool())
|
||||
|
||||
val uncached = Output(Bool())
|
||||
val l1_hit = Output(Bool())
|
||||
val ptag = Output(UInt(cacheConfig.tagWidth.W))
|
||||
val paddr = Output(UInt(PADDR_WID.W))
|
||||
val uncached = Output(Bool())
|
||||
val hit = Output(Bool())
|
||||
val ptag = Output(UInt(cacheTagLen.W))
|
||||
val paddr = Output(UInt(PADDR_WID.W))
|
||||
val access_fault = Output(Bool())
|
||||
val page_fault = Output(Bool())
|
||||
}
|
||||
|
||||
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_Ptw extends Bundle with Sv39Const {
|
||||
val vpn = Decoupled(UInt(vpnLen.W))
|
||||
val pte = Flipped(Decoupled(new Bundle {
|
||||
val access_fault = Bool()
|
||||
val page_fault = Bool()
|
||||
val entry = pteBundle
|
||||
val addr = 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 icache = new Tlb_Cache()
|
||||
val dcache = new Tlb_Cache()
|
||||
val csr = Flipped(new CsrTlb())
|
||||
val ptw = new Tlb_Ptw()
|
||||
val fence_vma = Input(new Bundle {
|
||||
val src1 = UInt(XLEN.W)
|
||||
val src2 = UInt(XLEN.W)
|
||||
})
|
||||
})
|
||||
|
||||
val satp = WireInit(io.csr.satp)
|
||||
val mode = WireInit(io.csr.mode)
|
||||
val satp = io.csr.satp.asTypeOf(satpBundle)
|
||||
val mstatus = io.csr.mstatus.asTypeOf(new Mstatus)
|
||||
val mode = io.csr.mode
|
||||
// 当SUM=0时,S模式内存访问U模式可访问的页面(U=1)将出现故障。
|
||||
// 当SUM=1时,这些访问是允许的。当基于页面的虚拟内存不生效时,SUM无效。
|
||||
// 请注意,虽然SUM通常在不在S模式下执行时被忽略,但当MPRV=1和MPP=S时,SUM有效。
|
||||
val sum_valid = (mode === ModeS) || mstatus.mprv && mstatus.mpp === ModeS
|
||||
val sum = mstatus.sum
|
||||
// 当MXR=0时,只有标记为可读的页面(R=1)的加载才会成功。
|
||||
// 当MXR=1时,标记为可读或可执行的页面(R=1或X=1)的加载才会成功。
|
||||
// 当基于页面的虚拟内存无效时,MXR无效。
|
||||
val mxr = mstatus.mxr
|
||||
|
||||
val vm_enabled = (satp.asTypeOf(satpBundle).mode === 8.U) && (mode < ModeM)
|
||||
val itlb = RegInit(0.U.asTypeOf(tlbBundle))
|
||||
// 只有当satp.mode为8且当前模式低于M模式时,才启用虚拟内存
|
||||
val vm_enabled = (satp.mode === 8.U) && (mode < ModeM)
|
||||
|
||||
val l1_hit = itlb.asid === satp.asTypeOf(satpBundle).asid
|
||||
val itlb = RegInit(0.U.asTypeOf(tlbBundle))
|
||||
val dtlb = RegInit(0.U.asTypeOf(tlbBundle))
|
||||
val tlbl2 = RegInit(VecInit(Seq.fill(cpuConfig.tlbEntries)(0.U.asTypeOf(tlbBundle))))
|
||||
|
||||
val ivpn = io.icache.addr(VADDR_WID - 1, pageOffsetLen)
|
||||
val dvpn = io.dcache.addr(VADDR_WID - 1, pageOffsetLen)
|
||||
|
||||
// 当(VPN一致)且(ASID一致或PTE.G为1时)且(PTE.V为1)时,TLB命中
|
||||
val itlbl1_hit = itlb.vpn === ivpn &&
|
||||
(itlb.asid === satp.asid || itlb.flag.g) &&
|
||||
itlb.flag.v
|
||||
val dtlbl1_hit = dtlb.vpn === dvpn &&
|
||||
(dtlb.asid === satp.asid || dtlb.flag.g) &&
|
||||
dtlb.flag.v
|
||||
|
||||
val il2_hit_vec = VecInit(
|
||||
tlbl2.map(tlb =>
|
||||
tlb.vpn === ivpn &&
|
||||
(tlb.asid === satp.asid || tlb.flag.g) &&
|
||||
tlb.flag.v
|
||||
)
|
||||
)
|
||||
val dl2_hit_vec = VecInit(
|
||||
tlbl2.map(tlb =>
|
||||
tlb.vpn === dvpn &&
|
||||
(tlb.asid === satp.asid || tlb.flag.g) &&
|
||||
tlb.flag.v
|
||||
)
|
||||
)
|
||||
|
||||
val search_l1 :: search_l2 :: search_pte :: search_fault :: Nil = Enum(4)
|
||||
val immu_state = RegInit(search_l1)
|
||||
|
||||
// 使用随机的方法替换TLB条目
|
||||
val replace_index = new Counter(cpuConfig.tlbEntries)
|
||||
|
||||
val ipage_fault = RegInit(false.B)
|
||||
val dpage_fault = RegInit(false.B)
|
||||
val iaccess_fault = RegInit(false.B)
|
||||
val daccess_fault = RegInit(false.B)
|
||||
|
||||
io.icache.hit := false.B
|
||||
io.dcache.hit := false.B
|
||||
io.icache.access_fault := iaccess_fault
|
||||
io.dcache.access_fault := daccess_fault
|
||||
io.icache.page_fault := ipage_fault
|
||||
io.dcache.page_fault := dpage_fault
|
||||
|
||||
io.ptw.vpn.valid := false.B
|
||||
io.ptw.vpn.bits := DontCare
|
||||
io.ptw.pte.ready := true.B
|
||||
|
||||
// ptw的请求标志,0位为指令tlb请求,1位为数据tlb请求
|
||||
val req_ptw = WireInit(VecInit(Seq.fill(2)(false.B)))
|
||||
|
||||
val ar_sel_lock = RegInit(false.B)
|
||||
val ar_sel_val = RegInit(false.B)
|
||||
// 我们默认优先发送数据tlb的请求
|
||||
val ar_sel = Mux(ar_sel_lock, ar_sel_val, !req_ptw(0) && req_ptw(1))
|
||||
|
||||
when(io.ptw.vpn.valid) {
|
||||
when(io.ptw.vpn.ready) {
|
||||
ar_sel_lock := false.B
|
||||
}.otherwise {
|
||||
ar_sel_lock := true.B
|
||||
ar_sel_val := ar_sel
|
||||
}
|
||||
}
|
||||
|
||||
// 指令虚实地址转换
|
||||
switch(immu_state) {
|
||||
is(search_l1) {
|
||||
// TODO:在这里实现访问tlb的pma和pmp权限检查
|
||||
ipage_fault := false.B
|
||||
iaccess_fault := false.B
|
||||
when(!vm_enabled) {
|
||||
io.icache.hit := true.B
|
||||
}.elsewhen(itlbl1_hit) {
|
||||
// 在这里进行取指需要的所有的权限检查
|
||||
// 0. X位检查,只有可执行的页面才能取指
|
||||
// 1. M模式,不可能到这里,因为vm_enabled为false
|
||||
// 2. S模式,如果U位为1,需要检查SUM
|
||||
// 3. U模式,必须保证U位为1
|
||||
io.icache.hit := false.B // 只有权限检查通过后可以置为true
|
||||
when(!itlb.flag.x) {
|
||||
ipage_fault := true.B
|
||||
immu_state := search_fault
|
||||
}.elsewhen(mode === ModeS) {
|
||||
when(itlb.flag.u && sum === 0.U) {
|
||||
ipage_fault := true.B
|
||||
immu_state := search_fault
|
||||
}.otherwise {
|
||||
io.icache.hit := true.B
|
||||
}
|
||||
}.elsewhen(mode === ModeU) {
|
||||
when(!itlb.flag.u) {
|
||||
ipage_fault := true.B
|
||||
immu_state := search_fault
|
||||
}.otherwise {
|
||||
io.icache.hit := true.B
|
||||
}
|
||||
}
|
||||
}.otherwise {
|
||||
immu_state := search_l2
|
||||
}
|
||||
}
|
||||
is(search_l2) {
|
||||
when(il2_hit_vec.asUInt.orR) {
|
||||
immu_state := search_l1
|
||||
itlb := tlbl2(il2_hit_vec.indexWhere(_ === true.B))
|
||||
}.otherwise {
|
||||
req_ptw(0) := true.B
|
||||
when(ar_sel === 0.U) {
|
||||
io.ptw.vpn.valid := true.B
|
||||
io.ptw.vpn.bits := ivpn
|
||||
immu_state := search_pte
|
||||
}
|
||||
}
|
||||
}
|
||||
is(search_pte) {
|
||||
io.ptw.vpn.valid := true.B
|
||||
io.ptw.vpn.bits := ivpn
|
||||
when(io.ptw.pte.valid) {
|
||||
when(io.ptw.pte.bits.access_fault) {
|
||||
io.icache.access_fault := true.B
|
||||
immu_state := search_fault
|
||||
}.elsewhen(io.ptw.pte.bits.page_fault) {
|
||||
ipage_fault := true.B
|
||||
immu_state := search_fault
|
||||
}.otherwise {
|
||||
// 在内存中找寻到了页表,将其写入TLB
|
||||
val replace_entry = Wire(tlbBundle)
|
||||
replace_entry.vpn := ivpn
|
||||
replace_entry.asid := satp.asid
|
||||
replace_entry.flag := io.ptw.pte.bits.entry.flag
|
||||
replace_entry.ppn := io.ptw.pte.bits.entry.ppn
|
||||
replace_entry.pteaddr := io.ptw.pte.bits.addr
|
||||
tlbl2(replace_index.value) := replace_entry
|
||||
itlb := replace_entry
|
||||
immu_state := search_l1
|
||||
}
|
||||
}
|
||||
}
|
||||
is(search_fault) {
|
||||
when(io.icache.complete_single_request) {
|
||||
ipage_fault := false.B
|
||||
iaccess_fault := false.B
|
||||
immu_state := search_l1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.ptag := Mux(vm_enabled, itlb.ppn, 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.ptag := Mux(vm_enabled, dtlb.ppn, io.dcache.addr(PADDR_WID - 1, pageOffsetLen))
|
||||
io.dcache.paddr := Cat(io.dcache.ptag, io.dcache.addr(pageOffsetLen - 1, 0))
|
||||
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ import chisel3.util._
|
|||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import icache.mmu.Tlb_ICache
|
||||
import icache.mmu.Tlb_DCache
|
||||
import icache.mmu.Tlb_Cache
|
||||
|
||||
class ExceptionInfo extends Bundle {
|
||||
val exception = Vec(EXC_WID, Bool())
|
||||
|
@ -122,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 Tlb_Cache()
|
||||
}
|
||||
|
||||
// cpu to dcache
|
||||
|
@ -141,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 Tlb_Cache()
|
||||
}
|
||||
|
||||
// axi
|
||||
|
|
|
@ -5,24 +5,24 @@ import chisel3.util._
|
|||
import cpu.defines.Const._
|
||||
|
||||
class Mstatus extends Bundle {
|
||||
val sd = Output(UInt(1.W))
|
||||
val sd = Output(Bool())
|
||||
|
||||
val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null
|
||||
val sxl = if (XLEN == 64) Output(UInt(2.W)) else null
|
||||
val uxl = if (XLEN == 64) Output(UInt(2.W)) else null
|
||||
val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W))
|
||||
|
||||
val tsr = Output(UInt(1.W))
|
||||
val tw = Output(UInt(1.W))
|
||||
val tvm = Output(UInt(1.W))
|
||||
val mxr = Output(UInt(1.W))
|
||||
val sum = Output(UInt(1.W))
|
||||
val mprv = Output(UInt(1.W))
|
||||
val tsr = Output(Bool())
|
||||
val tw = Output(Bool())
|
||||
val tvm = Output(Bool())
|
||||
val mxr = Output(Bool())
|
||||
val sum = Output(Bool())
|
||||
val mprv = Output(Bool())
|
||||
val xs = Output(UInt(2.W))
|
||||
val fs = Output(UInt(2.W))
|
||||
val mpp = Output(UInt(2.W))
|
||||
val hpp = Output(UInt(2.W))
|
||||
val spp = Output(UInt(1.W))
|
||||
val spp = Output(Bool())
|
||||
val pie = new Priv
|
||||
val ie = new Priv
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import chisel3._
|
|||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CacheConfig
|
||||
import cpu.TLBConfig
|
||||
import cpu.CpuConfig
|
||||
|
||||
trait Sv39Const extends CoreParameter {
|
||||
val PAddrBits = PADDR_WID // 32
|
||||
|
@ -28,6 +28,9 @@ trait Sv39Const extends CoreParameter {
|
|||
val satpResLen = XLEN - ppnLen - satpModeLen - asidLen
|
||||
val pteResLen = XLEN - ppnLen - 2 - flagLen
|
||||
|
||||
val cacheTagLen = PADDR_WID - pageOffsetLen
|
||||
require(ppnLen == cacheTagLen)
|
||||
|
||||
def vaBundle = new Bundle {
|
||||
val vpn2 = UInt(vpn2Len.W)
|
||||
val vpn1 = UInt(vpn1Len.W)
|
||||
|
@ -112,50 +115,12 @@ trait Sv39Const extends CoreParameter {
|
|||
}
|
||||
|
||||
trait HasTlbConst extends Sv39Const {
|
||||
val tlbConfig = TLBConfig()
|
||||
|
||||
val maskLen = vpn0Len + vpn1Len // 18
|
||||
val metaLen = vpnLen + asidLen + maskLen + flagLen // 27 + 16 + 18 + 8 = 69, is asid necessary
|
||||
val dataLen = ppnLen + PAddrBits // 20 + 32 = 52
|
||||
val tlbLen = metaLen + dataLen
|
||||
val nway = tlbConfig.nway
|
||||
val nindex = tlbConfig.nindex
|
||||
val indexWid = log2Up(nindex)
|
||||
val tagWid = vpnLen - indexWid
|
||||
|
||||
def vaddrTlbBundle = new Bundle {
|
||||
val tag = UInt(tagWid.W)
|
||||
val index = UInt(indexWid.W)
|
||||
val off = UInt(pageOffsetLen.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 flag = flagBundle
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,9 @@ class CsrDecodeUnit extends Bundle {
|
|||
}
|
||||
|
||||
class CsrTlb extends Bundle {
|
||||
val satp = Output(UInt(XLEN.W))
|
||||
val mode = Output(Priv())
|
||||
val satp = Output(UInt(XLEN.W))
|
||||
val mstatus = Output(UInt(XLEN.W))
|
||||
val mode = Output(Priv())
|
||||
}
|
||||
|
||||
class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
|
||||
|
@ -415,6 +416,7 @@ class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
|
|||
|
||||
io.tlb.mode := mode
|
||||
io.tlb.satp := satp
|
||||
io.tlb.mstatus := mstatus
|
||||
io.decodeUnit.mode := mode
|
||||
io.executeUnit.out.ex := io.executeUnit.in.ex
|
||||
io.executeUnit.out.ex.exception(illegalInstr) :=
|
||||
|
|
|
@ -3,11 +3,12 @@ import circt.stage._
|
|||
|
||||
import cpu.pipeline.execute.Csr
|
||||
import cache.DCache
|
||||
import icache.mmu.Tlb
|
||||
|
||||
object TestMain extends App {
|
||||
implicit val cpuConfig = new CpuConfig()
|
||||
implicit val dCacheConfig = CacheConfig(cacheType = "dcache")
|
||||
def top = new DCache(dCacheConfig)
|
||||
def top = new Tlb
|
||||
val useMFC = false // use MLIR-based firrtl compiler
|
||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
if (useMFC) {
|
||||
|
|
Loading…
Reference in New Issue