tlb支持巨页
This commit is contained in:
parent
f182d9b1b1
commit
a99cf13f87
|
@ -2,7 +2,7 @@ package cpu
|
|||
|
||||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
import cpu.defines.Sv39Const
|
||||
import cpu.defines.HasTlbConst
|
||||
|
||||
case class CpuConfig(
|
||||
val build: Boolean = false, // 是否为build模式
|
||||
|
@ -32,7 +32,7 @@ case class BranchPredictorConfig(
|
|||
|
||||
case class CacheConfig(
|
||||
cacheType: String = "icache" // icache, dcache
|
||||
) extends Sv39Const {
|
||||
) extends HasTlbConst {
|
||||
// ==========================================================
|
||||
// | tag | index | offset |
|
||||
// | | | bank index | bank offset |
|
||||
|
|
|
@ -42,30 +42,30 @@ class CacheAXIInterface extends Module {
|
|||
|
||||
// mux ar {
|
||||
// we need to lock ar to avoid signals change during handshake
|
||||
val ar_sel_lock = RegInit(false.B)
|
||||
val ar_sel_val = RegInit(false.B)
|
||||
val ar_sel = Mux(ar_sel_lock, ar_sel_val, !io.icache.ar.valid && io.dcache.ar.valid)
|
||||
val ar_sel_lock = RegInit(false.B)
|
||||
val ar_sel_val = RegInit(false.B)
|
||||
val choose_dcache = Mux(ar_sel_lock, ar_sel_val, !io.icache.ar.valid && io.dcache.ar.valid)
|
||||
|
||||
when(io.axi.ar.valid) {
|
||||
when(io.axi.ar.ready) {
|
||||
ar_sel_lock := false.B
|
||||
}.otherwise {
|
||||
ar_sel_lock := true.B
|
||||
ar_sel_val := ar_sel
|
||||
ar_sel_val := choose_dcache
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
io.axi.ar.bits.size := Mux(ar_sel, io.dcache.ar.bits.size, io.icache.ar.bits.size)
|
||||
io.axi.ar.valid := Mux(ar_sel, io.dcache.ar.valid, io.icache.ar.valid)
|
||||
io.axi.ar.bits.id := Cat(0.U(3.W), choose_dcache)
|
||||
io.axi.ar.bits.addr := Mux(choose_dcache, io.dcache.ar.bits.addr, io.icache.ar.bits.addr)
|
||||
io.axi.ar.bits.len := Mux(choose_dcache, io.dcache.ar.bits.len, io.icache.ar.bits.len)
|
||||
io.axi.ar.bits.size := Mux(choose_dcache, io.dcache.ar.bits.size, io.icache.ar.bits.size)
|
||||
io.axi.ar.valid := Mux(choose_dcache, io.dcache.ar.valid, io.icache.ar.valid)
|
||||
io.axi.ar.bits.burst := 1.U
|
||||
io.axi.ar.bits.prot := 0.U
|
||||
io.axi.ar.bits.cache := 0.U
|
||||
io.axi.ar.bits.lock := 0.U
|
||||
io.icache.ar.ready := !ar_sel && io.axi.ar.ready
|
||||
io.dcache.ar.ready := ar_sel && io.axi.ar.ready
|
||||
io.icache.ar.ready := !choose_dcache && io.axi.ar.ready
|
||||
io.dcache.ar.ready := choose_dcache && io.axi.ar.ready
|
||||
// mux ar }
|
||||
|
||||
// mux r based on rid {
|
||||
|
|
|
@ -51,7 +51,7 @@ class WriteBufferUnit extends Bundle {
|
|||
val size = UInt(AXI_SIZE_WID.W)
|
||||
}
|
||||
|
||||
class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Module with Sv39Const with HasCSRConst {
|
||||
class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Module with HasTlbConst with HasCSRConst {
|
||||
val nway = cacheConfig.nway
|
||||
val nindex = cacheConfig.nindex
|
||||
val nbank = cacheConfig.nbank
|
||||
|
@ -69,6 +69,17 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
// TODO:目前的实现只保证了AXI_DATA_WID为XLEN的情况下的正确性
|
||||
require(AXI_DATA_WID == XLEN, "AXI_DATA_WID should be greater than XLEN")
|
||||
|
||||
def pAddr = new Bundle {
|
||||
val tag = UInt(ppnLen.W)
|
||||
val index = UInt(indexWidth.W)
|
||||
val offset = UInt(offsetWidth.W)
|
||||
}
|
||||
|
||||
def bankAddr = new Bundle {
|
||||
val index = UInt(bankIndexWidth.W)
|
||||
val offset = UInt(bankOffsetWidth.W)
|
||||
}
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val cpu = Flipped(new Cache_DCache())
|
||||
val axi = new DCache_AXIInterface()
|
||||
|
@ -85,7 +96,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
// 临时寄存器
|
||||
val ptw_working = ptw_state =/= ptw_handshake && ptw_state =/= ptw_set
|
||||
val ptw_scratch = RegInit(0.U.asTypeOf(new Bundle {
|
||||
val paddr = cacheAddr
|
||||
val paddr = pAddr
|
||||
val replace = Bool()
|
||||
val dcache_wait = Bool()
|
||||
}))
|
||||
|
@ -99,17 +110,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
// | | | bank index | bank offset |
|
||||
// ==========================================================
|
||||
|
||||
def cacheAddr = new Bundle {
|
||||
val tag = UInt(tagWidth.W)
|
||||
val index = UInt(indexWidth.W)
|
||||
val offset = UInt(offsetWidth.W)
|
||||
}
|
||||
|
||||
def bankAddr = new Bundle {
|
||||
val index = UInt(bankIndexWidth.W)
|
||||
val offset = UInt(bankOffsetWidth.W)
|
||||
}
|
||||
|
||||
// exe级的index,用于访问第i行的数据
|
||||
val exe_index = io.cpu.exe_addr(indexWidth + offsetWidth - 1, offsetWidth)
|
||||
// mem级的bank的index,用于访问第i个bank的数据
|
||||
|
@ -219,7 +219,7 @@ 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
|
||||
io.cpu.tlb.vaddr := io.cpu.addr
|
||||
io.cpu.tlb.access_type := Mux(io.cpu.en && io.cpu.wen.orR, AccessType.store, AccessType.load)
|
||||
io.cpu.tlb.en := io.cpu.en
|
||||
|
||||
|
@ -357,7 +357,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
burst.wstrb(replace_way) := 1.U // 先写入第一块bank
|
||||
when(replace_dirty) {
|
||||
// cache行的脏位为真时需要写回,备份一下cache行,便于处理读写时序问题
|
||||
(0 until nbank).map(i => bank_replication(i) := data(i)(select_way))
|
||||
(0 until nbank).map(i => bank_replication(i) := data(i)(replace_way))
|
||||
}
|
||||
}.otherwise {
|
||||
when(io.cpu.dcache_ready) {
|
||||
|
@ -624,7 +624,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
(vpn_index === 2.U) -> vpn.vpn2
|
||||
)
|
||||
)
|
||||
val ptw_addr = paddrApply(ppn, vpnn).asTypeOf(cacheAddr)
|
||||
val ptw_addr = paddrApply(ppn, vpnn).asTypeOf(pAddr)
|
||||
val uncached = AddressSpace.isMMIO(ptw_addr.asUInt)
|
||||
when(uncached) {
|
||||
arvalid := true.B
|
||||
|
@ -679,12 +679,12 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
burst.wstrb(replace_way) := 1.U // 先写入第一块bank
|
||||
when(replace_dirty) {
|
||||
// cache行的脏位为真时需要写回,备份一下cache行,便于处理读写时序问题
|
||||
(0 until nbank).map(i => bank_replication(i) := data(i)(select_way))
|
||||
(0 until nbank).map(i => bank_replication(i) := data(i)(replace_way))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is(ptw_uncached) {
|
||||
is(ptw_uncached) { // 3
|
||||
when(io.axi.ar.fire) {
|
||||
arvalid := false.B
|
||||
}
|
||||
|
@ -711,7 +711,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
}
|
||||
}
|
||||
}
|
||||
is(ptw_check) {
|
||||
is(ptw_check) { // 4
|
||||
// 检查权限
|
||||
switch(access_type) {
|
||||
is(AccessType.load) {
|
||||
|
@ -745,11 +745,11 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
}
|
||||
}
|
||||
}
|
||||
is(ptw_set) {
|
||||
is(ptw_set) { // 5
|
||||
when(
|
||||
vpn_index > 0.U && (
|
||||
vpn_index === 1.U && pte.ppn(0) ||
|
||||
vpn_index === 2.U && pte.ppn(1, 0).orR
|
||||
vpn_index === 1.U && pte.ppn.asTypeOf(ppnBundle).ppn0.orR ||
|
||||
vpn_index === 2.U && (pte.ppn.asTypeOf(ppnBundle).ppn1.orR || pte.ppn.asTypeOf(ppnBundle).ppn0.orR)
|
||||
)
|
||||
) {
|
||||
raisePageFault()
|
||||
|
@ -757,18 +757,21 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
raisePageFault() // 使用软件的方式设置脏位以及访问位
|
||||
}.otherwise {
|
||||
// 翻译成功
|
||||
val rmask = WireInit(~0.U(maskLen.W))
|
||||
io.cpu.tlb.ptw.pte.valid := true.B
|
||||
io.cpu.tlb.ptw.pte.bits.addr := ar.addr
|
||||
io.cpu.tlb.ptw.pte.bits.rmask := rmask
|
||||
io.cpu.tlb.ptw.pte.bits.entry := pte
|
||||
val ppn_set = Wire(ppnBundle)
|
||||
when(vpn_index === 2.U) {
|
||||
ppn_set.ppn2 := pte.ppn.asTypeOf(ppnBundle).ppn2
|
||||
ppn_set.ppn1 := vpn.vpn1
|
||||
ppn_set.ppn0 := vpn.vpn0
|
||||
rmask := 0.U
|
||||
}.elsewhen(vpn_index === 1.U) {
|
||||
ppn_set.ppn2 := pte.ppn.asTypeOf(ppnBundle).ppn2
|
||||
ppn_set.ppn1 := pte.ppn.asTypeOf(ppnBundle).ppn1
|
||||
ppn_set.ppn0 := vpn.vpn0
|
||||
rmask := Cat(Fill(ppn1Len, true.B), 0.U(ppn0Len.W))
|
||||
}.otherwise {
|
||||
ppn_set := pte.ppn.asTypeOf(ppnBundle)
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ import cpu.defines.Const._
|
|||
=====================================
|
||||
*/
|
||||
|
||||
class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Module {
|
||||
class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Module with HasTlbConst {
|
||||
val nway = cacheConfig.nway
|
||||
val nindex = cacheConfig.nindex
|
||||
val nbank = cacheConfig.nbank
|
||||
|
@ -57,6 +57,18 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
|||
val indexWidth = cacheConfig.indexWidth
|
||||
val offsetWidth = cacheConfig.offsetWidth
|
||||
val bitsPerBank = cacheConfig.bitsPerBank
|
||||
|
||||
def pAddr = new Bundle {
|
||||
val tag = UInt(ppnLen.W)
|
||||
val index = UInt(indexWidth.W)
|
||||
val offset = UInt(offsetWidth.W)
|
||||
}
|
||||
|
||||
def bankAddr = new Bundle {
|
||||
val index = UInt(bankIndexWidth.W)
|
||||
val offset = UInt(bankOffsetWidth.W)
|
||||
}
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val cpu = Flipped(new Cache_ICache())
|
||||
val axi = new ICache_AXIInterface()
|
||||
|
@ -188,7 +200,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)
|
||||
io.cpu.tlb.vaddr := io.cpu.addr(0)
|
||||
io.cpu.tlb.complete_single_request := io.cpu.complete_single_request
|
||||
io.cpu.tlb.en := io.cpu.req && (state === s_idle || state === s_tlb_refill)
|
||||
|
||||
|
|
|
@ -15,20 +15,20 @@ object AccessType {
|
|||
def store = "b10".U
|
||||
}
|
||||
|
||||
class Tlb_Ptw extends Bundle with Sv39Const {
|
||||
class Tlb_Ptw extends Bundle with HasTlbConst {
|
||||
val vpn = Decoupled(UInt(vpnLen.W))
|
||||
val access_type = Output(AccessType())
|
||||
val pte = Flipped(Decoupled(new Bundle {
|
||||
val access_fault = Bool()
|
||||
val page_fault = Bool()
|
||||
val entry = pteBundle
|
||||
val addr = UInt(PADDR_WID.W)
|
||||
val rmask = UInt(maskLen.W)
|
||||
}))
|
||||
}
|
||||
|
||||
class Tlb_ICache extends Bundle with Sv39Const {
|
||||
class Tlb_ICache extends Bundle with HasTlbConst {
|
||||
val en = Input(Bool())
|
||||
val addr = Input(UInt(XLEN.W))
|
||||
val vaddr = Input(UInt(XLEN.W))
|
||||
val complete_single_request = Input(Bool())
|
||||
|
||||
val uncached = Output(Bool())
|
||||
|
@ -76,27 +76,27 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
|||
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)
|
||||
val ivpn = io.icache.vaddr(VADDR_WID - 1, pageOffsetLen)
|
||||
val dvpn = io.dcache.vaddr(VADDR_WID - 1, pageOffsetLen)
|
||||
|
||||
// 当(VPN一致)且(ASID一致或PTE.G为1时)且(PTE.V为1)时,TLB命中
|
||||
val itlbl1_hit = itlb.vpn === ivpn &&
|
||||
val itlbl1_hit = vpnEq(itlb.rmask, ivpn, itlb.vpn) &&
|
||||
(itlb.asid === satp.asid || itlb.flag.g) &&
|
||||
itlb.flag.v
|
||||
val dtlbl1_hit = dtlb.vpn === dvpn &&
|
||||
val dtlbl1_hit = vpnEq(dtlb.rmask, dvpn, dtlb.vpn) &&
|
||||
(dtlb.asid === satp.asid || dtlb.flag.g) &&
|
||||
dtlb.flag.v
|
||||
|
||||
val il2_hit_vec = VecInit(
|
||||
tlbl2.map(tlb =>
|
||||
tlb.vpn === ivpn &&
|
||||
vpnEq(tlb.rmask, ivpn, tlb.vpn) &&
|
||||
(tlb.asid === satp.asid || tlb.flag.g) &&
|
||||
tlb.flag.v
|
||||
)
|
||||
)
|
||||
val dl2_hit_vec = VecInit(
|
||||
tlbl2.map(tlb =>
|
||||
tlb.vpn === dvpn &&
|
||||
vpnEq(tlb.rmask, dvpn, tlb.vpn) &&
|
||||
(tlb.asid === satp.asid || tlb.flag.g) &&
|
||||
tlb.flag.v
|
||||
)
|
||||
|
@ -243,7 +243,7 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
|||
replace_entry.asid := satp.asid
|
||||
replace_entry.flag := io.dcache.ptw.pte.bits.entry.flag
|
||||
replace_entry.ppn := io.dcache.ptw.pte.bits.entry.ppn
|
||||
replace_entry.pteaddr := io.dcache.ptw.pte.bits.addr
|
||||
replace_entry.rmask := io.dcache.ptw.pte.bits.rmask
|
||||
tlbl2(replace_index.value) := replace_entry
|
||||
itlb := replace_entry
|
||||
replace_index.inc()
|
||||
|
@ -343,7 +343,7 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
|||
replace_entry.asid := satp.asid
|
||||
replace_entry.flag := io.dcache.ptw.pte.bits.entry.flag
|
||||
replace_entry.ppn := io.dcache.ptw.pte.bits.entry.ppn
|
||||
replace_entry.pteaddr := io.dcache.ptw.pte.bits.addr
|
||||
replace_entry.rmask := io.dcache.ptw.pte.bits.rmask
|
||||
tlbl2(replace_index.value) := replace_entry
|
||||
dtlb := replace_entry
|
||||
replace_index.inc()
|
||||
|
@ -360,8 +360,8 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
|||
}
|
||||
}
|
||||
|
||||
val src1 = io.sfence_vma.src_info.src1_data
|
||||
val src2 = io.sfence_vma.src_info.src2_data
|
||||
val src1 = io.sfence_vma.src_info.src1_data(vpnLen - 1, 0)
|
||||
val src2 = io.sfence_vma.src_info.src2_data(asidLen - 1, 0)
|
||||
when(io.sfence_vma.valid) {
|
||||
when(!src1.orR && !src2.orR) {
|
||||
// 将所有tlb的有效位置为0
|
||||
|
@ -385,39 +385,42 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
|||
}
|
||||
}.elsewhen(src1.orR && !src2.orR) {
|
||||
// 将vpn一致的tlb的有效位置为0
|
||||
when(itlb.vpn === src1) {
|
||||
when(vpnEq(itlb.rmask, src1, itlb.vpn)) {
|
||||
itlb.flag.v := false.B
|
||||
}
|
||||
when(dtlb.vpn === src1) {
|
||||
when(vpnEq(dtlb.rmask, src1, dtlb.vpn)) {
|
||||
dtlb.flag.v := false.B
|
||||
}
|
||||
for (i <- 0 until cpuConfig.tlbEntries) {
|
||||
when(tlbl2(i).vpn === src1) {
|
||||
when(vpnEq(tlbl2(i).rmask, src1, tlbl2(i).vpn)) {
|
||||
tlbl2(i).flag.v := false.B
|
||||
}
|
||||
}
|
||||
}.elsewhen(src1.orR && src2.orR) {
|
||||
// 将asid一致的且vpn一致的tlb的有效位置为0,g为1的除外
|
||||
when(itlb.asid === src2 && itlb.vpn === src1 && !itlb.flag.g) {
|
||||
when(itlb.asid === src2 && vpnEq(itlb.rmask, src1, itlb.vpn) && !itlb.flag.g) {
|
||||
itlb.flag.v := false.B
|
||||
}
|
||||
when(dtlb.asid === src2 && dtlb.vpn === src1 && !dtlb.flag.g) {
|
||||
when(dtlb.asid === src2 && vpnEq(dtlb.rmask, src1, dtlb.vpn) && !dtlb.flag.g) {
|
||||
dtlb.flag.v := false.B
|
||||
}
|
||||
for (i <- 0 until cpuConfig.tlbEntries) {
|
||||
when(tlbl2(i).asid === src2 && tlbl2(i).vpn === src1 && !tlbl2(i).flag.g) {
|
||||
when(tlbl2(i).asid === src2 && vpnEq(tlbl2(i).rmask, src1, tlbl2(i).vpn) && !tlbl2(i).flag.g) {
|
||||
tlbl2(i).flag.v := false.B
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
io.icache.uncached := AddressSpace.isMMIO(io.icache.addr)
|
||||
io.icache.ptag := Mux(ivm_enabled, itlb.ppn, io.icache.addr(PADDR_WID - 1, pageOffsetLen))
|
||||
io.icache.paddr := Cat(io.icache.ptag, io.icache.addr(pageOffsetLen - 1, 0))
|
||||
val imasktag = maskTag(itlb.rmask, itlb.ppn, ivpn)
|
||||
val dmasktag = maskTag(dtlb.rmask, dtlb.ppn, dvpn)
|
||||
|
||||
io.dcache.uncached := AddressSpace.isMMIO(io.dcache.addr)
|
||||
io.dcache.ptag := Mux(dvm_enabled, dtlb.ppn, io.dcache.addr(PADDR_WID - 1, pageOffsetLen))
|
||||
io.dcache.paddr := Cat(io.dcache.ptag, io.dcache.addr(pageOffsetLen - 1, 0))
|
||||
io.icache.uncached := AddressSpace.isMMIO(io.icache.vaddr)
|
||||
io.icache.ptag := Mux(ivm_enabled, imasktag, ivpn)
|
||||
io.icache.paddr := Cat(io.icache.ptag, io.icache.vaddr(pageOffsetLen - 1, 0))
|
||||
|
||||
io.dcache.uncached := AddressSpace.isMMIO(io.dcache.vaddr)
|
||||
io.dcache.ptag := Mux(dvm_enabled, dmasktag, dvpn)
|
||||
io.dcache.paddr := Cat(io.dcache.ptag, io.dcache.vaddr(pageOffsetLen - 1, 0))
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import cpu.defines.Const._
|
|||
import cpu.CacheConfig
|
||||
import cpu.CpuConfig
|
||||
|
||||
trait Sv39Const extends CoreParameter {
|
||||
trait HasTlbConst extends CoreParameter {
|
||||
val PAddrBits = PADDR_WID // 32
|
||||
val level = 3
|
||||
val pageOffsetLen = 12 // 页面大小为4KB,对应的偏移量长度为12位
|
||||
|
@ -18,6 +18,7 @@ trait Sv39Const extends CoreParameter {
|
|||
val vpn1Len = 9
|
||||
val vpn0Len = 9
|
||||
val vpnLen = vpn2Len + vpn1Len + vpn0Len // 27
|
||||
val maskLen = ppn1Len + ppn0Len // 18
|
||||
|
||||
val satpLen = XLEN
|
||||
val satpModeLen = 4
|
||||
|
@ -31,21 +32,14 @@ trait Sv39Const extends CoreParameter {
|
|||
val cacheTagLen = PADDR_WID - pageOffsetLen // 32 - 12 = 20
|
||||
require(ppnLen == cacheTagLen)
|
||||
|
||||
def vaBundle = new Bundle {
|
||||
val vpn2 = UInt(vpn2Len.W)
|
||||
val vpn1 = UInt(vpn1Len.W)
|
||||
val vpn0 = UInt(vpn0Len.W)
|
||||
val offset = UInt(pageOffsetLen.W)
|
||||
def vpnEq(mask: UInt, vpn: UInt, tlbvpn: UInt) = {
|
||||
val fullmask = Cat(Fill(vpn2Len, true.B), mask)
|
||||
(vpn & fullmask) === (tlbvpn & fullmask)
|
||||
}
|
||||
|
||||
def vaBundle2 = new Bundle {
|
||||
val vpn = UInt(vpnLen.W)
|
||||
val offset = UInt(pageOffsetLen.W)
|
||||
}
|
||||
|
||||
def vaBundle3 = new Bundle {
|
||||
val vpn = UInt(vpnLen.W)
|
||||
val offset = UInt(pageOffsetLen.W)
|
||||
def maskTag(mask: UInt, ppn: UInt, vpn: UInt) = {
|
||||
val fullmask = Cat(Fill(ppn2Len, true.B), mask)
|
||||
(ppn & fullmask) | (vpn & ~fullmask)
|
||||
}
|
||||
|
||||
def vpnBundle = new Bundle {
|
||||
|
@ -54,18 +48,6 @@ trait Sv39Const extends CoreParameter {
|
|||
val vpn0 = UInt(vpn0Len.W)
|
||||
}
|
||||
|
||||
def paBundle = new Bundle {
|
||||
val ppn2 = UInt(ppn2Len.W)
|
||||
val ppn1 = UInt(ppn1Len.W)
|
||||
val ppn0 = UInt(ppn0Len.W)
|
||||
val offset = UInt(pageOffsetLen.W)
|
||||
}
|
||||
|
||||
def paBundle2 = new Bundle {
|
||||
val ppn = UInt(ppnLen.W)
|
||||
val offset = UInt(pageOffsetLen.W)
|
||||
}
|
||||
|
||||
def ppnBundle = new Bundle {
|
||||
val ppn2 = UInt(ppn2Len.W)
|
||||
val ppn1 = UInt(ppn1Len.W)
|
||||
|
@ -110,23 +92,11 @@ trait Sv39Const extends CoreParameter {
|
|||
val v = Bool()
|
||||
}
|
||||
|
||||
def maskPaddr(ppn: UInt, vaddr: UInt, mask: UInt) = {
|
||||
MaskData(vaddr, Cat(ppn, 0.U(pageOffsetLen.W)), Cat(Fill(ppn2Len, 1.U(1.W)), mask, 0.U(pageOffsetLen.W)))
|
||||
}
|
||||
|
||||
def MaskEQ(mask: UInt, pattern: UInt, vpn: UInt) = {
|
||||
(Cat("h1ff".U(vpn2Len.W), mask) & pattern) === (Cat("h1ff".U(vpn2Len.W), mask) & vpn)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trait HasTlbConst extends Sv39Const {
|
||||
def tlbBundle = new Bundle {
|
||||
val vpn = UInt(vpnLen.W)
|
||||
val asid = UInt(asidLen.W)
|
||||
val flag = flagBundle
|
||||
val ppn = UInt(ppnLen.W)
|
||||
val pteaddr = UInt(PAddrBits.W)
|
||||
val vpn = UInt(vpnLen.W)
|
||||
val asid = UInt(asidLen.W)
|
||||
val flag = flagBundle
|
||||
val ppn = UInt(ppnLen.W)
|
||||
val rmask = UInt(maskLen.W)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue