Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

area(csr): fix intr NO bits and remove reg for waddr/wdata #3970

Merged
merged 2 commits into from
Dec 23, 2024
Merged
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
6 changes: 3 additions & 3 deletions src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Debug(implicit val p: Parameters) extends Module with HasXSParameter {
private val trapInfo = io.in.trapInfo
private val hasTrap = trapInfo.valid
private val trapIsInterrupt = trapInfo.bits.isInterrupt
private val intrVec = trapInfo.bits.intrVec
private val isDebugIntr = trapInfo.bits.isDebugIntr
private val trapVec = trapInfo.bits.trapVec
private val singleStep = trapInfo.bits.singleStep
private val trigger = io.in.trapInfo.bits.trigger
Expand Down Expand Up @@ -42,7 +42,7 @@ class Debug(implicit val p: Parameters) extends Module with HasXSParameter {
*/
// debug_intr
val hasIntr = hasTrap && trapIsInterrupt
val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG)
val hasDebugIntr = hasIntr && isDebugIntr

// debug_exception_ebreak
val hasExp = hasTrap && !trapIsInterrupt
Expand Down Expand Up @@ -144,7 +144,7 @@ class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter {
val in = Input(new Bundle {
val trapInfo = ValidIO(new Bundle {
val trapVec = UInt(64.W)
val intrVec = UInt(64.W)
val isDebugIntr = Bool()
val isInterrupt = Bool()
val singleStep = Bool()
val trigger = TriggerAction()
Expand Down
69 changes: 46 additions & 23 deletions src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -363,84 +363,106 @@ class InterruptFilter extends Module {
((Candidate123HighCandidate45 && iprioCandidate <= 255.U) || (Candidate123LowCandidate45 && Candidate4) || (Candidate123LowCandidate45 && Candidate5 && hvictl.IPRIOM.asBool)) -> iprioCandidate(7, 0),
))

val mIRVec = Mux(
val mIRVecTmp = Mux(
privState.isModeM && mstatusMIE || privState < PrivState.ModeM,
io.out.mtopi.IID.asUInt,
0.U
)

val hsIRVec = Mux(
val hsIRVecTmp = Mux(
privState.isModeHS && sstatusSIE || privState < PrivState.ModeHS,
io.out.stopi.IID.asUInt,
0.U
)

val vsIRVec = Mux(
val vsIRVecTmp = Mux(
privState.isModeVS && vsstatusSIE || privState < PrivState.ModeVS,
io.out.vstopi.IID.asUInt,
0.U
)

val mIRNotZero = mIRVec.orR
val hsIRNotZero = hsIRVec.orR
val vsIRNotZero = vsIRVec.orR
val mIRNotZero = mIRVecTmp.orR
val hsIRNotZero = hsIRVecTmp.orR
val vsIRNotZero = vsIRVecTmp.orR

val mIRVecOH = Mux(mIRNotZero, UIntToOH(mIRVec, 64), 0.U)
val hsIRVecOH = Mux(hsIRNotZero, UIntToOH(hsIRVec, 64), 0.U)
val vsIRVecOH = Mux(vsIRNotZero, UIntToOH(vsIRVec, 64), 0.U)
val irToHS = !mIRNotZero && hsIRNotZero
val irToVS = !mIRNotZero && !hsIRNotZero && vsIRNotZero

val vsMapHostIRVec = Cat((0 until vsIRVecOH.getWidth).map { num =>
val mIRVec = Mux(mIRNotZero, mIRVecTmp, 0.U)
val hsIRVec = Mux(irToHS, hsIRVecTmp, 0.U)
val vsIRVec = Mux(irToVS, UIntToOH(vsIRVecTmp, 64), 0.U)

val vsMapHostIRVecTmp = Cat((0 until vsIRVec.getWidth).map { num =>
// 2,6,10
if (InterruptNO.getVS.contains(num)) {
// 1,5,9
val sNum = num - 1
vsIRVecOH(sNum)
vsIRVec(sNum)
}
// 1,5,9
else if(InterruptNO.getHS.contains(num)) {
else if (InterruptNO.getHS.contains(num)) {
0.U(1.W)
}
else {
vsIRVecOH(num)
vsIRVec(num)
}
}.reverse)

val vsMapHostIRVec = OHToUInt(vsMapHostIRVecTmp)

dontTouch(vsMapHostIRVec)

val nmiVecTmp = Wire(Vec(64, Bool()))
nmiVecTmp.zipWithIndex.foreach { case (irq, i) =>
if (NonMaskableIRNO.interruptDefaultPrio.contains(i)) {
val higherIRSeq = NonMaskableIRNO.getIRQHigherThan(i)
irq := (
higherIRSeq.nonEmpty.B && Cat(higherIRSeq.map(num => !io.in.nmiVec(num))).andR ||
higherIRSeq.isEmpty.B
) && io.in.nmiVec(i)
dontTouch(irq)
} else
irq := false.B
}
val nmiVec = OHToUInt(nmiVecTmp)

// support debug interrupt
// support smrnmi when NMIE is 0, all interrupt disable
val disableDebugIntr = io.in.debugMode || (io.in.dcsr.STEP.asBool && !io.in.dcsr.STEPIE.asBool)
val enableDebugIntr = io.in.debugIntr && !disableDebugIntr

val disableAllIntr = disableDebugIntr || !io.in.mnstatusNMIE
val debugInterupt = ((io.in.debugIntr && !disableDebugIntr) << CSRConst.IRQ_DEBUG).asUInt

val normalIntrVec = Mux(mIRNotZero, mIRVecOH,
Mux(hsIRNotZero, hsIRVecOH,
Mux(vsIRNotZero, vsMapHostIRVec, 0.U)))
val intrVec = VecInit(Mux(io.in.nmi, io.in.nmiVec, normalIntrVec).asBools.map(IR => IR && !disableAllIntr)).asUInt | debugInterupt
val normalIntrVec = mIRVec | hsIRVec | vsMapHostIRVec
val intrVec = Mux(disableAllIntr, 0.U, Mux(io.in.nmi, nmiVec, normalIntrVec))

// virtual interrupt with hvictl injection
val vsIRModeCond = privState.isModeVS && vsstatusSIE || privState < PrivState.ModeVS
val SelectCandidate5 = Candidate123LowCandidate45 && Candidate5
// delay at least 6 cycles to maintain the atomic of sret/mret
// 65bit indict current interrupt is NMI
val intrVecReg = RegInit(0.U(64.W))
val intrVecReg = RegInit(0.U(8.W))
val debugIntrReg = RegInit(false.B)
val nmiReg = RegInit(false.B)
val viIsHvictlInjectReg = RegInit(false.B)
val irToHSReg = RegInit(false.B)
val irToVSReg = RegInit(false.B)
intrVecReg := intrVec
debugIntrReg := enableDebugIntr
nmiReg := io.in.nmi
viIsHvictlInjectReg := vsIRModeCond && SelectCandidate5
irToHSReg := !mIRNotZero && hsIRNotZero
irToVSReg := !mIRNotZero && !hsIRNotZero && vsIRNotZero
irToHSReg := irToHS
irToVSReg := irToVS
val delayedIntrVec = DelayN(intrVecReg, 5)
val delayedDebugIntr = DelayN(debugIntrReg, 5)
val delayedNMI = DelayN(nmiReg, 5)
val delayedVIIsHvictlInjectReg = DelayN(viIsHvictlInjectReg, 5)
val delayedIRToHS = DelayN(irToHSReg, 5)
val delayedIRToVS = DelayN(irToVSReg, 5)

io.out.interruptVec.valid := delayedIntrVec.orR || delayedVIIsHvictlInjectReg
io.out.interruptVec.valid := delayedIntrVec.orR || delayedDebugIntr || delayedVIIsHvictlInjectReg
io.out.interruptVec.bits := delayedIntrVec
io.out.debug := delayedDebugIntr
io.out.nmi := delayedNMI
io.out.virtualInterruptIsHvictlInject := delayedVIIsHvictlInjectReg & !delayedNMI
io.out.irToHS := delayedIRToHS & !delayedNMI
Expand Down Expand Up @@ -489,8 +511,9 @@ class InterruptFilterIO extends Bundle {
})

val out = Output(new Bundle {
val debug = Bool()
val nmi = Bool()
val interruptVec = ValidIO(UInt(64.W))
val interruptVec = ValidIO(UInt(8.W))
val mtopi = new TopIBundle
val stopi = new TopIBundle
val vstopi = new TopIBundle
Expand Down
44 changes: 20 additions & 24 deletions src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ class NewCSRInput(implicit p: Parameters) extends Bundle {
val ren = Bool()
val op = UInt(2.W)
val addr = UInt(12.W)
val waddrReg = UInt(12.W)
val src = UInt(64.W)
val wdata = UInt(64.W)
val mnret = Input(Bool())
Expand Down Expand Up @@ -243,13 +242,11 @@ class NewCSR(implicit val p: Parameters) extends Module
/* Alias of input signals */
val wen = io.in.bits.wen && valid
val addr = io.in.bits.addr
val wdata = io.in.bits.wdata

val ren = io.in.bits.ren && valid
val raddr = io.in.bits.addr

val waddrReg = io.in.bits.waddrReg
val wdataReg = io.in.bits.wdata

val hasTrap = io.fromRob.trap.valid
val trapVec = io.fromRob.trap.bits.trapVec
val trapPC = io.fromRob.trap.bits.pc
Expand Down Expand Up @@ -306,7 +303,6 @@ class NewCSR(implicit val p: Parameters) extends Module
val legalDret = permitMod.io.out.hasLegalDret

private val wenLegalReg = GatedValidRegNext(wenLegal)
private val isModeVSReg = GatedValidRegNext(isModeVS)

var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] =
machineLevelCSRMap ++
Expand Down Expand Up @@ -382,10 +378,11 @@ class NewCSR(implicit val p: Parameters) extends Module
intrMod.io.in.dcsr := dcsr.regOut

when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) {
nmip.NMI_31 := nmip.NMI_31 & !intrMod.io.out.interruptVec.bits(NonMaskableIRNO.NMI_31).asBool
nmip.NMI_43 := nmip.NMI_43 & !intrMod.io.out.interruptVec.bits(NonMaskableIRNO.NMI_43).asBool
nmip.NMI_31 := nmip.NMI_31 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_31)
nmip.NMI_43 := nmip.NMI_43 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_43)
}
val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid)
val debug = RegEnable(intrMod.io.out.debug, false.B, intrMod.io.out.interruptVec.valid)
val nmi = RegEnable(intrMod.io.out.nmi, false.B, intrMod.io.out.interruptVec.valid)
val virtualInterruptIsHvictlInject = RegEnable(intrMod.io.out.virtualInterruptIsHvictlInject, false.B, intrMod.io.out.interruptVec.valid)
val irToHS = RegEnable(intrMod.io.out.irToHS, false.B, intrMod.io.out.interruptVec.valid)
Expand Down Expand Up @@ -428,21 +425,20 @@ class NewCSR(implicit val p: Parameters) extends Module
pmpEntryMod.io.in.ren := ren
pmpEntryMod.io.in.wen := wenLegalReg
pmpEntryMod.io.in.addr := addr
pmpEntryMod.io.in.waddr := waddrReg
pmpEntryMod.io.in.wdata := wdataReg
pmpEntryMod.io.in.wdata := wdata

// Todo: all wen and wdata of CSRModule assigned in this for loop
for ((id, (wBundle, _)) <- csrRwMap) {
if (vsMapS.contains(id)) {
// VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U
wBundle.wen := wenLegalReg && ((isModeVSReg && waddrReg === vsMapS(id).U) || (!isModeVSReg && waddrReg === id.U))
wBundle.wdata := wdataReg
wBundle.wen := wenLegalReg && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U))
wBundle.wdata := wdata
} else if (sMapVS.contains(id)) {
wBundle.wen := wenLegalReg && !isModeVSReg && waddrReg === id.U
wBundle.wdata := wdataReg
wBundle.wen := wenLegalReg && !isModeVS && addr === id.U
wBundle.wdata := wdata
} else {
wBundle.wen := wenLegalReg && waddrReg === id.U
wBundle.wdata := wdataReg
wBundle.wen := wenLegalReg && addr === id.U
wBundle.wdata := wdata
}
}

Expand Down Expand Up @@ -503,23 +499,23 @@ class NewCSR(implicit val p: Parameters) extends Module

miregiprios.foreach { mod =>
mod.w.wen := mireg.w.wen && (miselect.regOut.ALL.asUInt === mod.addr.U)
mod.w.wdata := wdataReg
mod.w.wdata := wdata
}

siregiprios.foreach { mod =>
mod.w.wen := sireg.w.wen && (siselect.regOut.ALL.asUInt === mod.addr.U)
mod.w.wdata := wdataReg
mod.w.wdata := wdata
}

mhartid.hartid := this.io.fromTop.hartId

cfgs.zipWithIndex.foreach { case (mod, i) =>
mod.w.wen := wenLegalReg && (waddrReg === (0x3A0 + i / 8 * 2).U)
mod.w.wen := wenLegalReg && (addr === (0x3A0 + i / 8 * 2).U)
mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8))
}

pmpaddr.zipWithIndex.foreach{ case(mod, i) =>
mod.w.wen := wenLegalReg && (waddrReg === (0x3B0 + i).U)
mod.w.wen := wenLegalReg && (addr === (0x3B0 + i).U)
mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i)
}

Expand Down Expand Up @@ -868,7 +864,7 @@ class NewCSR(implicit val p: Parameters) extends Module
)

// flush
val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === waddrReg)).orR && wenLegalReg // write to satp will cause the pipeline be flushed
val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed

