Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/scala/xiangshan/Parameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ case class XSCoreParameters
AsidLength: Int = 16,
SdidLength: Int = 6,
VmidLength: Int = 14,
EnbaleTlbDebug: Boolean = false,
EnableTlbDebug: Boolean = false,
EnableClockGate: Boolean = true,
EnableJal: Boolean = false,
EnableSv48: Boolean = true,
Expand Down Expand Up @@ -639,7 +639,7 @@ trait HasXSParameter {
def HasFPU = coreParams.HasFPU
def HasVPU = coreParams.HasVPU
def HasCustomCSRCacheOp = coreParams.HasCustomCSRCacheOp
def EnbaleTlbDebug = coreParams.EnbaleTlbDebug
def EnableTlbDebug = coreParams.EnableTlbDebug
def EnableCommitGHistDiff = coreParams.EnableCommitGHistDiff
def EnableClockGate = coreParams.EnableClockGate

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/xiangshan/backend/fu/CSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg)
val sieMask = "h222".U & mideleg
val sipMask = "h222".U & mideleg
val sipWMask = "h2".U(XLEN.W) // ssip is writeable in smode
val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
val satp = if(EnableTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W))
// val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug
// val satpMask = "h80000fffffffffff".U(XLEN.W) // disable asid, mode can only be 8 / 0
// TODO: use config to control the length of asid
Expand Down
104 changes: 61 additions & 43 deletions src/main/scala/xiangshan/cache/mmu/L2TLB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package xiangshan.cache.mmu

import org.chipsalliance.cde.config.Parameters
import chisel3._
import chisel3.experimental.ExtModule
import chisel3.util._
import xiangshan._
import xiangshan.cache.{HasDCacheParameters, MemoryOpConstants}
Expand Down Expand Up @@ -1118,16 +1117,6 @@ class BlockHelper(latency: Int)(implicit p: Parameters) extends XSModule {
}
}

class PTEHelper() extends ExtModule {
val clock = IO(Input(Clock()))
val enable = IO(Input(Bool()))
val satp = IO(Input(UInt(64.W)))
val vpn = IO(Input(UInt(64.W)))
val pte = IO(Output(UInt(64.W)))
val level = IO(Output(UInt(8.W)))
val pf = IO(Output(UInt(8.W)))
}

