1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import utility.{DelayN, GatedValidRegNext} 6import utils._ 7import xiangshan.ExceptionNO 8import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, PrivState, XtvecBundle} 9import xiangshan.backend.fu.NewCSR.CSRDefines.{PrivMode, XtvecMode} 10import xiangshan.backend.fu.NewCSR.InterruptNO 11 12 13class InterruptFilter extends Module { 14 val io = IO(new InterruptFilterIO) 15 16 val privState = io.in.privState 17 val mstatusMIE = io.in.mstatusMIE 18 val sstatusSIE = io.in.sstatusSIE 19 val vsstatusSIE = io.in.vsstatusSIE 20 val mip = io.in.mip 21 val mie = io.in.mie 22 val mideleg = io.in.mideleg 23 val sip = io.in.sip 24 val sie = io.in.sie 25 val hip = io.in.hip 26 val hie = io.in.hie 27 val hideleg = io.in.hideleg 28 val vsip = io.in.vsip 29 val vsie = io.in.vsie 30 val hvictl = io.in.hvictl 31 val hstatus = io.in.hstatus 32 val mtopei = io.in.mtopei 33 val stopei = io.in.stopei 34 val vstopei = io.in.vstopei 35 val hviprio1 = io.in.hviprio1 36 val hviprio2 = io.in.hviprio2 37 val miprios = io.in.miprios 38 val hsiprios = io.in.hsiprios 39 val hviprios = Cat(hviprio2.asUInt, hviprio1.asUInt) 40 val fromAIAValid = io.in.fromAIA.meip || io.in.fromAIA.seip 41 val platformValid = io.in.platform.meip || io.in.platform.seip 42 43 /** 44 * Sort by implemented interrupt default priority 45 * index low, priority high 46 */ 47 val vsipFields = Wire(new VSipBundle); vsipFields := vsip 48 val vsieFields = Wire(new VSieBundle); vsieFields := vsie 49 50 private val hsip = hip.asUInt | sip.asUInt 51 private val hsie = hie.asUInt | sie.asUInt 52 53 val mtopiIsNotZero: Bool = (mip & mie & (~mideleg).asUInt) =/= 0.U 54 val stopiIsNotZero: Bool = (hsip & hsie & (~hideleg).asUInt) =/= 0.U 55 56 val NoSEIMask = (~(BigInt(1) << InterruptNO.SEI).U(64.W)).asUInt 57 val mtopigather = mip & mie & (~mideleg).asUInt 58 val hstopigather = hsip & hsie & (~hideleg).asUInt 59 val vstopigather = vsip & vsie & NoSEIMask 60 61 val flag = RegInit(false.B) 62 when (platformValid) { 63 flag := true.B 64 }.elsewhen(fromAIAValid) { 65 flag := false.B 66 } 67 68 val mipriosSort = Wire(Vec(InterruptNO.interruptDefaultPrio.size, new IpriosSort)) 69 mipriosSort.zip(InterruptNO.interruptDefaultPrio).zipWithIndex.foreach { case ((iprio, defaultPrio), i) => 70 iprio.idx := i.U 71 when (mtopigather(defaultPrio)) { 72 iprio.enable := true.B 73 when (defaultPrio.U === InterruptNO.MEI.U) { 74 iprio.isZero := platformValid || flag 75 val mtopeiGreaterThan255 = mtopei.IPRIO.asUInt(10, 8).orR 76 iprio.greaterThan255 := mtopeiGreaterThan255 77 iprio.prioNum := mtopei.IPRIO.asUInt(7, 0) 78 }.otherwise { 79 iprio.isZero := !miprios(7 + 8 * defaultPrio, 8 * defaultPrio).orR 80 iprio.greaterThan255 := false.B 81 iprio.prioNum := miprios(7 + 8 * defaultPrio, 8 * defaultPrio) 82 } 83 }.otherwise { 84 iprio.enable := false.B 85 iprio.isZero := false.B 86 iprio.greaterThan255 := false.B 87 iprio.prioNum := 0.U 88 } 89 } 90 val hsipriosSort = Wire(Vec(InterruptNO.interruptDefaultPrio.size, new IpriosSort)) 91 hsipriosSort.zip(InterruptNO.interruptDefaultPrio).zipWithIndex.foreach { case ((iprio, defaultPrio), i) => 92 iprio.idx := i.U 93 when (hstopigather(defaultPrio)) { 94 iprio.enable := true.B 95 when (defaultPrio.U === InterruptNO.SEI.U) { 96 iprio.isZero := platformValid || flag 97 val stopeiGreaterThan255 = stopei.IPRIO.asUInt(10, 8).orR 98 iprio.greaterThan255 := stopeiGreaterThan255 99 iprio.prioNum := stopei.IPRIO.asUInt(7, 0) 100 }.otherwise { 101 iprio.isZero := !hsiprios(7 + 8 * defaultPrio, 8 * defaultPrio).orR 102 iprio.greaterThan255 := false.B 103 iprio.prioNum := hsiprios(7 + 8 * defaultPrio, 8 * defaultPrio) 104 } 105 }.otherwise { 106 iprio.enable := false.B 107 iprio.isZero := false.B 108 iprio.greaterThan255 := false.B 109 iprio.prioNum := 0.U 110 } 111 } 112 val hvipriosSort = Wire(Vec(InterruptNO.interruptDefaultPrio.size, new IpriosSort)) 113 hvipriosSort.zip(InterruptNO.interruptDefaultPrio).zipWithIndex.foreach { case ((iprio, defaultPrio), i) => 114 iprio.idx := i.U 115 when(vstopigather(defaultPrio)) { 116 iprio.enable := true.B 117 iprio.isZero := true.B 118 iprio.greaterThan255 := false.B 119 iprio.prioNum := 0.U 120 }.otherwise { 121 iprio.enable := false.B 122 iprio.isZero := false.B 123 iprio.greaterThan255 := false.B 124 iprio.prioNum := 0.U 125 } 126 } 127 when(vstopigather(1).asBool) { 128 hvipriosSort(findIndex(1.U)).isZero := !hviprio1.PrioSSI.asUInt.orR 129 hvipriosSort(findIndex(1.U)).prioNum := hviprio1.PrioSSI.asUInt 130 } 131 132 when(vstopigather(5).asBool) { 133 hvipriosSort(findIndex(5.U)).isZero := !hviprio1.PrioSTI.asUInt.orR 134 hvipriosSort(findIndex(5.U)).prioNum := hviprio1.PrioSTI.asUInt 135 } 136 137 for (i <- 0 to 10) { 138 when(vstopigather(i + 13).asBool) { 139 hvipriosSort(findIndex((i + 13).U)).isZero := !hviprios(7 + 8 * (i + 5), 8 * (i + 5)).orR 140 hvipriosSort(findIndex((i + 13).U)).prioNum := hviprios(7 + 8 * (i + 5), 8 * (i + 5)) 141 } 142 } 143 144 def findNum(input: UInt): UInt = { 145 val select = Mux1H(UIntToOH(input), InterruptNO.interruptDefaultPrio.map(_.U)) 146 select 147 } 148 149 def findIndex(input: UInt): UInt = { 150 val select = WireInit(0.U(log2Up(InterruptNO.interruptDefaultPrio.length).W)) 151 InterruptNO.interruptDefaultPrio.zipWithIndex.foreach { case (value, i) => 152 when (input === value.U) { 153 select := i.U 154 } 155 } 156 select 157 } 158 159 // value lower, priority higher 160 def minSelect(iprios: Vec[IpriosSort], xei: UInt): Vec[IpriosSort] = { 161 iprios.size match { 162 case 1 => 163 iprios 164 case 2 => 165 val left = iprios(0) 166 val right = iprios(1) 167 val minIprio = Mux1H(Seq( 168 (left.enable && !right.enable) -> left, 169 (!left.enable && right.enable) -> right, 170 (left.enable && right.enable) -> Mux1H(Seq( 171 (left.isZero && right.isZero) -> left, 172 (left.isZero && !right.isZero) -> Mux(left.idx <= xei, left, right), 173 (!left.isZero && right.isZero) -> Mux(right.idx <= xei, right, left), 174 (!left.isZero && !right.isZero) -> Mux1H(Seq( 175 (left.greaterThan255 && !right.greaterThan255) -> right, 176 (!left.greaterThan255 && right.greaterThan255) -> left, 177 (!left.greaterThan255 && !right.greaterThan255) -> Mux(left.prioNum <= right.prioNum, left, right), 178 )) 179 )) 180 )) 181 VecInit(minIprio) 182 case _ => 183 val leftIprio = minSelect(VecInit(iprios.take((iprios.size + 1) / 2)), xei) 184 val rightIprio = minSelect(VecInit(iprios.drop((iprios.size + 1) / 2)), xei) 185 minSelect(VecInit(leftIprio ++ rightIprio), xei) 186 } 187 } 188 189 def highIprio(iprios: Vec[IpriosSort], xei: UInt): IpriosSort = { 190 val result = minSelect(iprios, xei) 191 result(0) 192 } 193 194 def sliceIpriosSort(ipriosSort: Vec[IpriosSort]): Vec[Vec[IpriosSort]] = { 195 val ipriosSortTmp = Wire(Vec(8, Vec(8, new IpriosSort))) 196 for (i <- 0 until 8) { 197 val end = math.min(8 * (i + 1), InterruptNO.interruptDefaultPrio.size) 198 val ipriosSlice = ipriosSort.slice(8 * i, end) 199 val paddingSlice = ipriosSlice ++ Seq.fill(8 - ipriosSlice.length)(0.U.asTypeOf(new IpriosSort)) 200 ipriosSortTmp(i) := VecInit(paddingSlice) 201 } 202 ipriosSortTmp 203 } 204 205 private val mipriosSortTmp = sliceIpriosSort(mipriosSort) 206 private val hsipriosSortTmp = sliceIpriosSort(hsipriosSort) 207 private val hvipriosSortTmp = sliceIpriosSort(hvipriosSort) 208 209 private val meiPrioIdx = InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.MEI).U 210 private val seiPrioIdx = InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.SEI).U 211 private val vseiPrioIdx = InterruptNO.getPrioIdxInGroup(_.interruptDefaultPrio)(_.VSEI).U 212 213 private val mipriosTmp = Wire(Vec(8, new IpriosSort)) 214 mipriosSortTmp.zipWithIndex.foreach { case (iprios, i) => 215 val ipriosTmp = highIprio(iprios, meiPrioIdx) 216 mipriosTmp(i) := ipriosTmp 217 } 218 219 private val hsipriosTmp = Wire(Vec(8, new IpriosSort)) 220 hsipriosSortTmp.zipWithIndex.foreach { case (iprios, i) => 221 val ipriosTmp = highIprio(iprios, seiPrioIdx) 222 hsipriosTmp(i) := ipriosTmp 223 } 224 225 private val hvipriosTmp = Wire(Vec(8, new IpriosSort)) 226 hvipriosSortTmp.zipWithIndex.foreach { case (iprios, i) => 227 val ipriosTmp = highIprio(iprios, vseiPrioIdx) 228 hvipriosTmp(i) := ipriosTmp 229 } 230 231 private val mipriosReg = Reg(Vec(8, new IpriosSort)) 232 private val hsipriosReg = Reg(Vec(8, new IpriosSort)) 233 private val hvipriosReg = Reg(Vec(8, new IpriosSort)) 234 235 for (i <- 0 until 8) { 236 mipriosReg(i) := mipriosTmp(i) 237 hsipriosReg(i) := hsipriosTmp(i) 238 hvipriosReg(i) := hvipriosTmp(i) 239 } 240 241 private val mipriosRegTmp = highIprio(mipriosReg, meiPrioIdx) 242 private val hsipriosRegTmp = highIprio(hsipriosReg, seiPrioIdx) 243 private val hvipriosRegTmp = highIprio(hvipriosReg, vseiPrioIdx) 244 245 private val mIidIdxReg = mipriosRegTmp.idx 246 private val hsIidIdxReg = hsipriosRegTmp.idx 247 private val vsIidIdxReg = hvipriosRegTmp.idx 248 249 private val mIidNum = findNum(mIidIdxReg) 250 private val hsIidNum = findNum(hsIidIdxReg) 251 private val vsIidNum = findNum(vsIidIdxReg) 252 253 private val mIidDefaultPrioHighMEI: Bool = mIidIdxReg < meiPrioIdx 254 private val mIidDefaultPrioLowMEI : Bool = mIidIdxReg > meiPrioIdx 255 256 private val hsIidDefaultPrioHighSEI: Bool = hsIidIdxReg < seiPrioIdx 257 private val hsIidDefaultPrioLowSEI : Bool = hsIidIdxReg > seiPrioIdx 258 259 // update mtopi 260 io.out.mtopi.IID := Mux(mtopiIsNotZero, mIidNum, 0.U) 261 io.out.mtopi.IPRIO := Mux(mtopiIsNotZero, 262 Mux1H(Seq( 263 (!mipriosRegTmp.isZero && !mipriosRegTmp.greaterThan255) -> mipriosRegTmp.prioNum, 264 (mipriosRegTmp.greaterThan255 || mipriosRegTmp.isZero && mIidDefaultPrioLowMEI) -> 255.U, 265 (mipriosRegTmp.isZero && mIidDefaultPrioHighMEI) -> 0.U, 266 )), 267 0.U 268 ) 269 270 // upadte stopi 271 io.out.stopi.IID := Mux(stopiIsNotZero, hsIidNum, 0.U) 272 io.out.stopi.IPRIO := Mux(stopiIsNotZero, 273 Mux1H(Seq( 274 (!hsipriosRegTmp.isZero && !hsipriosRegTmp.greaterThan255) -> hsipriosRegTmp.prioNum, 275 (hsipriosRegTmp.greaterThan255 || hsipriosRegTmp.isZero && hsIidDefaultPrioLowSEI) -> 255.U, 276 (hsipriosRegTmp.isZero && hsIidDefaultPrioHighSEI) -> 0.U, 277 )), 278 0.U 279 ) 280 281 // refactor this code & has some problem 282 val Candidate1: Bool = vsip.SEIP && vsie.SEIE && (hstatus.VGEIN.asUInt =/= 0.U) && (vstopei.asUInt =/= 0.U) 283 val Candidate2: Bool = vsip.SEIP && vsie.SEIE && (hstatus.VGEIN.asUInt === 0.U) && (hvictl.IID.asUInt === 9.U) && (hvictl.IPRIO.asUInt =/= 0.U) 284 val Candidate3: Bool = vsip.SEIP && vsie.SEIE && !Candidate1 && !Candidate2 285 val Candidate4: Bool = (hvictl.VTI.asUInt === 0.U) && vstopigather.orR 286 val Candidate5: Bool = (hvictl.VTI.asUInt === 1.U) && (hvictl.IID.asUInt =/= 9.U) 287 val CandidateNoValid: Bool = !Candidate1 && !Candidate2 && !Candidate3 && !Candidate4 && !Candidate5 288 289 assert(PopCount(Cat(Candidate1, Candidate2, Candidate3)) < 2.U, "Only one Candidate could be select from Candidate1/2/3 in VS-level!") 290 assert(PopCount(Cat(Candidate4, Candidate5)) < 2.U, "Only one Candidate could be select from Candidate4/5 in VS-level!") 291 assert(PopCount(Cat(Candidate2, Candidate5)) < 2.U, "Candidate2 and candidate5 cannot be true at the same time. ") 292 293 val Candidate123 = Candidate1 || Candidate2 || Candidate3 294 val Candidate45 = Candidate4 || Candidate5 295 296 // Candidate2,Candidate5 不可能同时成立 297 val onlyC1Enable = Candidate1 & !Candidate45 298 val onlyC2Enable = Candidate2 & !Candidate45 299 val onlyC3Enable = Candidate3 & !Candidate123 300 val onlyC4Enable = Candidate4 & !Candidate123 301 val onlyC5Enable = Candidate5 & !Candidate123 302 val C1C4Enable = Candidate1 & Candidate4 303 val C1C5Enable = Candidate1 & Candidate5 304 val C2C4Enable = Candidate2 & Candidate4 305 val C3C4Enable = Candidate3 & Candidate4 306 val C3C5Enable = Candidate3 & Candidate5 307 308 val iidOnlyC1 = Wire(UInt(12.W)) 309 val iidOnlyC4 = Wire(UInt(12.W)) 310 val iidOnlyC5 = Wire(UInt(12.W)) 311 val iprioOnlyC1 = Wire(UInt(8.W)) 312 val iprioOnlyC2 = Wire(UInt(8.W)) 313 val iprioOnlyC3 = Wire(UInt(8.W)) 314 val iprioOnlyC4 = Wire(UInt(8.W)) 315 val iprioOnlyC5 = Wire(UInt(8.W)) 316 val iidC1C4 = Wire(UInt(12.W)) 317 val iidC1C5 = Wire(UInt(12.W)) 318 val iidC2C4 = Wire(UInt(12.W)) 319 val iidC3C4 = Wire(UInt(12.W)) 320 val iidC3C5 = Wire(UInt(12.W)) 321 val iprioC1C4 = Wire(UInt(8.W)) 322 val iprioC1C5 = Wire(UInt(8.W)) 323 val iprioC2C4 = Wire(UInt(8.W)) 324 val iprioC3C4 = Wire(UInt(8.W)) 325 val iprioC3C5 = Wire(UInt(8.W)) 326 327 iidOnlyC1 := InterruptNO.SEI.U 328 iidOnlyC4 := vsIidNum 329 iidOnlyC5 := hvictl.IID.asUInt 330 331 val iidC4Idx = Wire(UInt(12.W)) 332 iidC4Idx := vsIidIdxReg 333 334 val iprioC1 = Wire(UInt(11.W)) 335 val iprioC2C5 = Wire(UInt(11.W)) 336 val iprioC4 = Wire(UInt(11.W)) 337 val iprioC1Tmp = Wire(UInt(8.W)) 338 val iprioC4Tmp = Wire(UInt(8.W)) 339 val iprioC3C5Tmp = Wire(UInt(8.W)) 340 341 val hvictlDPR = Mux(hvictl.DPR.asBool, 255.U, 0.U) 342 val C1GreaterThan255 = vstopei.IPRIO.asUInt(10, 8).orR 343 val C4IsZero = !hvipriosRegTmp.prioNum.orR 344 val C2C5IsZero = !hvictl.IPRIO.asUInt.orR 345 val C4HighVSEI = iidC4Idx < findIndex(InterruptNO.VSEI.U) 346 val SEIHighC4 = findIndex(InterruptNO.SEI.U) < iidC4Idx 347 val iprioC1GreaterThan255 = Mux(C1GreaterThan255, 255.U, iprioC1Tmp) 348 349 iprioC1 := vstopei.IPRIO.asUInt 350 iprioC2C5 := hvictl.IPRIO.asUInt 351 iprioC4 := hvipriosRegTmp.prioNum 352 353 iprioC1Tmp := iprioC1(7, 0) 354 iprioC4Tmp := Mux(C4IsZero, Mux(C4HighVSEI, 0.U, 255.U), iprioC4) 355 iprioC3C5Tmp := Mux(C2C5IsZero, hvictlDPR, iprioC2C5) 356 357 iprioOnlyC1 := iprioC1GreaterThan255 358 iprioOnlyC2 := iprioC2C5 359 iprioOnlyC3 := 255.U 360 iprioOnlyC4 := iprioC4Tmp 361 iprioOnlyC5 := iprioC3C5Tmp 362 363 // C1,C4 enable 364 when(C4IsZero) { 365 iidC1C4 := Mux(C4HighVSEI, iidOnlyC4, iidOnlyC1) 366 iprioC1C4 := Mux(C4HighVSEI, 0.U, iprioC1GreaterThan255) 367 }.elsewhen(iprioC1 < iprioC4) { 368 iidC1C4 := iidOnlyC1 369 iprioC1C4 := iprioC1Tmp 370 }.elsewhen(iprioC1 === iprioC4) { 371 iidC1C4 := Mux(SEIHighC4, iidOnlyC1, iidOnlyC4) 372 iprioC1C4 := Mux(SEIHighC4, iprioC1Tmp, iprioC4) 373 }.otherwise { 374 iidC1C4 := iidOnlyC4 375 iprioC1C4 := iprioC4 376 } 377 378 // C1,C5 enable 379 iidC1C5 := Mux(hvictl.DPR.asBool, iidOnlyC1, iidOnlyC5) 380 when(C2C5IsZero) { 381 iprioC1C5 := Mux(hvictl.DPR.asBool, iprioC1GreaterThan255, 0.U) 382 }.elsewhen(iprioC1 < iprioC2C5) { 383 iidC1C5 := iidOnlyC1 384 iprioC1C5 := iprioC1Tmp 385 }.elsewhen(iprioC1 === iprioC2C5) { 386 iprioC1C5 := Mux(hvictl.DPR.asBool, iprioC1Tmp, iprioC2C5) 387 }.otherwise { 388 iidC1C5 := iidOnlyC5 389 iprioC1C5 := iprioC3C5Tmp 390 } 391 392 // C2,C4 enable 393 when(C4IsZero) { 394 iidC2C4 := Mux(C4HighVSEI, iidOnlyC4, iidOnlyC1) 395 iprioC2C4 := Mux(C4HighVSEI, 0.U, iprioC2C5) 396 }.elsewhen(iprioC2C5 < iprioC4) { 397 iidC2C4 := iidOnlyC1 398 iprioC2C4 := iprioC2C5 399 }.elsewhen(iprioC2C5 === iprioC4) { 400 iidC2C4 := Mux(SEIHighC4, iidOnlyC1, iidOnlyC4) 401 iprioC2C4 := Mux(SEIHighC4, iprioC2C5, iprioC4) 402 }.otherwise { 403 iidC2C4 := iidOnlyC4 404 iprioC2C4 := iprioC4 405 } 406 407 // C3,C4 enable 408 iidC3C4 := Mux(C4IsZero, Mux(C4HighVSEI, iidOnlyC4, iidOnlyC1), iidOnlyC4) 409 iprioC3C4 := iprioC4Tmp 410 // C3,C5 enable 411 iidC3C5 := Mux(C2C5IsZero, Mux(hvictl.DPR.asBool, iidOnlyC5, iidOnlyC1), iidOnlyC5) 412 iprioC3C5 := iprioC3C5Tmp 413 414 // update vstopi 415 io.out.vstopi.IID := Mux(CandidateNoValid, 416 0.U, 417 Mux1H(Seq( 418 (Candidate123 & !Candidate45) -> iidOnlyC1, 419 onlyC4Enable -> iidOnlyC4, 420 onlyC5Enable -> iidOnlyC5, 421 C1C4Enable -> iidC1C4, 422 C1C5Enable -> iidC1C5, 423 C2C4Enable -> iidC2C4, 424 C3C4Enable -> iidC3C4, 425 C3C5Enable -> iidC3C5, 426 )) 427 ) 428 io.out.vstopi.IPRIO := Mux(CandidateNoValid, 429 0.U, 430 Mux(!hvictl.IPRIOM.asBool, 1.U, 431 Mux1H(Seq( 432 onlyC1Enable -> iprioOnlyC1, 433 onlyC2Enable -> iprioOnlyC2, 434 onlyC3Enable -> iprioOnlyC3, 435 onlyC4Enable -> iprioOnlyC4, 436 onlyC5Enable -> iprioOnlyC5, 437 C1C4Enable -> iprioC1C4, 438 C1C5Enable -> iprioC1C5, 439 C2C4Enable -> iprioC2C4, 440 C3C4Enable -> iprioC3C4, 441 C3C5Enable -> iprioC3C5, 442 )) 443 ) 444 ) 445 446 val mIRVecTmp = Mux( 447 privState.isModeM && mstatusMIE || privState < PrivState.ModeM, 448 io.out.mtopi.IID.asUInt, 449 0.U 450 ) 451 452 val hsIRVecTmp = Mux( 453 privState.isModeHS && sstatusSIE || privState < PrivState.ModeHS, 454 io.out.stopi.IID.asUInt, 455 0.U 456 ) 457 458 val vsIRVecTmp = Mux( 459 privState.isModeVS && vsstatusSIE || privState < PrivState.ModeVS, 460 io.out.vstopi.IID.asUInt, 461 0.U 462 ) 463 464 val mIRNotZero = mIRVecTmp.orR 465 val hsIRNotZero = hsIRVecTmp.orR 466 val vsIRNotZero = vsIRVecTmp.orR 467 468 val irToHS = !mIRNotZero && hsIRNotZero 469 val irToVS = !mIRNotZero && !hsIRNotZero && vsIRNotZero 470 471 val mIRVec = mIRVecTmp 472 val hsIRVec = Mux(irToHS, hsIRVecTmp, 0.U) 473 val vsIRVec = Mux(irToVS, UIntToOH(vsIRVecTmp, 64), 0.U) 474 475 val vsMapHostIRVecTmp = Cat((0 until vsIRVec.getWidth).map { num => 476 // 2,6,10 477 if (InterruptNO.getVS.contains(num)) { 478 // 1,5,9 479 val sNum = num - 1 480 vsIRVec(sNum) 481 } 482 // 1,5,9 483 else if (InterruptNO.getHS.contains(num)) { 484 0.U(1.W) 485 } 486 else { 487 vsIRVec(num) 488 } 489 }.reverse) 490 491 val vsMapHostIRVec = OHToUInt(vsMapHostIRVecTmp) 492 493 dontTouch(vsMapHostIRVec) 494 495 val nmiVecTmp = Wire(Vec(64, Bool())) 496 nmiVecTmp.zipWithIndex.foreach { case (irq, i) => 497 if (NonMaskableIRNO.interruptDefaultPrio.contains(i)) { 498 val higherIRSeq = NonMaskableIRNO.getIRQHigherThan(i) 499 irq := ( 500 higherIRSeq.nonEmpty.B && Cat(higherIRSeq.map(num => !io.in.nmiVec(num))).andR || 501 higherIRSeq.isEmpty.B 502 ) && io.in.nmiVec(i) 503 dontTouch(irq) 504 } else 505 irq := false.B 506 } 507 val nmiVec = OHToUInt(nmiVecTmp) 508 509 // support debug interrupt 510 // support smrnmi when NMIE is 0, all interrupt disable 511 val disableDebugIntr = io.in.debugMode || (io.in.dcsr.STEP.asBool && !io.in.dcsr.STEPIE.asBool) 512 val enableDebugIntr = io.in.debugIntr && !disableDebugIntr 513 514 val disableAllIntr = disableDebugIntr || !io.in.mnstatusNMIE 515 516 val normalIntrVec = mIRVec | hsIRVec | vsMapHostIRVec 517 val intrVec = Mux(disableAllIntr, 0.U, Mux(io.in.nmi, nmiVec, normalIntrVec)) 518 519 // virtual interrupt with hvictl injection 520 val vsIRModeCond = privState.isModeVS && vsstatusSIE || privState < PrivState.ModeVS 521 val SelectCandidate5 = onlyC5Enable || C3C5Enable || 522 C1C5Enable && (iprioC1 === iprioC2C5 && !hvictl.DPR.asBool || iprioC1 > iprioC2C5) 523 // delay at least 6 cycles to maintain the atomic of sret/mret 524 // 65bit indict current interrupt is NMI 525 val intrVecReg = RegInit(0.U(8.W)) 526 val debugIntrReg = RegInit(false.B) 527 val nmiReg = RegInit(false.B) 528 val viIsHvictlInjectReg = RegInit(false.B) 529 val irToHSReg = RegInit(false.B) 530 val irToVSReg = RegInit(false.B) 531 intrVecReg := intrVec 532 debugIntrReg := enableDebugIntr 533 nmiReg := io.in.nmi 534 viIsHvictlInjectReg := vsIRModeCond && SelectCandidate5 535 irToHSReg := irToHS 536 irToVSReg := irToVS 537 val delayedIntrVec = DelayN(intrVecReg, 5) 538 val delayedDebugIntr = DelayN(debugIntrReg, 5) 539 val delayedNMI = DelayN(nmiReg, 5) 540 val delayedVIIsHvictlInjectReg = DelayN(viIsHvictlInjectReg, 5) 541 val delayedIRToHS = DelayN(irToHSReg, 5) 542 val delayedIRToVS = DelayN(irToVSReg, 5) 543 544 io.out.interruptVec.valid := delayedIntrVec.orR || delayedDebugIntr || delayedVIIsHvictlInjectReg 545 io.out.interruptVec.bits := delayedIntrVec 546 io.out.debug := delayedDebugIntr 547 io.out.nmi := delayedNMI 548 io.out.virtualInterruptIsHvictlInject := delayedVIIsHvictlInjectReg & !delayedNMI 549 io.out.irToHS := delayedIRToHS & !delayedNMI 550 io.out.irToVS := delayedIRToVS & !delayedNMI 551 552 dontTouch(hsip) 553 dontTouch(hsie) 554 dontTouch(mIRVec) 555 dontTouch(hsIRVec) 556 dontTouch(vsIRVec) 557} 558 559class InterruptFilterIO extends Bundle { 560 val in = Input(new Bundle { 561 val privState = new PrivState 562 val mstatusMIE = Bool() 563 val sstatusSIE = Bool() 564 val vsstatusSIE = Bool() 565 val mip = new MipBundle 566 val mie = new MieBundle 567 val mideleg = new MidelegBundle 568 val sip = new SipBundle 569 val sie = new SieBundle 570 val hip = new HipBundle 571 val hie = new HieBundle 572 val hideleg = new HidelegBundle 573 val vsip = new VSipBundle 574 val vsie = new VSieBundle 575 val hvictl = new HvictlBundle 576 val hstatus = new HstatusBundle 577 val mtopei = new TopEIBundle 578 val stopei = new TopEIBundle 579 val vstopei = new TopEIBundle 580 val hviprio1 = new Hviprio1Bundle 581 val hviprio2 = new Hviprio2Bundle 582 val debugIntr = Bool() 583 val debugMode = Bool() 584 val dcsr = new DcsrBundle 585 586 val miprios = UInt((64*8).W) 587 val hsiprios = UInt((64*8).W) 588 //smrnmi 589 val nmi = Bool() 590 val nmiVec = UInt(64.W) 591 val mnstatusNMIE = Bool() 592 val platform = new Bundle { 593 val meip = Bool() 594 val seip = Bool() 595 } 596 val fromAIA = new Bundle { 597 val meip = Bool() 598 val seip = Bool() 599 } 600 }) 601 602 val out = Output(new Bundle { 603 val debug = Bool() 604 val nmi = Bool() 605 val interruptVec = ValidIO(UInt(8.W)) 606 val mtopi = new TopIBundle 607 val stopi = new TopIBundle 608 val vstopi = new TopIBundle 609 val virtualInterruptIsHvictlInject = Bool() 610 val irToHS = Bool() 611 val irToVS = Bool() 612 }) 613} 614 615 616class IpriosSort extends Bundle { 617 val idx = UInt(6.W) 618 val enable = Bool() 619 val isZero = Bool() 620 val greaterThan255 = Bool() 621 val prioNum = UInt(8.W) 622} 623