1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.experimental.SourceInfo 5import chisel3.util._ 6import org.chipsalliance.cde.config.Parameters 7import freechips.rocketchip.rocket.CSRs 8import utility.SignExt 9import utils.PerfEvent 10import xiangshan.backend.fu.NewCSR.CSRBundles._ 11import xiangshan.backend.fu.NewCSR.CSRDefines._ 12import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 13import xiangshan.backend.fu.NewCSR.CSREvents._ 14import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 15import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 16import xiangshan.backend.fu.PerfCounterIO 17import xiangshan.backend.fu.NewCSR.CSRConfig._ 18import xiangshan.backend.fu.NewCSR.CSRFunc.wNoEffectWhen 19 20import scala.collection.immutable.SeqMap 21 22trait MachineLevel { self: NewCSR => 23 val mstatus = Module(new MstatusModule) 24 .setAddr(CSRs.mstatus) 25 26 val misa = Module(new CSRModule("Misa", new MisaBundle)) 27 .setAddr(CSRs.misa) 28 29 println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}") 30 31 val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle)) 32 .setAddr(CSRs.medeleg) 33 34 val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle)) 35 .setAddr(CSRs.mideleg) 36 37 val mie = Module(new CSRModule("Mie", new MieBundle) with HasIpIeBundle { 38 val fromHie = IO(Flipped(new HieToMie)) 39 val fromSie = IO(Flipped(new SieToMie)) 40 val fromVSie = IO(Flipped(new VSieToMie)) 41 42 // bit 1 SSIE 43 when (fromSie.SSIE.valid) { 44 reg.SSIE := fromSie.SSIE.bits 45 } 46 47 // bit 2 VSSIE 48 when (fromHie.VSSIE.valid || fromVSie.VSSIE.valid) { 49 reg.VSSIE := Mux1H(Seq( 50 fromHie .VSSIE.valid -> fromHie .VSSIE.bits, 51 fromVSie.VSSIE.valid -> fromVSie.VSSIE.bits, 52 )) 53 } 54 55 // bit 5 STIE 56 when(fromSie.STIE.valid) { 57 reg.STIE := fromSie.STIE.bits 58 } 59 60 // bit 6 VSTIE 61 when(fromHie.VSTIE.valid || fromVSie.VSTIE.valid) { 62 reg.VSTIE := Mux1H(Seq( 63 fromHie .VSTIE.valid -> fromHie .VSTIE.bits, 64 fromVSie.VSTIE.valid -> fromVSie.VSTIE.bits, 65 )) 66 } 67 68 // bit 9 SEIE 69 when(fromSie.SEIE.valid) { 70 reg.SEIE := fromSie.SEIE.bits 71 } 72 73 // bit 10 VSEIE 74 when(fromHie.VSEIE.valid || fromVSie.VSEIE.valid) { 75 reg.VSEIE := Mux1H(Seq( 76 fromHie .VSEIE.valid -> fromHie .VSEIE.bits, 77 fromVSie.VSEIE.valid -> fromVSie.VSEIE.bits, 78 )) 79 } 80 81 // bit 12 SGEIE 82 when(fromHie.SGEIE.valid) { 83 reg.SGEIE := fromHie.SGEIE.bits 84 } 85 86 // bit 13~63 LCIP 87 reg.getLocal lazyZip fromSie.getLocal lazyZip fromVSie.getLocal foreach { case (rLCIE, sieLCIE, vsieLCIE) => 88 when (sieLCIE.valid || vsieLCIE.valid) { 89 rLCIE := Mux1H(Seq( 90 sieLCIE .valid -> sieLCIE .bits, 91 vsieLCIE.valid -> vsieLCIE.bits, 92 )) 93 } 94 } 95 96 // 14~63 read only 0 97 regOut.getLocal.filterNot(_.lsb == InterruptNO.COI).foreach(_ := 0.U) 98 }).setAddr(CSRs.mie) 99 100 val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle)) 101 .setAddr(CSRs.mtvec) 102 103 // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0 104 // Todo: support Sscounterenw Extension 105 val mcounteren = Module(new CSRModule("Mcounteren", new Counteren)) 106 .setAddr(CSRs.mcounteren) 107 108 val mvien = Module(new CSRModule("Mvien", new MvienBundle)) 109 .setAddr(CSRs.mvien) 110 111 val mvip = Module(new CSRModule("Mvip", new MvipBundle) 112 with HasIpIeBundle 113 with HasMachineEnvBundle 114 { 115 val toMip = IO(new MvipToMip).connectZeroNonRW 116 val fromMip = IO(Flipped(new MipToMvip)) 117 val fromSip = IO(Flipped(new SipToMvip)) 118 val fromVSip = IO(Flipped(new VSipToMvip)) 119 120 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 121 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 122 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 123 // XiangShan will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one 124 reg.SSIP := Mux(wen && this.mvien.SSIE.asBool, wdata.SSIP, reg.SSIP) 125 regOut.SSIP := Mux(this.mvien.SSIE.asBool, reg.SSIP, this.mip.SSIP) 126 toMip.SSIP.valid := wen && !this.mvien.SSIE.asBool 127 toMip.SSIP.bits := wdata.SSIP 128 129 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 130 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 131 // Todo: check mip writable when menvcfg.STCE = 1 132 regOut.STIP := Mux(this.menvcfg.STCE.asBool, 0.U, this.mip.STIP.asBool) 133 // Don't update mip.STIP when menvcfg.STCE is 1 134 toMip.STIP.valid := wen && !this.menvcfg.STCE.asBool 135 toMip.STIP.bits := wdata.STIP 136 137 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 138 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 139 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 140 toMip.SEIP.valid := wen && !this.mvien.SEIE.asUInt.asBool 141 toMip.SEIP.bits := wdata.SEIP 142 when (fromMip.SEIP.valid) { 143 reg.SEIP := fromMip.SEIP.bits 144 } 145 146 // write from sip 147 when (fromSip.SSIP.valid) { 148 reg.SSIP := fromSip.SSIP.bits 149 } 150 151 reg.getLocal lazyZip fromSip.getLocal lazyZip fromVSip.getLocal foreach { case (rLCIP, sipLCIP, vsipLCIP) => 152 // sip should assert valid when mideleg=0 && mvien=1 153 when (sipLCIP.valid || vsipLCIP.valid) { 154 rLCIP := Mux1H(Seq( 155 sipLCIP .valid -> sipLCIP .bits, 156 vsipLCIP.valid -> vsipLCIP.bits, 157 )) 158 } 159 } 160 }).setAddr(CSRs.mvip) 161 162 val menvcfg = Module(new CSRModule("Menvcfg", new MEnvCfg)) 163 .setAddr(CSRs.menvcfg) 164 165 val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle)) 166 .setAddr(CSRs.mcountinhibit) 167 168 val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 169 Module(new CSRModule(s"Mhpmevent$num") with HasPerfEventBundle { 170 regOut := this.perfEvents(num - 3) 171 }) 172 .setAddr(CSRs.mhpmevent3 - 3 + num) 173 ) 174 175 val mscratch = Module(new CSRModule("Mscratch")) 176 .setAddr(CSRs.mscratch) 177 178 val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle) 179 .setAddr(CSRs.mepc) 180 181 val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle) 182 .setAddr(CSRs.mcause) 183 184 val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle) 185 .setAddr(CSRs.mtval) 186 187 val mip = Module(new CSRModule("Mip", new MipBundle) 188 with HasIpIeBundle 189 with HasExternalInterruptBundle 190 with HasMachineEnvBundle 191 with HasLocalInterruptReqBundle 192 with HasAIABundle 193 { 194 // Alias write in 195 val fromMvip = IO(Flipped(new MvipToMip)) 196 val fromSip = IO(Flipped(new SipToMip)) 197 val fromVSip = IO(Flipped(new VSipToMip)) 198 // Alias write out 199 val toMvip = IO(new MipToMvip).connectZeroNonRW 200 val toHvip = IO(new MipToHvip).connectZeroNonRW 201 202 // bit 1 SSIP 203 when (fromMvip.SSIP.valid || fromSip.SSIP.valid) { 204 reg.SSIP := Mux1H(Seq( 205 fromMvip.SSIP.valid -> fromMvip.SSIP.bits, 206 fromSip .SSIP.valid -> fromSip .SSIP.bits, 207 )) 208 } 209 210 // bit 2 VSSIP reg in hvip 211 // alias of hvip.VSSIP 212 toHvip.VSSIP.valid := wen 213 toHvip.VSSIP.bits := wdata.VSSIP 214 regOut.VSSIP := hvip.VSSIP 215 216 // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 217 // which are used by remote harts to provide machine-level interprocessor interrupts. 218 regOut.MSIP := platformIRP.MSIP 219 220 // bit 5 STIP 221 // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip. 222 regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool) 223 when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) { 224 reg.STIP := Mux1H(Seq( 225 wen -> wdata.STIP, 226 fromMvip.STIP.valid -> fromMvip.STIP.bits, 227 )) 228 } 229 230 // bit 6 VSTIP 231 regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP 232 233 // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 234 regOut.MTIP := platformIRP.MTIP 235 236 // bit 9 SEIP 237 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 238 // when bit 9 of mvien is one, bit SEIP in mip is read-only and does not include the value of bit 9 of mvip. 239 // 240 // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64), 241 // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of 242 // mip.SEIP reg and other source from the interrupt controller. 243 // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller. 244 // 245 // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0 246 // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller. 247 248 toMvip.SEIP.valid := wen && !this.mvien.SSIE 249 toMvip.SEIP.bits := wdata.SEIP 250 // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP. 251 // Otherwise, mip.SEIP is read only 0 252 regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U) 253 rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip 254 255 // bit 10 VSEIP 256 regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt) 257 258 // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 259 // MEIP can from PLIC and IMSIC 260 regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip 261 262 // bit 12 SGEIP 263 regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR 264 265 // bit 13 LCOFIP 266 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) { 267 reg.LCOFIP := Mux1H(Seq( 268 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 269 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 270 wen -> wdata.LCOFIP, 271 )) 272 }.elsewhen(lcofiReq) { 273 reg.LCOFIP := lcofiReq 274 } 275 }).setAddr(CSRs.mip) 276 277 val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle) 278 .setAddr(CSRs.mtinst) 279 280 val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle) 281 .setAddr(CSRs.mtval2) 282 283 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 284 val MLPE = RO(10) // Landing pand, Zicfilp extension 285 val SSEED = RO( 9) // Zkr extension 286 val USEED = RO( 8) // Zkr extension 287 val RLB = RO( 2) // Smepmp 288 val MMWP = RO( 1) // Smepmp 289 val MML = RO( 0) // Smepmp 290 })).setAddr(CSRs.mseccfg) 291 292 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 293 when(w.wen) { 294 reg := w.wdata 295 }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) { 296 reg := reg.ALL.asUInt + 1.U 297 }.otherwise { 298 reg := reg 299 } 300 }).setAddr(CSRs.mcycle) 301 302 303 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 304 when(w.wen) { 305 reg := w.wdata 306 }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) { 307 reg := reg.ALL.asUInt + robCommit.instNum.bits 308 }.otherwise { 309 reg := reg 310 } 311 }).setAddr(CSRs.minstret) 312 313 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 314 Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle { 315 val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn 316 val counterAdd = reg.ALL.asUInt +& perf.value 317 when (w.wen) { 318 reg := w.wdata 319 }.elsewhen (perf.value =/= 0.U && !countingInhibit) { 320 reg := counterAdd.tail(1) 321 }.otherwise { 322 reg := reg 323 } 324 // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from 325 // hardware increments of counter registers. 326 toMhpmeventOF := !countingInhibit & counterAdd.head(1) 327 }).setAddr(CSRs.mhpmcounter3 - 3 + num) 328 ) 329 330 val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U }) 331 .setAddr(CSRs.mvendorid) 332 333 // architecture id for XiangShan is 25 334 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 335 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 336 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 337 })).setAddr(CSRs.marchid) 338 339 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 340 val ALL = RO(0).withReset(0.U) 341 })) 342 .setAddr(CSRs.mimpid) 343 344 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 345 val ALL = RO(7, 0) 346 }) { 347 val hartid = IO(Input(UInt(hartIdLen.W))) 348 this.reg.ALL := RegEnable(hartid, reset.asBool) 349 }) 350 .setAddr(CSRs.mhartid) 351 352 val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle { 353 val ALL = RO(63, 0) 354 })) 355 .setAddr(CSRs.mconfigptr) 356 357 val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0) 358 359 // smrnmi extension 360 val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle { 361 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 362 }) 363 .setAddr(CSRs.mnepc) 364 365 val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle) 366 .setAddr(CSRs.mncause) 367 val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle) 368 with TrapEntryMNEventSinkBundle 369 with MNretEventSinkBundle{ 370 // NMIE write 0 with no effect 371 // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing 372 // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered 373// when(!wdata.NMIE.asBool) { 374// reg.NMIE := reg.NMIE 375// } 376 }).setAddr(CSRs.mnstatus) 377 val mnscratch = Module(new CSRModule("Mnscratch")) 378 .setAddr(CSRs.mnscratch) 379 380 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 381 mstatus, 382 misa, 383 medeleg, 384 mideleg, 385 mie, 386 mtvec, 387 mcounteren, 388 mvien, 389 mvip, 390 menvcfg, 391 mcountinhibit, 392 mscratch, 393 mepc, 394 mcause, 395 mtval, 396 mip, 397 mtinst, 398 mtval2, 399 mseccfg, 400 mcycle, 401 minstret, 402 mvendorid, 403 marchid, 404 mimpid, 405 mhartid, 406 mconfigptr, 407 mstateen0, 408 mnepc, 409 mncause, 410 mnstatus, 411 mnscratch, 412 ) ++ mhpmevents ++ mhpmcounters 413 414 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 415 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 416 ) 417 418 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 419 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 420 ) 421 422 // read/write/update mhpmevents -> read/write/update perfEvents 423 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 424 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 425 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 426 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 427 428 mhpmevents.foreach { mod => 429 mod match { 430 case m: HasPerfEventBundle => 431 m.perfEvents := perfEvents 432 case _ => 433 } 434 } 435 436} 437 438class MstatusBundle extends CSRBundle { 439 440 val SIE = CSRRWField (1).withReset(0.U) 441 val MIE = CSRRWField (3).withReset(0.U) 442 val SPIE = CSRRWField (5).withReset(0.U) 443 val UBE = CSRROField (6).withReset(0.U) 444 val MPIE = CSRRWField (7).withReset(0.U) 445 val SPP = CSRRWField (8).withReset(0.U) 446 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 447 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 448 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 449 val XS = ContextStatusRO(16, 15).withReset(0.U) 450 val MPRV = CSRRWField (17).withReset(0.U) 451 val SUM = CSRRWField (18).withReset(0.U) 452 val MXR = CSRRWField (19).withReset(0.U) 453 val TVM = CSRRWField (20).withReset(0.U) 454 val TW = CSRRWField (21).withReset(0.U) 455 val TSR = CSRRWField (22).withReset(0.U) 456 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 457 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 458 val SBE = CSRROField (36).withReset(0.U) 459 val MBE = CSRROField (37).withReset(0.U) 460 val GVA = CSRRWField (38).withReset(0.U) 461 val MPV = VirtMode (39).withReset(0.U) 462 val SD = CSRROField (63, 463 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 464 ) 465} 466 467class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 468 with TrapEntryMEventSinkBundle 469 with TrapEntryHSEventSinkBundle 470 with DretEventSinkBundle 471 with MretEventSinkBundle 472 with MNretEventSinkBundle 473 with SretEventSinkBundle 474 with HasRobCommitBundle 475{ 476 val mstatus = IO(Output(bundle)) 477 val sstatus = IO(Output(new SstatusBundle)) 478 val sstatusRdata = IO(Output(UInt(64.W))) 479 480 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 481 for ((name, field) <- wAliasSstatus.wdataFields.elements) { 482 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 483 wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal, 484 field.asInstanceOf[CSREnumType] 485 ) 486 } 487 488 // write connection 489 reconnectReg() 490 491 when (robCommit.fsDirty || writeFCSR) { 492 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 493 reg.FS := ContextStatus.Dirty 494 } 495 496 when (robCommit.vsDirty || writeVCSR) { 497 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 498 reg.VS := ContextStatus.Dirty 499 } 500 501 // read connection 502 mstatus :|= reg 503 sstatus := mstatus 504 rdata := mstatus.asUInt 505 sstatusRdata := sstatus.asUInt 506} 507 508class MnstatusBundle extends CSRBundle { 509 val NMIE = CSRRWField (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open 510 val MNPV = VirtMode (7).withReset(0.U) 511 val MNPELP = RO (9).withReset(0.U) 512 val MNPP = PrivMode (12, 11).withReset(PrivMode.U) 513} 514 515class MisaBundle extends CSRBundle { 516 // Todo: reset with ISA string 517 val A = RO( 0).withReset(1.U) // Atomic extension 518 val B = RO( 1).withReset(1.U) // B extension 519 val C = RO( 2).withReset(1.U) // Compressed extension 520 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 521 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 522 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 523 val G = RO( 6).withReset(0.U) // Reserved 524 val H = RO( 7).withReset(1.U) // Hypervisor extension 525 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 526 val J = RO( 9).withReset(0.U) // Reserved 527 val K = RO(10).withReset(0.U) // Reserved 528 val L = RO(11).withReset(0.U) // Reserved 529 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 530 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 531 val O = RO(14).withReset(0.U) // Reserved 532 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 533 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 534 val R = RO(17).withReset(0.U) // Reserved 535 val S = RO(18).withReset(1.U) // Supervisor mode implemented 536 val T = RO(19).withReset(0.U) // Reserved 537 val U = RO(20).withReset(1.U) // User mode implemented 538 val V = RO(21).withReset(1.U) // Vector extension 539 val W = RO(22).withReset(0.U) // Reserved 540 val X = RO(23).withReset(0.U) // Non-standard extensions present 541 val Y = RO(24).withReset(0.U) // Reserved 542 val Z = RO(25).withReset(0.U) // Reserved 543 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 544 545 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 546} 547 548class MedelegBundle extends ExceptionBundle { 549 this.getALL.foreach(_.setRW().withReset(0.U)) 550 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 551 this.EX_BP.setRO().withReset(0.U) // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0. 552} 553 554class MidelegBundle extends InterruptBundle { 555 this.getALL.foreach(_.setRW().withReset(0.U)) 556 // Don't delegate Machine level interrupts 557 this.getM.foreach(_.setRO().withReset(0.U)) 558 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 559 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 560 // interrupts) are each read-only one. 561 this.getVS.foreach(_.setRO().withReset(1.U)) 562 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 563 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 564 this.SGEI.setRO().withReset(1.U) 565 this.getLocal.foreach(_.setRO().withReset(0.U)) 566 this.LCOFI.setRW().withReset(0.U) 567} 568 569class MieBundle extends InterruptEnableBundle { 570 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 571 this.LCOFIE.setRW().withReset(0.U) 572} 573 574class MipBundle extends InterruptPendingBundle { 575 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 576 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 577 // 578 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 579 // while these bits in hip are aliases for the same bits in mip. 580 // 581 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 582 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 583 this.getHS.foreach(_.setRW().withReset(0.U)) 584 this.getVS.foreach(_.setRW().withReset(0.U)) 585 this.LCOFIP.setRW().withReset(0.U) 586} 587 588class MvienBundle extends InterruptEnableBundle { 589 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 590 // It is strongly recommended that bit 9 of mvien be writable. 591 // It is strongly recommended that bit 1 of mvien also be writable. 592 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 593 this.SSIE.setRW().withReset(0.U) 594 this.SEIE.setRW().withReset(0.U) 595 this.getLocal.foreach(_.setRW().withReset(0.U)) 596} 597 598class MvipBundle extends InterruptPendingBundle { 599 this.getHS.foreach(_.setRW().withReset(0.U)) 600 this.getLocal.foreach(_.setRW().withReset(0.U)) 601} 602 603class Epc extends CSRBundle { 604 val epc = RW(63, 1).withReset(0.U) 605} 606 607class McountinhibitBundle extends CSRBundle { 608 val CY = RW(0).withReset(0.U) 609 val IR = RW(2).withReset(0.U) 610 val HPM3 = RW(31, 3).withReset(0.U) 611} 612 613class Mtval2Bundle extends FieldInitBundle 614 615class MhpmcounterBundle extends FieldInitBundle 616 617// todo: for the future, delete bypass between mhpmevents and perfEvents 618class MhpmeventBundle extends CSRBundle { 619 val OF = RW(63).withReset(0.U) 620 val MINH = RW(62).withReset(0.U) 621 val SINH = RW(61).withReset(0.U) 622 val UINH = RW(60).withReset(0.U) 623 val VSINH = RW(59).withReset(0.U) 624 val VUINH = RW(58).withReset(0.U) 625} 626 627class MEnvCfg extends EnvCfg { 628 if (CSRConfig.EXT_SSTC) { 629 this.STCE.setRW().withReset(1.U) 630 } 631 this.PBMTE.setRW().withReset(0.U) 632} 633 634object MarchidField extends CSREnum with ROApply { 635 val XSArchid = Value(25.U) 636} 637 638class MieToHie extends Bundle { 639 val VSSIE = ValidIO(RW(0)) 640 val VSTIE = ValidIO(RW(0)) 641 val VSEIE = ValidIO(RW(0)) 642 val SGEIE = ValidIO(RW(0)) 643} 644 645class MvipToMip extends IpValidBundle { 646 this.getHS.foreach(_.bits.setRW()) 647} 648 649class HipToMip extends IpValidBundle { 650 // Only hip.VSSIP is writable 651 this.VSSIP.bits.setRW() 652} 653 654class VSipToMip extends IpValidBundle { 655 this.LCOFIP.bits.setRW() 656} 657 658class MipToHvip extends IpValidBundle { 659 this.VSSIP.bits.setRW() 660} 661 662class MipToMvip extends IpValidBundle { 663 this.SEIP.bits.setRW() 664} 665 666trait HasMipToAlias { self: CSRModule[_] => 667 val mipAlias = Output(new MipBundle) 668} 669 670trait HasMachineDelegBundle { self: CSRModule[_] => 671 val mideleg = IO(Input(new MidelegBundle)) 672 val medeleg = IO(Input(new MedelegBundle)) 673} 674 675trait HasExternalInterruptBundle { 676 val platformIRP = IO(new Bundle { 677 val MEIP = Input(Bool()) 678 val MTIP = Input(Bool()) 679 val MSIP = Input(Bool()) 680 val SEIP = Input(Bool()) 681 val STIP = Input(Bool()) 682 val VSEIP = Input(Bool()) 683 val VSTIP = Input(Bool()) 684 // debug interrupt from debug module 685 val debugIP = Input(Bool()) 686 }) 687} 688trait HasNonMaskableIRPBundle { 689 val nonMaskableIRP = IO(new Bundle { 690 val NMI = Input(Bool()) 691 }) 692} 693 694trait HasMachineCounterControlBundle { self: CSRModule[_] => 695 val mcountinhibit = IO(Input(new McountinhibitBundle)) 696} 697 698trait HasRobCommitBundle { self: CSRModule[_] => 699 val robCommit = IO(Input(new RobCommitCSR)) 700 val writeFCSR = IO(Input(Bool())) 701 val writeVCSR = IO(Input(Bool())) 702 val isVirtMode = IO(Input(Bool())) 703} 704 705trait HasMachineEnvBundle { self: CSRModule[_] => 706 val menvcfg = IO(Input(new MEnvCfg)) 707} 708 709trait HasPerfCounterBundle { self: CSRModule[_] => 710 val countingEn = IO(Input(Bool())) 711 val perf = IO(Input(new PerfEvent)) 712 val toMhpmeventOF = IO(Output(Bool())) 713} 714 715trait HasPerfEventBundle { self: CSRModule[_] => 716 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 717} 718 719trait HasLocalInterruptReqBundle { self: CSRModule[_] => 720 val lcofiReq = IO(Input(Bool())) 721}