val floatStatusOnOff = mstatus.w.wen && (
mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off ||
Expand Down Expand Up @@ -1073,7 +1069,7 @@ class NewCSR(implicit val p: Parameters) extends Module
val debugMod = Module(new Debug)
debugMod.io.in.trapInfo.valid := hasTrap
debugMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt
debugMod.io.in.trapInfo.bits.intrVec := intrVec
debugMod.io.in.trapInfo.bits.isDebugIntr := debug
debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt
debugMod.io.in.trapInfo.bits.trigger := trigger
debugMod.io.in.trapInfo.bits.singleStep := singleStep
Expand All @@ -1087,7 +1083,7 @@ class NewCSR(implicit val p: Parameters) extends Module
debugMod.io.in.tdata2Selected := tdata2.rdata
debugMod.io.in.tdata1Update := tdata1Update
debugMod.io.in.tdata2Update := tdata2Update
debugMod.io.in.tdata1Wdata := wdataReg
debugMod.io.in.tdata1Wdata := wdata
debugMod.io.in.triggerCanRaiseBpExp := triggerCanRaiseBpExp

entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode
Expand All @@ -1112,9 +1108,9 @@ class NewCSR(implicit val p: Parameters) extends Module
}
tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => {
mod1.w.wen := tdata1Update && (tselect.rdata === idx.U)
mod1.w.wdata := wdataReg
mod1.w.wdata := wdata
mod2.w.wen := tdata2Update && (tselect.rdata === idx.U)
mod2.w.wdata := wdataReg
mod2.w.wdata := wdata
}}

