Skip to content

Commit

Permalink
timing(csr): add 1 cycle to the highest interrupt priority select
Browse files Browse the repository at this point in the history
  • Loading branch information
sinceforYy committed Nov 28, 2024
1 parent f32d59f commit 52f8e7e
Showing 1 changed file with 164 additions and 40 deletions.
204 changes: 164 additions & 40 deletions src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package xiangshan.backend.fu.NewCSR

import chisel3._
import chisel3.util._
import utility.DelayN
import utility.{DelayN, GatedValidRegNext}
import utils._
import xiangshan.ExceptionNO
import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, PrivState, XtvecBundle}
Expand Down Expand Up @@ -59,13 +59,16 @@ class InterruptFilter extends Module {
val mtopigather = mip & mie & (~mideleg).asUInt
val hstopigather = hsip & hsie & (~hideleg).asUInt
val vstopigather = vsip & vsie
val mipriosSort: Vec[UInt] = VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(9.W)))
val mipriosSort: Vec[UInt] = VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(9.W)))
val hsipriosSort: Vec[UInt] = VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(9.W)))
val hvipriosSort: Vec[UInt] = VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(9.W)))
val indexSort : Vec[UInt] = VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(6.W)))

InterruptNO.interruptDefaultPrio.zipWithIndex.foreach { case (value, index) =>
mipriosSort(index) := Mux(mtopigather(value), Cat(1.U, miprios(7 + 8 * value, 8 * value)), 0.U)
hsipriosSort(index) := Mux(hstopigather(value), Cat(1.U, hsiprios(7 + 8 * value, 8 * value)), 0.U)
hvipriosSort(index) := Mux(vstopigather(value), Cat(1.U, 0.U(8.W)), 0.U)
indexSort(index) := index.U
}
hvipriosSort(findIndex(1.U)) := Mux(vstopigather(1).asBool, Cat(1.U, hviprio1.PrioSSI.asUInt), 0.U)
hvipriosSort(findIndex(5.U)) := Mux(vstopigather(5).asBool, Cat(1.U, hviprio1.PrioSTI.asUInt), 0.U)
Expand Down Expand Up @@ -154,23 +157,102 @@ class InterruptFilter extends Module {
}
}

