Skip to content

Commit

Permalink
area(csr): intr NO bits is reduced from 64 to 8
Browse files Browse the repository at this point in the history
  • Loading branch information
sinceforYy committed Dec 2, 2024
1 parent fcefab3 commit 83be9b9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 45 deletions.
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
7 changes: 4 additions & 3 deletions src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,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 @@ -1063,7 +1064,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 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

0 comments on commit 83be9b9

Please sign in to comment.