From 52f8e7e9f3b5a110c72e5dd9066eb402d41454af Mon Sep 17 00:00:00 2001 From: sinceforYy <1017657683@qq.com> Date: Thu, 28 Nov 2024 14:20:46 +0800 Subject: [PATCH] timing(csr): add 1 cycle to the highest interrupt priority select --- .../backend/fu/NewCSR/InterruptFilter.scala | 204 ++++++++++++++---- 1 file changed, 164 insertions(+), 40 deletions(-) diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala index 767885f90dc..1e75451babf 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/InterruptFilter.scala @@ -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} @@ -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) @@ -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) @@ -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) @@ -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, )) @@ -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(