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 reg.LCOFIP := lcofiReq 267 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) { 268 reg.LCOFIP := Mux1H(Seq( 269 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 270 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 271 wen -> wdata.LCOFIP, 272 )) 273 } 274 }).setAddr(CSRs.mip) 275 276 val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle) 277 .setAddr(CSRs.mtinst) 278 279 val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle) 280 .setAddr(CSRs.mtval2) 281 282 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 283 val PMM = RO(33, 32) 284 val SSEED = RO( 9) 285 val USEED = RO( 8) 286 val RLB = RO( 2) 287 val MMWP = RO( 1) 288 val MML = RO( 0) 289 })).setAddr(CSRs.mseccfg) 290 291 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 292 when(w.wen) { 293 reg := w.wdata 294 }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) { 295 reg := reg.ALL.asUInt + 1.U 296 }.otherwise { 297 reg := reg 298 } 299 }).setAddr(CSRs.mcycle) 300 301 302 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 303 when(w.wen) { 304 reg := w.wdata 305 }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) { 306 reg := reg.ALL.asUInt + robCommit.instNum.bits 307 }.otherwise { 308 reg := reg 309 } 310 }).setAddr(CSRs.minstret) 311 312 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 313 Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle { 314 val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn 315 val counterAdd = reg.ALL.asUInt +& perf.value 316 when (w.wen) { 317 reg := w.wdata 318 }.elsewhen (perf.value =/= 0.U && !countingInhibit) { 319 reg := counterAdd.tail(1) 320 }.otherwise { 321 reg := reg 322 } 323 // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from 324 // hardware increments of counter registers. 325 toMhpmeventOF := !countingInhibit & counterAdd.head(1) 326 }).setAddr(CSRs.mhpmcounter3 - 3 + num) 327 ) 328 329 val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U }) 330 .setAddr(CSRs.mvendorid) 331 332 // architecture id for XiangShan is 25 333 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 334 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 335 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 336 })).setAddr(CSRs.marchid) 337 338 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 339 val ALL = RO(0).withReset(0.U) 340 })) 341 .setAddr(CSRs.mimpid) 342 343 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 344 val ALL = RO(7, 0) 345 }) { 346 val hartid = IO(Input(UInt(hartIdLen.W))) 347 this.reg.ALL := RegEnable(hartid, reset.asBool) 348 }) 349 .setAddr(CSRs.mhartid) 350 351 val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle { 352 val ALL = RO(63, 0) 353 })) 354 .setAddr(CSRs.mconfigptr) 355 356 val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0) 357 358 // smrnmi extension 359 val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle { 360 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 361 }) 362 .setAddr(CSRs.mnepc) 363 364 val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle) 365 .setAddr(CSRs.mncause) 366 val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle) 367 with TrapEntryMNEventSinkBundle 368 with MNretEventSinkBundle{ 369 // NMIE write 0 with no effect 370 // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing 371 // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered 372// when(!wdata.NMIE.asBool) { 373// reg.NMIE := reg.NMIE 374// } 375 }).setAddr(CSRs.mnstatus) 376 val mnscratch = Module(new CSRModule("Mnscratch")) 377 .setAddr(CSRs.mnscratch) 378 379 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 380 mstatus, 381 misa, 382 medeleg, 383 mideleg, 384 mie, 385 mtvec, 386 mcounteren, 387 mvien, 388 mvip, 389 menvcfg, 390 mcountinhibit, 391 mscratch, 392 mepc, 393 mcause, 394 mtval, 395 mip, 396 mtinst, 397 mtval2, 398 mseccfg, 399 mcycle, 400 minstret, 401 mvendorid, 402 marchid, 403 mimpid, 404 mhartid, 405 mconfigptr, 406 mstateen0, 407 mnepc, 408 mncause, 409 mnstatus, 410 mnscratch, 411 ) ++ mhpmevents ++ mhpmcounters 412 413 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 414 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 415 ) 416 417 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 418 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 419 ) 420 421 // read/write/update mhpmevents -> read/write/update perfEvents 422 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 423 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 424 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 425 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 426 427 mhpmevents.foreach { mod => 428 mod match { 429 case m: HasPerfEventBundle => 430 m.perfEvents := perfEvents 431 case _ => 432 } 433 } 434 435} 436 437class MstatusBundle extends CSRBundle { 438 439 val SIE = CSRRWField (1).withReset(0.U) 440 val MIE = CSRRWField (3).withReset(0.U) 441 val SPIE = CSRRWField (5).withReset(0.U) 442 val UBE = CSRROField (6).withReset(0.U) 443 val MPIE = CSRRWField (7).withReset(0.U) 444 val SPP = CSRRWField (8).withReset(0.U) 445 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 446 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 447 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 448 val XS = ContextStatusRO(16, 15).withReset(0.U) 449 val MPRV = CSRRWField (17).withReset(0.U) 450 val SUM = CSRRWField (18).withReset(0.U) 451 val MXR = CSRRWField (19).withReset(0.U) 452 val TVM = CSRRWField (20).withReset(0.U) 453 val TW = CSRRWField (21).withReset(0.U) 454 val TSR = CSRRWField (22).withReset(0.U) 455 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 456 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 457 val SBE = CSRROField (36).withReset(0.U) 458 val MBE = CSRROField (37).withReset(0.U) 459 val GVA = CSRRWField (38).withReset(0.U) 460 val MPV = VirtMode (39).withReset(0.U) 461 val SD = CSRROField (63, 462 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 463 ) 464} 465 466class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 467 with TrapEntryMEventSinkBundle 468 with TrapEntryHSEventSinkBundle 469 with DretEventSinkBundle 470 with MretEventSinkBundle 471 with MNretEventSinkBundle 472 with SretEventSinkBundle 473 with HasRobCommitBundle 474{ 475 val mstatus = IO(Output(bundle)) 476 val sstatus = IO(Output(new SstatusBundle)) 477 val sstatusRdata = IO(Output(UInt(64.W))) 478 479 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 480 481 // write connection 482 this.wfn(reg)(Seq(wAliasSstatus)) 483 484 when (robCommit.fsDirty || writeFCSR) { 485 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 486 reg.FS := ContextStatus.Dirty 487 } 488 489 when (robCommit.vsDirty || writeVCSR) { 490 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 491 reg.VS := ContextStatus.Dirty 492 } 493 494 // read connection 495 mstatus :|= reg 496 sstatus := mstatus 497 rdata := mstatus.asUInt 498 sstatusRdata := sstatus.asUInt 499} 500class MnstatusBundle extends CSRBundle { 501 502 val NMIE = CSRRWField (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open 503 val MNPV = VirtMode (7).withReset(0.U) 504 val MNPELP = CSRRWField (9).withReset(0.U) 505 val MNPP = PrivMode (12, 11).withReset(PrivMode.U) 506} 507class MisaBundle extends CSRBundle { 508 // Todo: reset with ISA string 509 val A = RO( 0).withReset(1.U) // Atomic extension 510 val B = RO( 1).withReset(1.U) // B extension 511 val C = RO( 2).withReset(1.U) // Compressed extension 512 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 513 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 514 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 515 val G = RO( 6).withReset(0.U) // Reserved 516 val H = RO( 7).withReset(1.U) // Hypervisor extension 517 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 518 val J = RO( 9).withReset(0.U) // Reserved 519 val K = RO(10).withReset(0.U) // Reserved 520 val L = RO(11).withReset(0.U) // Reserved 521 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 522 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 523 val O = RO(14).withReset(0.U) // Reserved 524 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 525 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 526 val R = RO(17).withReset(0.U) // Reserved 527 val S = RO(18).withReset(1.U) // Supervisor mode implemented 528 val T = RO(19).withReset(0.U) // Reserved 529 val U = RO(20).withReset(1.U) // User mode implemented 530 val V = RO(21).withReset(1.U) // Vector extension 531 val W = RO(22).withReset(0.U) // Reserved 532 val X = RO(23).withReset(0.U) // Non-standard extensions present 533 val Y = RO(24).withReset(0.U) // Reserved 534 val Z = RO(25).withReset(0.U) // Reserved 535 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 536 537 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 538} 539 540class MedelegBundle extends ExceptionBundle { 541 this.getALL.foreach(_.setRW().withReset(0.U)) 542 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 543 this.EX_BP.setRO().withReset(0.U) // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0. 544} 545 546class MidelegBundle extends InterruptBundle { 547 this.getALL.foreach(_.setRW().withReset(0.U)) 548 // Don't delegate Machine level interrupts 549 this.getM.foreach(_.setRO().withReset(0.U)) 550 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 551 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 552 // interrupts) are each read-only one. 553 this.getVS.foreach(_.setRO().withReset(1.U)) 554 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 555 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 556 this.SGEI.setRO().withReset(1.U) 557 this.getLocal.foreach(_.setRO().withReset(0.U)) 558 this.LCOFI.setRW().withReset(0.U) 559} 560 561class MieBundle extends InterruptEnableBundle { 562 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 563 this.LCOFIE.setRW().withReset(0.U) 564} 565 566class MipBundle extends InterruptPendingBundle { 567 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 568 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 569 // 570 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 571 // while these bits in hip are aliases for the same bits in mip. 572 // 573 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 574 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 575 this.getHS.foreach(_.setRW().withReset(0.U)) 576 this.getVS.foreach(_.setRW().withReset(0.U)) 577 this.LCOFIP.setRW().withReset(0.U) 578} 579 580class MvienBundle extends InterruptEnableBundle { 581 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 582 // It is strongly recommended that bit 9 of mvien be writable. 583 // It is strongly recommended that bit 1 of mvien also be writable. 584 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 585 this.SSIE.setRW().withReset(0.U) 586 this.SEIE.setRW().withReset(0.U) 587 this.getLocal.foreach(_.setRW().withReset(0.U)) 588} 589 590class MvipBundle extends InterruptPendingBundle { 591 this.getHS.foreach(_.setRW().withReset(0.U)) 592 this.getLocal.foreach(_.setRW().withReset(0.U)) 593} 594 595class Epc extends CSRBundle { 596 val epc = RW(63, 1).withReset(0.U) 597} 598 599class McountinhibitBundle extends CSRBundle { 600 val CY = RW(0).withReset(0.U) 601 val IR = RW(2).withReset(0.U) 602 val HPM3 = RW(31, 3).withReset(0.U) 603} 604 605class Mtval2Bundle extends FieldInitBundle 606 607class MhpmcounterBundle extends FieldInitBundle 608 609// todo: for the future, delete bypass between mhpmevents and perfEvents 610class MhpmeventBundle extends CSRBundle { 611 val OF = RW(63).withReset(0.U) 612 val MINH = RW(62).withReset(0.U) 613 val SINH = RW(61).withReset(0.U) 614 val UINH = RW(60).withReset(0.U) 615 val VSINH = RW(59).withReset(0.U) 616 val VUINH = RW(58).withReset(0.U) 617} 618 619class MEnvCfg extends EnvCfg { 620 if (CSRConfig.EXT_SSTC) { 621 this.STCE.setRW().withReset(1.U) 622 } 623} 624 625object MarchidField extends CSREnum with ROApply { 626 val XSArchid = Value(25.U) 627} 628 629class MieToHie extends Bundle { 630 val VSSIE = ValidIO(RW(0)) 631 val VSTIE = ValidIO(RW(0)) 632 val VSEIE = ValidIO(RW(0)) 633 val SGEIE = ValidIO(RW(0)) 634} 635 636class MvipToMip extends IpValidBundle { 637 this.getHS.foreach(_.bits.setRW()) 638} 639 640class HipToMip extends IpValidBundle { 641 // Only hip.VSSIP is writable 642 this.VSSIP.bits.setRW() 643} 644 645class VSipToMip extends IpValidBundle { 646 this.LCOFIP.bits.setRW() 647} 648 649class MipToHvip extends IpValidBundle { 650 this.VSSIP.bits.setRW() 651} 652 653class MipToMvip extends IpValidBundle { 654 this.SEIP.bits.setRW() 655} 656 657trait HasMipToAlias { self: CSRModule[_] => 658 val mipAlias = Output(new MipBundle) 659} 660 661trait HasMachineDelegBundle { self: CSRModule[_] => 662 val mideleg = IO(Input(new MidelegBundle)) 663 val medeleg = IO(Input(new MedelegBundle)) 664} 665 666trait HasExternalInterruptBundle { 667 val platformIRP = IO(new Bundle { 668 val MEIP = Input(Bool()) 669 val MTIP = Input(Bool()) 670 val MSIP = Input(Bool()) 671 val SEIP = Input(Bool()) 672 val STIP = Input(Bool()) 673 val VSEIP = Input(Bool()) 674 val VSTIP = Input(Bool()) 675 // debug interrupt from debug module 676 val debugIP = Input(Bool()) 677 }) 678} 679trait HasNonMaskableIRPBundle { 680 val nonMaskableIRP = IO(new Bundle { 681 val NMI = Input(Bool()) 682 }) 683} 684 685trait HasMachineCounterControlBundle { self: CSRModule[_] => 686 val mcountinhibit = IO(Input(new McountinhibitBundle)) 687} 688 689trait HasRobCommitBundle { self: CSRModule[_] => 690 val robCommit = IO(Input(new RobCommitCSR)) 691 val writeFCSR = IO(Input(Bool())) 692 val writeVCSR = IO(Input(Bool())) 693 val isVirtMode = IO(Input(Bool())) 694} 695 696trait HasMachineEnvBundle { self: CSRModule[_] => 697 val menvcfg = IO(Input(new MEnvCfg)) 698} 699 700trait HasPerfCounterBundle { self: CSRModule[_] => 701 val countingEn = IO(Input(Bool())) 702 val perf = IO(Input(new PerfEvent)) 703 val toMhpmeventOF = IO(Output(Bool())) 704} 705 706trait HasPerfEventBundle { self: CSRModule[_] => 707 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 708} 709 710trait HasLocalInterruptReqBundle { self: CSRModule[_] => 711 val lcofiReq = IO(Input(Bool())) 712}