class PTWDelayN[T <: Data](gen: T, n: Int, flush: Bool) extends Module {
val io = IO(new Bundle() {
val in = Input(gen)
Expand All @@ -1138,7 +1127,12 @@ class PTWDelayN[T <: Data](gen: T, n: Int, flush: Bool) extends Module {
val t = RegInit(VecInit(Seq.fill(n)(0.U.asTypeOf(gen))))
out(0) := io.in
if (n == 1) {
io.out := out(0)
when (io.ptwflush) {
out(0) := 0.U.asTypeOf(gen)
io.out := 0.U.asTypeOf(gen)
}.otherwise {
io.out := out(0)
}
} else {
when (io.ptwflush) {
for (i <- 0 until n) {
Expand All @@ -1165,48 +1159,73 @@ object PTWDelayN {
}
}

// FakePTW: Software PTW implementation using DPI-C PteHelper
// Used when coreParams.softPTW is enabled for debug/simulation
// Supports H-extension two-stage address translation
class FakePTW()(implicit p: Parameters) extends XSModule with HasPtwConst {
val io = IO(new L2TLBIO)

val flush = VecInit(Seq.fill(PtwWidth)(false.B))
flush(0) := DelayN(io.sfence.valid || io.csr.tlb.satp.changed || io.csr.tlb.vsatp.changed || io.csr.tlb.hgatp.changed || io.csr.tlb.priv.virt_changed, itlbParams.fenceDelay)
flush(1) := DelayN(io.sfence.valid || io.csr.tlb.satp.changed || io.csr.tlb.vsatp.changed || io.csr.tlb.hgatp.changed || io.csr.tlb.priv.virt_changed, ldtlbParams.fenceDelay)
val flushCond = io.sfence.valid ||
io.csr.tlb.satp.changed ||
io.csr.tlb.vsatp.changed ||
io.csr.tlb.hgatp.changed ||
io.csr.tlb.priv.virt_changed
flush(0) := DelayN(flushCond, itlbParams.fenceDelay)
flush(1) := DelayN(flushCond, ldtlbParams.fenceDelay)

for (i <- 0 until PtwWidth) {
val helper = Module(new PTEHelper())
val helper = Module(new PteHelper())
helper.clock := clock
helper.satp := io.csr.tlb.satp.ppn
helper.connectCsr(io.csr.tlb)

if (coreParams.softPTWDelay == 1) {
helper.enable := io.tlb(i).req(0).fire
helper.vpn := io.tlb(i).req(0).bits.vpn
helper.connectReq(
reqVpn = io.tlb(i).req(0).bits.vpn,
reqS2xlate = io.tlb(i).req(0).bits.s2xlate,
reqEnable = io.tlb(i).req(0).fire && !reset.asBool
)
} else {
helper.enable := PTWDelayN(io.tlb(i).req(0).fire, coreParams.softPTWDelay - 1, flush(i))
helper.vpn := PTWDelayN(io.tlb(i).req(0).bits.vpn, coreParams.softPTWDelay - 1, flush(i))
helper.connectReq(
reqVpn = PTWDelayN(io.tlb(i).req(0).bits.vpn, coreParams.softPTWDelay - 1, flush(i)),
reqS2xlate = PTWDelayN(io.tlb(i).req(0).bits.s2xlate, coreParams.softPTWDelay - 1, flush(i)),
reqEnable = PTWDelayN(io.tlb(i).req(0).fire, coreParams.softPTWDelay - 1, flush(i)) && !reset.asBool
)
}

val pte = helper.pte.asTypeOf(new PteBundle)
val level = helper.level
val pf = helper.pf
val helperResult = PteHelperResult.fromHelper(helper, helper.enable)
val vpnDelayed = PTWDelayN(io.tlb(i).req(0).bits.vpn, coreParams.softPTWDelay, flush(i))
val s2xlateReg = if (coreParams.softPTWDelay == 1) {
RegEnable(io.tlb(i).req(0).bits.s2xlate, io.tlb(i).req(0).fire)
} else {
PTWDelayN(io.tlb(i).req(0).bits.s2xlate, coreParams.softPTWDelay, flush(i))
}

// Request/response handshake logic
val empty = RegInit(true.B)
when (io.tlb(i).req(0).fire) {
when (flush(i)) {
empty := true.B
}.elsewhen (io.tlb(i).req(0).fire) {
empty := false.B
} .elsewhen (io.tlb(i).resp.fire || flush(i)) {
}.elsewhen (io.tlb(i).resp.fire) {
empty := true.B
}

io.tlb(i).req(0).ready := empty || io.tlb(i).resp.fire
io.tlb(i).req(0).ready := !flush(i) && (empty || io.tlb(i).resp.fire)
io.tlb(i).resp.valid := PTWDelayN(io.tlb(i).req(0).fire, coreParams.softPTWDelay, flush(i))
assert(!io.tlb(i).resp.valid || io.tlb(i).resp.ready)
io.tlb(i).resp.bits.s1.entry.tag := PTWDelayN(io.tlb(i).req(0).bits.vpn, coreParams.softPTWDelay, flush(i))
io.tlb(i).resp.bits.s1.entry.pbmt := pte.pbmt
io.tlb(i).resp.bits.s1.entry.ppn := pte.ppn
io.tlb(i).resp.bits.s1.entry.perm.map(_ := pte.getPerm())
io.tlb(i).resp.bits.s1.entry.level.map(_ := level)
io.tlb(i).resp.bits.s1.pf := pf
io.tlb(i).resp.bits.s1.af := DontCare // TODO: implement it
io.tlb(i).resp.bits.s1.entry.v := !pf
io.tlb(i).resp.bits.s1.entry.prefetch := DontCare
io.tlb(i).resp.bits.s1.entry.asid := io.csr.tlb.satp.asid

helperResult.fillS1Resp(
resp = io.tlb(i).resp.bits.s1,
vpn = vpnDelayed,
s2xlate = s2xlateReg,
asid = io.csr.tlb.satp.asid,
vsasid = io.csr.tlb.vsatp.asid,
vmid = io.csr.tlb.hgatp.vmid
)
helperResult.fillS2Resp(io.tlb(i).resp.bits.s2, vpnDelayed, s2xlateReg, io.csr.tlb.hgatp.vmid)
io.tlb(i).resp.bits.s2xlate := s2xlateReg
}
io.wfi.wfiSafe := true.B
}

class L2TLBWrapper()(implicit p: Parameters) extends LazyModule with HasXSParameter {
Expand All @@ -1221,13 +1240,12 @@ class L2TLBWrapper()(implicit p: Parameters) extends LazyModule with HasXSParame
class L2TLBWrapperImp(wrapper: LazyModule) extends LazyModuleImp(wrapper) with HasPerfEvents {
val io = IO(new L2TLBIO)
val perfEvents = if (useSoftPTW) {
val fake_ptw = Module(new FakePTW())
io <> fake_ptw.io
val fakePtw = Module(new FakePTW())
io <> fakePtw.io
Seq()
}
else {
io <> ptw.module.io
ptw.module.getPerfEvents
} else {
io <> ptw.module.io
ptw.module.getPerfEvents
}
generatePerfEvent()
}
Expand Down
30 changes: 30 additions & 0 deletions src/main/scala/xiangshan/cache/mmu/MMUBundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ class TlbPermBundle(implicit p: Parameters) extends TlbBundle {
this
}

def apply(pte: PteBundle, pf: Bool, af: Bool, entryValid: Bool) = {
this.pf := pf
this.af := af
this.v := entryValid
this.d := pte.perm.d
this.a := pte.perm.a
this.g := pte.perm.g
this.u := pte.perm.u
this.x := pte.perm.x
this.w := pte.perm.w
this.r := pte.perm.r

this
}

override def toPrintable: Printable = {
p"pf:${pf} af:${af} d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r} "
}
Expand Down Expand Up @@ -144,6 +159,21 @@ class TlbSectorPermBundle(implicit p: Parameters) extends TlbBundle {

this
}
def apply(pte: PteBundle, pf: Bool, af: Bool, entryValid: Bool) = {
this.pf := pf
this.af := af
this.v := entryValid
this.d := pte.perm.d
this.a := pte.perm.a
this.g := pte.perm.g
this.u := pte.perm.u
this.x := pte.perm.x
this.w := pte.perm.w
this.r := pte.perm.r

this
}

override def toPrintable: Printable = {
p"pf:${pf} af:${af} d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r} "
}
Expand Down
Loading
Loading