triggerFrontendChange := debugMod.io.out.triggerFrontendChange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class PMPEntryHandleModule(implicit p: Parameters) extends PMPModule {
val ren = io.in.ren
val wen = io.in.wen
val addr = io.in.addr
val waddr = io.in.waddr
val wdata = io.in.wdata

val pmpMask = RegInit(VecInit(Seq.fill(p(PMParameKey).NumPMP)(0.U(PMPAddrBits.W))))
Expand All @@ -36,7 +35,7 @@ class PMPEntryHandleModule(implicit p: Parameters) extends PMPModule {
// write pmpCfg
val cfgVec = WireInit(VecInit(Seq.fill(8)(0.U.asTypeOf(new PMPCfgBundle))))
for (i <- 0 until (p(PMParameKey).NumPMP/8+1) by 2) {
when (wen && (waddr === (0x3A0 + i).U)) {
when (wen && (addr === (0x3A0 + i).U)) {
for (j <- cfgVec.indices) {
val cfgOldTmp = pmpEntry(8*i/2+j).cfg
val cfgNewTmp = Wire(new PMPCfgBundle)
Expand Down Expand Up @@ -65,7 +64,7 @@ class PMPEntryHandleModule(implicit p: Parameters) extends PMPModule {
pmpAddrW(i) := pmpEntry(i).addr.ADDRESS.asUInt
pmpAddrR(i) := pmpEntry(i).addr.ADDRESS.asUInt
// write pmpAddr
when (wen && (waddr === (0x3B0 + i).U)) {
when (wen && (addr === (0x3B0 + i).U)) {
if (i != (p(PMParameKey).NumPMP - 1)) {
val addrNextLocked: Bool = PMPCfgLField.addrLocked(pmpEntry(i).cfg, pmpEntry(i + 1).cfg)
pmpMask(i) := Mux(!addrNextLocked, pmpEntry(i).matchMask(wdata), pmpEntry(i).mask)
Expand All @@ -92,7 +91,6 @@ class PMPEntryHandleIOBundle(implicit p: Parameters) extends PMPBundle {
val wen = Bool()
val ren = Bool()
val addr = UInt(12.W)
val waddr = UInt(12.W)
val wdata = UInt(64.W)
val pmpCfg = Vec(NumPMP, new PMPCfgBundle)
val pmpAddr = Vec(NumPMP, new PMPAddrBundle)
Expand Down
18 changes: 2 additions & 16 deletions src/main/scala/xiangshan/backend/fu/NewCSR/TrapHandleModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@ class TrapHandleModule extends Module {
private val irToHS = io.in.trapInfo.bits.irToHS
private val irToVS = io.in.trapInfo.bits.irToVS

private val highestPrioNMIVec = Wire(Vec(64, Bool()))
highestPrioNMIVec.zipWithIndex.foreach { case (irq, i) =>
if (NonMaskableIRNO.interruptDefaultPrio.contains(i)) {
val higherIRSeq = NonMaskableIRNO.getIRQHigherThan(i)
irq := (
higherIRSeq.nonEmpty.B && Cat(higherIRSeq.map(num => !hasIRVec(num))).andR ||
higherIRSeq.isEmpty.B
) && hasIRVec(i)
dontTouch(irq)
} else
irq := false.B
}

private val highestPrioEXVec = Wire(Vec(64, Bool()))
highestPrioEXVec.zipWithIndex.foreach { case (excp, i) =>
if (ExceptionNO.priorities.contains(i)) {
Expand All @@ -63,7 +50,6 @@ class TrapHandleModule extends Module {
}

private val highestPrioIR = hasIRVec.asUInt
private val highestPrioNMI = highestPrioNMIVec.asUInt
private val highestPrioEX = highestPrioEXVec.asUInt

private val mEXVec = highestPrioEX
Expand All @@ -89,7 +75,7 @@ class TrapHandleModule extends Module {

// Todo: support more interrupt and exception
private val exceptionRegular = OHToUInt(highestPrioEX)
private val interruptNO = OHToUInt(Mux(hasNMI, highestPrioNMI, highestPrioIR))
private val interruptNO = highestPrioIR
private val exceptionNO = Mux(trapInfo.bits.singleStep, ExceptionNO.breakPoint.U, exceptionRegular)

private val causeNO = Mux(hasIR, interruptNO, exceptionNO)
Expand Down Expand Up @@ -129,7 +115,7 @@ class TrapHandleIO extends Bundle {
val trapInfo = ValidIO(new Bundle {
val trapVec = UInt(64.W)
val nmi = Bool()
val intrVec = UInt(64.W)
val intrVec = UInt(8.W)
val isInterrupt = Bool()
val singleStep = Bool()
// trap to x mode
Expand Down
Loading
Loading