def highIprio(iprios: Vec[UInt], xei: UInt = 0.U): (UInt, UInt) = {
val index = WireInit(VecInit(Seq.fill(InterruptNO.interruptDefaultPrio.size)(0.U(6.W))))
InterruptNO.interruptDefaultPrio.zipWithIndex.foreach { case (prio, i) =>
index(i) := i.U
}
def highIprio(index: Vec[UInt], iprios: Vec[UInt], xei: UInt = 0.U): (UInt, UInt, UInt) = {
val result = minSelect(index, iprios, xei)
(result._1(0), result._2(0)(7, 0))
(result._1(0), result._2(0)(8), result._2(0)(7, 0))
}

private val (mIidIdx, mPrioNum) = highIprio(mipriosSort, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (hsIidIdx, hsPrioNum) = highIprio(hsipriosSort, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)

private val mIidIdxReg = RegNext(mIidIdx)
private val mPrioNumReg = RegNext(mPrioNum)
private val indexTmp0 = VecInit(indexSort.slice(0, 8))
private val indexTmp1 = VecInit(indexSort.slice(8, 16))
private val indexTmp2 = VecInit(indexSort.slice(16, 24))
private val indexTmp3 = VecInit(indexSort.slice(24, 32))
private val indexTmp4 = VecInit(indexSort.slice(32, 40))
private val indexTmp5 = VecInit(indexSort.slice(40, 48))
private val indexTmp6 = VecInit(indexSort.slice(48, 56))
private val indexTmp7 = VecInit(indexSort.slice(56, InterruptNO.interruptDefaultPrio.size))

private val mipriosSortTmp0 = VecInit(mipriosSort.slice( 0, 8))
private val mipriosSortTmp1 = VecInit(mipriosSort.slice( 8, 16))
private val mipriosSortTmp2 = VecInit(mipriosSort.slice(16, 24))
private val mipriosSortTmp3 = VecInit(mipriosSort.slice(24, 32))
private val mipriosSortTmp4 = VecInit(mipriosSort.slice(32, 40))
private val mipriosSortTmp5 = VecInit(mipriosSort.slice(40, 48))
private val mipriosSortTmp6 = VecInit(mipriosSort.slice(48, 56))
private val mipriosSortTmp7 = VecInit(mipriosSort.slice(56, InterruptNO.interruptDefaultPrio.size))

private val hsipriosSortTmp0 = VecInit(hsipriosSort.slice(0, 8))
private val hsipriosSortTmp1 = VecInit(hsipriosSort.slice(8, 16))
private val hsipriosSortTmp2 = VecInit(hsipriosSort.slice(16, 24))
private val hsipriosSortTmp3 = VecInit(hsipriosSort.slice(24, 32))
private val hsipriosSortTmp4 = VecInit(hsipriosSort.slice(32, 40))
private val hsipriosSortTmp5 = VecInit(hsipriosSort.slice(40, 48))
private val hsipriosSortTmp6 = VecInit(hsipriosSort.slice(48, 56))
private val hsipriosSortTmp7 = VecInit(hsipriosSort.slice(56, InterruptNO.interruptDefaultPrio.size))


private val (mIidIdx0, mEnable0, mPrioNum0) = highIprio(indexTmp0, mipriosSortTmp0, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx1, mEnable1, mPrioNum1) = highIprio(indexTmp1, mipriosSortTmp1, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx2, mEnable2, mPrioNum2) = highIprio(indexTmp2, mipriosSortTmp2, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx3, mEnable3, mPrioNum3) = highIprio(indexTmp3, mipriosSortTmp3, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx4, mEnable4, mPrioNum4) = highIprio(indexTmp4, mipriosSortTmp4, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx5, mEnable5, mPrioNum5) = highIprio(indexTmp5, mipriosSortTmp5, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx6, mEnable6, mPrioNum6) = highIprio(indexTmp6, mipriosSortTmp6, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (mIidIdx7, mEnable7, mPrioNum7) = highIprio(indexTmp7, mipriosSortTmp7, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)

private val (hsIidIdx0, hsEnable0, hsPrioNum0) = highIprio(indexTmp0, hsipriosSortTmp0, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx1, hsEnable1, hsPrioNum1) = highIprio(indexTmp1, hsipriosSortTmp1, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx2, hsEnable2, hsPrioNum2) = highIprio(indexTmp2, hsipriosSortTmp2, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx3, hsEnable3, hsPrioNum3) = highIprio(indexTmp3, hsipriosSortTmp3, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx4, hsEnable4, hsPrioNum4) = highIprio(indexTmp4, hsipriosSortTmp4, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx5, hsEnable5, hsPrioNum5) = highIprio(indexTmp5, hsipriosSortTmp5, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx6, hsEnable6, hsPrioNum6) = highIprio(indexTmp6, hsipriosSortTmp6, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)
private val (hsIidIdx7, hsEnable7, hsPrioNum7) = highIprio(indexTmp7, hsipriosSortTmp7, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)


private val mIndexReg = RegInit(VecInit(Seq.fill(8)(0.U(6.W))))
mIndexReg(0) := mIidIdx0
mIndexReg(1) := mIidIdx1
mIndexReg(2) := mIidIdx2
mIndexReg(3) := mIidIdx3
mIndexReg(4) := mIidIdx4
mIndexReg(5) := mIidIdx5
mIndexReg(6) := mIidIdx6
mIndexReg(7) := mIidIdx7

private val hsIndexReg = RegInit(VecInit(Seq.fill(8)(0.U(6.W))))
hsIndexReg(0) := hsIidIdx0
hsIndexReg(1) := hsIidIdx1
hsIndexReg(2) := hsIidIdx2
hsIndexReg(3) := hsIidIdx3
hsIndexReg(4) := hsIidIdx4
hsIndexReg(5) := hsIidIdx5
hsIndexReg(6) := hsIidIdx6
hsIndexReg(7) := hsIidIdx7

private val mipriosSortReg = RegInit(VecInit(Seq.fill(8)(0.U(9.W))))
mipriosSortReg(0) := Cat(mEnable0, mPrioNum0)
mipriosSortReg(1) := Cat(mEnable1, mPrioNum1)
mipriosSortReg(2) := Cat(mEnable2, mPrioNum2)
mipriosSortReg(3) := Cat(mEnable3, mPrioNum3)
mipriosSortReg(4) := Cat(mEnable4, mPrioNum4)
mipriosSortReg(5) := Cat(mEnable5, mPrioNum5)
mipriosSortReg(6) := Cat(mEnable6, mPrioNum6)
mipriosSortReg(7) := Cat(mEnable7, mPrioNum7)

private val hsipriosSortReg = RegInit(VecInit(Seq.fill(8)(0.U(9.W))))
hsipriosSortReg(0) := Cat(hsEnable0, hsPrioNum0)
hsipriosSortReg(1) := Cat(hsEnable1, hsPrioNum1)
hsipriosSortReg(2) := Cat(hsEnable2, hsPrioNum2)
hsipriosSortReg(3) := Cat(hsEnable3, hsPrioNum3)
hsipriosSortReg(4) := Cat(hsEnable4, hsPrioNum4)
hsipriosSortReg(5) := Cat(hsEnable5, hsPrioNum5)
hsipriosSortReg(6) := Cat(hsEnable6, hsPrioNum6)
hsipriosSortReg(7) := Cat(hsEnable7, hsPrioNum7)


private val (mIidIdxReg, mEnable, mPrioNumReg) = highIprio(mIndexReg, mipriosSortReg, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U)
private val (hsIidIdxReg, hsEnable, hsPrioNumReg) = highIprio(hsIndexReg, hsipriosSortReg, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U)

private val hsIidIdxReg = RegNext(hsIidIdx)
private val hsPrioNumReg = RegNext(hsPrioNum)

private val mIidNum = findNum(mIidIdxReg)
private val hsIidNum = findNum(hsIidIdxReg)
Expand All @@ -184,10 +266,10 @@ class InterruptFilter extends Module {
val mtopiPrioNumReal = mPrioNumReg
val stopiPrioNumReal = hsPrioNumReg

val mtopiIsNotZeroReg = RegNext(mtopiIsNotZero)
val stopiIsNotZeroReg = RegNext(stopiIsNotZero)
val mIpriosIsZeroReg = RegNext(mIpriosIsZero)
val hsIpriosIsZeroReg = RegNext(hsIpriosIsZero)
val mtopiIsNotZeroReg = GatedValidRegNext(mtopiIsNotZero)
val stopiIsNotZeroReg = GatedValidRegNext(stopiIsNotZero)
val mIpriosIsZeroReg = GatedValidRegNext(mIpriosIsZero)
val hsIpriosIsZeroReg = GatedValidRegNext(hsIpriosIsZero)

// update mtopi
io.out.mtopi.IID := Mux(mtopiIsNotZeroReg, mIidNum, 0.U)
Expand Down Expand Up @@ -232,43 +314,85 @@ class InterruptFilter extends Module {
assert(PopCount(Cat(Candidate1, Candidate2, Candidate3)) < 2.U, "Only one Candidate could be select from Candidate1/2/3 in VS-level!")
assert(PopCount(Cat(Candidate4, Candidate5)) < 2.U, "Only one Candidate could be select from Candidate4/5 in VS-level!")

private val (vsIidIdx, vsPrioNum) = highIprio(hvipriosSort, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)

private val vsIidIdxReg = RegNext(vsIidIdx)
private val vsPrioNumReg = RegNext(vsPrioNum)
private val hvipriosSortTmp0 = VecInit(hvipriosSort.slice( 0, 8))
private val hvipriosSortTmp1 = VecInit(hvipriosSort.slice( 8, 16))
private val hvipriosSortTmp2 = VecInit(hvipriosSort.slice(16, 24))
private val hvipriosSortTmp3 = VecInit(hvipriosSort.slice(24, 32))
private val hvipriosSortTmp4 = VecInit(hvipriosSort.slice(32, 40))
private val hvipriosSortTmp5 = VecInit(hvipriosSort.slice(40, 48))
private val hvipriosSortTmp6 = VecInit(hvipriosSort.slice(48, 56))
private val hvipriosSortTmp7 = VecInit(hvipriosSort.slice(56, InterruptNO.interruptDefaultPrio.size))

private val (vsIidIdx0, vsEnable0, vsPrioNum0) = highIprio(indexTmp0, hvipriosSortTmp0, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx1, vsEnable1, vsPrioNum1) = highIprio(indexTmp1, hvipriosSortTmp1, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx2, vsEnable2, vsPrioNum2) = highIprio(indexTmp2, hvipriosSortTmp2, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx3, vsEnable3, vsPrioNum3) = highIprio(indexTmp3, hvipriosSortTmp3, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx4, vsEnable4, vsPrioNum4) = highIprio(indexTmp4, hvipriosSortTmp4, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx5, vsEnable5, vsPrioNum5) = highIprio(indexTmp5, hvipriosSortTmp5, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx6, vsEnable6, vsPrioNum6) = highIprio(indexTmp6, hvipriosSortTmp6, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)
private val (vsIidIdx7, vsEnable7, vsPrioNum7) = highIprio(indexTmp7, hvipriosSortTmp7, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)

private val vsIndexReg = RegInit(VecInit(Seq.fill(8)(0.U(6.W))))
vsIndexReg(0) := vsIidIdx0
vsIndexReg(1) := vsIidIdx1
vsIndexReg(2) := vsIidIdx2
vsIndexReg(3) := vsIidIdx3
vsIndexReg(4) := vsIidIdx4
vsIndexReg(5) := vsIidIdx5
vsIndexReg(6) := vsIidIdx6
vsIndexReg(7) := vsIidIdx7

private val hvipriosSortReg = RegInit(VecInit(Seq.fill(8)(0.U(9.W))))
hvipriosSortReg(0) := Cat(vsEnable0, vsPrioNum0)
hvipriosSortReg(1) := Cat(vsEnable1, vsPrioNum1)
hvipriosSortReg(2) := Cat(vsEnable2, vsPrioNum2)
hvipriosSortReg(3) := Cat(vsEnable3, vsPrioNum3)
hvipriosSortReg(4) := Cat(vsEnable4, vsPrioNum4)
hvipriosSortReg(5) := Cat(vsEnable5, vsPrioNum5)
hvipriosSortReg(6) := Cat(vsEnable6, vsPrioNum6)
hvipriosSortReg(7) := Cat(vsEnable7, vsPrioNum7)

private val (vsIidIdxReg, vsEnable, vsPrioNumReg) = highIprio(vsIndexReg, hvipriosSortReg, InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U)

private val vsIidNum = findNum(vsIidIdxReg)

private val Candidate1Reg = GatedValidRegNext(Candidate1)
private val Candidate2Reg = GatedValidRegNext(Candidate2)
private val Candidate3Reg = GatedValidRegNext(Candidate3)
private val Candidate4Reg = GatedValidRegNext(Candidate4)
private val Candidate5Reg = GatedValidRegNext(Candidate5)
private val CandidateNoValidReg = !Candidate1Reg && !Candidate2Reg && !Candidate3Reg && !Candidate4Reg && !Candidate5Reg

val iidCandidate123 = Wire(UInt(12.W))
val iidCandidate45 = Wire(UInt(12.W))
val iprioCandidate123 = Wire(UInt(11.W))
val iprioCandidate45 = Wire(UInt(11.W))
iidCandidate123 := InterruptNO.SEI.U
iprioCandidate123 := Mux1H(Seq(
Candidate1 -> vstopei.IPRIO.asUInt,
Candidate2 -> hvictl.IPRIO.asUInt,
Candidate3 -> 256.U,
Candidate1Reg -> vstopei.IPRIO.asUInt,
Candidate2Reg -> hvictl.IPRIO.asUInt,
Candidate3Reg -> 256.U,
))
iidCandidate45 := Mux1H(Seq(
Candidate4 -> vsIidNum,
Candidate5 -> hvictl.IID.asUInt,
Candidate4Reg -> vsIidNum,
Candidate5Reg -> hvictl.IID.asUInt,
))
iprioCandidate45 := Mux1H(Seq(
Candidate4 -> vsPrioNumReg,
Candidate5 -> hvictl.IPRIO.asUInt,
Candidate4Reg -> vsPrioNumReg,
Candidate5Reg -> hvictl.IPRIO.asUInt,
))

val Candidate123 = Candidate1 || Candidate2 || Candidate3
val Candidate45 = Candidate4 || Candidate5
val Candidate123 = Candidate1Reg || Candidate2Reg || Candidate3Reg
val Candidate45 = Candidate4Reg || Candidate5Reg

val Candidate123HighCandidate45 = Mux1H(Seq(
(Candidate123 && Candidate4) -> ((iprioCandidate123 < iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && (findIndex(iidCandidate123) <= findIndex(iidCandidate45)))),
(Candidate123 && Candidate5) -> ((iprioCandidate123 < iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && hvictl.DPR.asBool)),
(Candidate123 && Candidate4Reg) -> ((iprioCandidate123 < iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && (findIndex(iidCandidate123) <= findIndex(iidCandidate45)))),
(Candidate123 && Candidate5Reg) -> ((iprioCandidate123 < iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && hvictl.DPR.asBool)),
(Candidate123 && !Candidate45) -> true.B,
))
val Candidate123LowCandidate45 = Mux1H(Seq(
(Candidate123 && Candidate4) -> ((iprioCandidate123 > iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && (findIndex(iidCandidate123) > findIndex(iidCandidate45)))),
(Candidate123 && Candidate5) -> ((iprioCandidate123 > iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && !hvictl.DPR.asBool)),
(Candidate123 && Candidate4Reg) -> ((iprioCandidate123 > iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && (findIndex(iidCandidate123) > findIndex(iidCandidate45)))),
(Candidate123 && Candidate5Reg) -> ((iprioCandidate123 > iprioCandidate45) || ((iprioCandidate123 === iprioCandidate45) && !hvictl.DPR.asBool)),
(!Candidate123 && Candidate45) -> true.B,
))

Expand All @@ -284,12 +408,12 @@ class InterruptFilter extends Module {
))

// update vstopi
io.out.vstopi.IID := Mux(CandidateNoValid, 0.U, iidCandidate)
io.out.vstopi.IID := Mux(CandidateNoValidReg, 0.U, iidCandidate)
io.out.vstopi.IPRIO := Mux1H(Seq(
CandidateNoValid -> 0.U,
CandidateNoValidReg -> 0.U,
(iprioCandidate > 255.U) -> 255.U,
(Candidate123LowCandidate45 && Candidate5 && !hvictl.IPRIOM.asBool) -> 1.U,
((Candidate123HighCandidate45 && iprioCandidate <= 255.U) || (Candidate123LowCandidate45 && Candidate4) || (Candidate123LowCandidate45 && Candidate5 && hvictl.IPRIOM.asBool)) -> iprioCandidate(7, 0),
(Candidate123LowCandidate45 && Candidate5Reg && !hvictl.IPRIOM.asBool) -> 1.U,
((Candidate123HighCandidate45 && iprioCandidate <= 255.U) || (Candidate123LowCandidate45 && Candidate4Reg) || (Candidate123LowCandidate45 && Candidate5Reg && hvictl.IPRIOM.asBool)) -> iprioCandidate(7, 0),
))

val mIRVec = Mux(
Expand Down

0 comments on commit 52f8e7e

Please sign in to comment.