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, PerfEvent} 9import xiangshan.backend.fu.NewCSR.CSRBundles._ 10import xiangshan.backend.fu.NewCSR.CSRDefines._ 11import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 12import xiangshan.backend.fu.NewCSR.CSREvents._ 13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 14import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 15import xiangshan.backend.fu.PerfCounterIO 16import xiangshan.backend.fu.NewCSR.CSRConfig._ 17import xiangshan.backend.fu.NewCSR.CSRFunc.wNoEffectWhen 18 19import scala.collection.immutable.SeqMap 20 21trait MachineLevel { self: NewCSR => 22 val mstatus = Module(new MstatusModule) 23 .setAddr(CSRs.mstatus) 24 25 val misa = Module(new CSRModule("Misa", new MisaBundle)) 26 .setAddr(CSRs.misa) 27 28 println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}") 29 30 val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle)) 31 .setAddr(CSRs.medeleg) 32 33 val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle)) 34 .setAddr(CSRs.mideleg) 35 36 val mie = Module(new CSRModule("Mie", new MieBundle) with HasIpIeBundle { 37 val fromHie = IO(Flipped(new HieToMie)) 38 val fromSie = IO(Flipped(new SieToMie)) 39 val fromVSie = IO(Flipped(new VSieToMie)) 40 41 // bit 1 SSIE 42 when (fromSie.SSIE.valid) { 43 reg.SSIE := fromSie.SSIE.bits 44 } 45 46 // bit 2 VSSIE 47 when (fromHie.VSSIE.valid || fromVSie.VSSIE.valid) { 48 reg.VSSIE := Mux1H(Seq( 49 fromHie .VSSIE.valid -> fromHie .VSSIE.bits, 50 fromVSie.VSSIE.valid -> fromVSie.VSSIE.bits, 51 )) 52 } 53 54 // bit 5 STIE 55 when(fromSie.STIE.valid) { 56 reg.STIE := fromSie.STIE.bits 57 } 58 59 // bit 6 VSTIE 60 when(fromHie.VSTIE.valid || fromVSie.VSTIE.valid) { 61 reg.VSTIE := Mux1H(Seq( 62 fromHie .VSTIE.valid -> fromHie .VSTIE.bits, 63 fromVSie.VSTIE.valid -> fromVSie.VSTIE.bits, 64 )) 65 } 66 67 // bit 9 SEIE 68 when(fromSie.SEIE.valid) { 69 reg.SEIE := fromSie.SEIE.bits 70 } 71 72 // bit 10 VSEIE 73 when(fromHie.VSEIE.valid || fromVSie.VSEIE.valid) { 74 reg.VSEIE := Mux1H(Seq( 75 fromHie .VSEIE.valid -> fromHie .VSEIE.bits, 76 fromVSie.VSEIE.valid -> fromVSie.VSEIE.bits, 77 )) 78 } 79 80 // bit 12 SGEIE 81 when(fromHie.SGEIE.valid) { 82 reg.SGEIE := fromHie.SGEIE.bits 83 } 84 85 // bit 13~63 LCIP 86 reg.getLocal lazyZip fromSie.getLocal lazyZip fromVSie.getLocal foreach { case (rLCIE, sieLCIE, vsieLCIE) => 87 when (sieLCIE.valid || vsieLCIE.valid) { 88 rLCIE := Mux1H(Seq( 89 sieLCIE .valid -> sieLCIE .bits, 90 vsieLCIE.valid -> vsieLCIE.bits, 91 )) 92 } 93 } 94 95 // 14~63 read only 0 96 regOut.getLocal.filterNot(_.lsb == InterruptNO.COI).foreach(_ := 0.U) 97 }).setAddr(CSRs.mie) 98 99 val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle)) 100 .setAddr(CSRs.mtvec) 101 102 // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0 103 // Todo: support Sscounterenw Extension 104 val mcounteren = Module(new CSRModule("Mcounteren", new Counteren)) 105 .setAddr(CSRs.mcounteren) 106 107 val mvien = Module(new CSRModule("Mvien", new MvienBundle)) 108 .setAddr(CSRs.mvien) 109 110 val mvip = Module(new CSRModule("Mvip", new MvipBundle) 111 with HasIpIeBundle 112 with HasMachineEnvBundle 113 { 114 val toMip = IO(new MvipToMip).connectZeroNonRW 115 val fromMip = IO(Flipped(new MipToMvip)) 116 val fromSip = IO(Flipped(new SipToMvip)) 117 val fromVSip = IO(Flipped(new VSipToMvip)) 118 119 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 120 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 121 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 122 // XiangShan will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one 123 reg.SSIP := Mux(wen && this.mvien.SSIE.asBool, wdata.SSIP, reg.SSIP) 124 regOut.SSIP := Mux(this.mvien.SSIE.asBool, reg.SSIP, this.mip.SSIP) 125 toMip.SSIP.valid := wen && !this.mvien.SSIE.asBool 126 toMip.SSIP.bits := wdata.SSIP 127 128 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 129 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 130 // Todo: check mip writable when menvcfg.STCE = 1 131 regOut.STIP := Mux(this.menvcfg.STCE.asBool, 0.U, this.mip.STIP.asBool) 132 // Don't update mip.STIP when menvcfg.STCE is 1 133 toMip.STIP.valid := wen && !this.menvcfg.STCE.asBool 134 toMip.STIP.bits := wdata.STIP 135 136 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 137 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 138 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 139 toMip.SEIP.valid := wen && !this.mvien.SEIE.asUInt.asBool 140 toMip.SEIP.bits := wdata.SEIP 141 when (fromMip.SEIP.valid) { 142 reg.SEIP := fromMip.SEIP.bits 143 } 144 145 // write from sip 146 when (fromSip.SSIP.valid) { 147 reg.SSIP := fromSip.SSIP.bits 148 } 149 150 reg.getLocal lazyZip fromSip.getLocal lazyZip fromVSip.getLocal foreach { case (rLCIP, sipLCIP, vsipLCIP) => 151 // sip should assert valid when mideleg=0 && mvien=1 152 when (sipLCIP.valid || vsipLCIP.valid) { 153 rLCIP := Mux1H(Seq( 154 sipLCIP .valid -> sipLCIP .bits, 155 vsipLCIP.valid -> vsipLCIP.bits, 156 )) 157 } 158 } 159 }).setAddr(CSRs.mvip) 160 161 val menvcfg = Module(new CSRModule("Menvcfg", new MEnvCfg)) 162 .setAddr(CSRs.menvcfg) 163 164 val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle)) 165 .setAddr(CSRs.mcountinhibit) 166 167 val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 168 Module(new CSRModule(s"Mhpmevent$num") with HasPerfEventBundle { 169 regOut := this.perfEvents(num - 3) 170 }) 171 .setAddr(CSRs.mhpmevent3 - 3 + num) 172 ) 173 174 val mscratch = Module(new CSRModule("Mscratch")) 175 .setAddr(CSRs.mscratch) 176 177 val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle) 178 .setAddr(CSRs.mepc) 179 180 val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle) 181 .setAddr(CSRs.mcause) 182 183 val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle) 184 .setAddr(CSRs.mtval) 185 186 val mip = Module(new CSRModule("Mip", new MipBundle) 187 with HasIpIeBundle 188 with HasExternalInterruptBundle 189 with HasMachineEnvBundle 190 with HasLocalInterruptReqBundle 191 with HasAIABundle 192 { 193 // Alias write in 194 val fromMvip = IO(Flipped(new MvipToMip)) 195 val fromSip = IO(Flipped(new SipToMip)) 196 val fromVSip = IO(Flipped(new VSipToMip)) 197 // Alias write out 198 val toMvip = IO(new MipToMvip).connectZeroNonRW 199 val toHvip = IO(new MipToHvip).connectZeroNonRW 200 201 // bit 1 SSIP 202 when (fromMvip.SSIP.valid || fromSip.SSIP.valid) { 203 reg.SSIP := Mux1H(Seq( 204 fromMvip.SSIP.valid -> fromMvip.SSIP.bits, 205 fromSip .SSIP.valid -> fromSip .SSIP.bits, 206 )) 207 } 208 209 // bit 2 VSSIP reg in hvip 210 // alias of hvip.VSSIP 211 toHvip.VSSIP.valid := wen 212 toHvip.VSSIP.bits := wdata.VSSIP 213 regOut.VSSIP := hvip.VSSIP 214 215 // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 216 // which are used by remote harts to provide machine-level interprocessor interrupts. 217 regOut.MSIP := platformIRP.MSIP 218 219 // bit 5 STIP 220 // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip. 221 regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool) 222 when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) { 223 reg.STIP := Mux1H(Seq( 224 wen -> wdata.STIP, 225 fromMvip.STIP.valid -> fromMvip.STIP.bits, 226 )) 227 } 228 229 // bit 6 VSTIP 230 regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP 231 232 // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 233 regOut.MTIP := platformIRP.MTIP 234 235 // bit 9 SEIP 236 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 237 // 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. 238 // 239 // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64), 240 // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of 241 // mip.SEIP reg and other source from the interrupt controller. 242 // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller. 243 // 244 // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0 245 // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller. 246 247 toMvip.SEIP.valid := wen && !this.mvien.SSIE 248 toMvip.SEIP.bits := wdata.SEIP 249 // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP. 250 // Otherwise, mip.SEIP is read only 0 251 regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U) 252 rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip 253 254 // bit 10 VSEIP 255 regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt) 256 257 // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 258 // MEIP can from PLIC and IMSIC 259 regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip 260 261 // bit 12 SGEIP 262 regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR 263 264 // bit 13 LCOFIP 265 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) { 266 reg.LCOFIP := Mux1H(Seq( 267 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 268 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 269 wen -> wdata.LCOFIP, 270 )) 271 }.elsewhen(lcofiReq) { 272 reg.LCOFIP := lcofiReq 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 MLPE = RO(10) // Landing pand, Zicfilp extension 284 val SSEED = RO( 9) // Zkr extension 285 val USEED = RO( 8) // Zkr extension 286 val RLB = RO( 2) // Smepmp 287 val MMWP = RO( 1) // Smepmp 288 val MML = RO( 0) // Smepmp 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(hartIdLen - 1, 0) 345 }) { 346 val hartid = IO(Input(UInt(hartIdLen.W))) 347 this.regOut.ALL := hartid 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 SDT = CSRRWField (24).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 MDT = CSRRWField (42).withReset(mdtInit.U) 463 val SD = CSRROField (63, 464 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 465 ) 466} 467 468class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 469 with TrapEntryMEventSinkBundle 470 with TrapEntryHSEventSinkBundle 471 with DretEventSinkBundle 472 with MretEventSinkBundle 473 with MNretEventSinkBundle 474 with SretEventSinkBundle 475 with HasRobCommitBundle 476 with HasMachineEnvBundle 477{ 478 val mstatus = IO(Output(bundle)) 479 val sstatus = IO(Output(new SstatusBundle)) 480 val sstatusRdata = IO(Output(UInt(64.W))) 481 482 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 483 for ((name, field) <- wAliasSstatus.wdataFields.elements) { 484 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 485 wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal, 486 field.asInstanceOf[CSREnumType] 487 ) 488 } 489 490 // write connection 491 reconnectReg() 492 493 when (robCommit.fsDirty || writeFCSR) { 494 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 495 reg.FS := ContextStatus.Dirty 496 } 497 498 when (robCommit.vsDirty || writeVCSR) { 499 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 500 reg.VS := ContextStatus.Dirty 501 } 502 // when MDT is explicitly written by 1, clear MIE 503 // only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1 504 when (w.wdataFields.MDT && w.wen) { 505 reg.MIE := false.B 506 } 507 // when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block) 508 val writeSDT = Wire(Bool()) 509 writeSDT := Mux(this.menvcfg.DTE.asBool, (w.wdataFields.SDT && w.wen) || (wAliasSstatus.wdataFields.SDT && wAliasSstatus.wen), 0.U) 510 when (!this.menvcfg.DTE) { 511 regOut.SDT := false.B 512 } 513 // SDT and SIE is the same as MDT and MIE 514 when (writeSDT) { 515 reg.SIE := false.B 516 } 517 // read connection 518 mstatus :|= regOut 519 sstatus := mstatus 520 rdata := mstatus.asUInt 521 sstatusRdata := sstatus.asUInt 522} 523 524class MnstatusBundle extends CSRBundle { 525 val NMIE = CSRRWField (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open 526 val MNPV = VirtMode (7).withReset(0.U) 527 val MNPELP = RO (9).withReset(0.U) 528 val MNPP = PrivMode (12, 11).withReset(PrivMode.U) 529} 530 531class MisaBundle extends CSRBundle { 532 // Todo: reset with ISA string 533 val A = RO( 0).withReset(1.U) // Atomic extension 534 val B = RO( 1).withReset(1.U) // B extension 535 val C = RO( 2).withReset(1.U) // Compressed extension 536 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 537 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 538 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 539 val G = RO( 6).withReset(0.U) // Reserved 540 val H = RO( 7).withReset(1.U) // Hypervisor extension 541 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 542 val J = RO( 9).withReset(0.U) // Reserved 543 val K = RO(10).withReset(0.U) // Reserved 544 val L = RO(11).withReset(0.U) // Reserved 545 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 546 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 547 val O = RO(14).withReset(0.U) // Reserved 548 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 549 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 550 val R = RO(17).withReset(0.U) // Reserved 551 val S = RO(18).withReset(1.U) // Supervisor mode implemented 552 val T = RO(19).withReset(0.U) // Reserved 553 val U = RO(20).withReset(1.U) // User mode implemented 554 val V = RO(21).withReset(1.U) // Vector extension 555 val W = RO(22).withReset(0.U) // Reserved 556 val X = RO(23).withReset(0.U) // Non-standard extensions present 557 val Y = RO(24).withReset(0.U) // Reserved 558 val Z = RO(25).withReset(0.U) // Reserved 559 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 560 561 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 562} 563 564class MedelegBundle extends ExceptionBundle { 565 this.getALL.foreach(_.setRW().withReset(0.U)) 566 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 567 this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable 568} 569 570class MidelegBundle extends InterruptBundle { 571 this.getALL.foreach(_.setRW().withReset(0.U)) 572 // Don't delegate Machine level interrupts 573 this.getM.foreach(_.setRO().withReset(0.U)) 574 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 575 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 576 // interrupts) are each read-only one. 577 this.getVS.foreach(_.setRO().withReset(1.U)) 578 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 579 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 580 this.SGEI.setRO().withReset(1.U) 581 this.getLocal.foreach(_.setRO().withReset(0.U)) 582 this.LCOFI.setRW().withReset(0.U) 583} 584 585class MieBundle extends InterruptEnableBundle { 586 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 587 this.LCOFIE.setRW().withReset(0.U) 588} 589 590class MipBundle extends InterruptPendingBundle { 591 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 592 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 593 // 594 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 595 // while these bits in hip are aliases for the same bits in mip. 596 // 597 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 598 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 599 this.getHS.foreach(_.setRW().withReset(0.U)) 600 this.getVS.foreach(_.setRW().withReset(0.U)) 601 this.LCOFIP.setRW().withReset(0.U) 602} 603 604class MvienBundle extends InterruptEnableBundle { 605 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 606 // It is strongly recommended that bit 9 of mvien be writable. 607 // It is strongly recommended that bit 1 of mvien also be writable. 608 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 609 this.SSIE.setRW().withReset(0.U) 610 this.SEIE.setRW().withReset(0.U) 611 this.getLocal.foreach(_.setRW().withReset(0.U)) 612} 613 614class MvipBundle extends InterruptPendingBundle { 615 this.getHS.foreach(_.setRW().withReset(0.U)) 616 this.getLocal.foreach(_.setRW().withReset(0.U)) 617} 618 619class Epc extends CSRBundle { 620 val epc = RW(63, 1).withReset(0.U) 621} 622 623class McountinhibitBundle extends CSRBundle { 624 val CY = RW(0).withReset(0.U) 625 val IR = RW(2).withReset(0.U) 626 val HPM3 = RW(31, 3).withReset(0.U) 627} 628 629class Mtval2Bundle extends FieldInitBundle 630 631class MhpmcounterBundle extends FieldInitBundle 632 633// todo: for the future, delete bypass between mhpmevents and perfEvents 634class MhpmeventBundle extends CSRBundle { 635 val OF = RW(63).withReset(0.U) 636 val MINH = RW(62).withReset(0.U) 637 val SINH = RW(61).withReset(0.U) 638 val UINH = RW(60).withReset(0.U) 639 val VSINH = RW(59).withReset(0.U) 640 val VUINH = RW(58).withReset(0.U) 641} 642 643class MEnvCfg extends EnvCfg { 644 if (CSRConfig.EXT_SSTC) { 645 this.STCE.setRW().withReset(1.U) 646 } 647 this.PBMTE.setRW().withReset(0.U) 648 if (CSRConfig.EXT_DBLTRP) { 649 // software write envcfg to open ssdbltrp if need 650 // set 0 to pass ci 651 this.DTE.setRW().withReset(0.U) 652 } 653} 654 655object MarchidField extends CSREnum with ROApply { 656 val XSArchid = Value(25.U) 657} 658 659class MieToHie extends Bundle { 660 val VSSIE = ValidIO(RW(0)) 661 val VSTIE = ValidIO(RW(0)) 662 val VSEIE = ValidIO(RW(0)) 663 val SGEIE = ValidIO(RW(0)) 664} 665 666class MvipToMip extends IpValidBundle { 667 this.getHS.foreach(_.bits.setRW()) 668} 669 670class HipToMip extends IpValidBundle { 671 // Only hip.VSSIP is writable 672 this.VSSIP.bits.setRW() 673} 674 675class VSipToMip extends IpValidBundle { 676 this.LCOFIP.bits.setRW() 677} 678 679class MipToHvip extends IpValidBundle { 680 this.VSSIP.bits.setRW() 681} 682 683class MipToMvip extends IpValidBundle { 684 this.SEIP.bits.setRW() 685} 686 687trait HasMipToAlias { self: CSRModule[_] => 688 val mipAlias = Output(new MipBundle) 689} 690 691trait HasMachineDelegBundle { self: CSRModule[_] => 692 val mideleg = IO(Input(new MidelegBundle)) 693 val medeleg = IO(Input(new MedelegBundle)) 694} 695 696trait HasExternalInterruptBundle { 697 val platformIRP = IO(new Bundle { 698 val MEIP = Input(Bool()) 699 val MTIP = Input(Bool()) 700 val MSIP = Input(Bool()) 701 val SEIP = Input(Bool()) 702 val STIP = Input(Bool()) 703 val VSEIP = Input(Bool()) 704 val VSTIP = Input(Bool()) 705 // debug interrupt from debug module 706 val debugIP = Input(Bool()) 707 }) 708} 709trait HasNonMaskableIRPBundle { 710 val nonMaskableIRP = IO(new Bundle { 711 val NMI_43 = Input(Bool()) 712 val NMI_31 = Input(Bool()) 713 }) 714} 715 716trait HasMachineCounterControlBundle { self: CSRModule[_] => 717 val mcountinhibit = IO(Input(new McountinhibitBundle)) 718} 719 720trait HasRobCommitBundle { self: CSRModule[_] => 721 val robCommit = IO(Input(new RobCommitCSR)) 722 val writeFCSR = IO(Input(Bool())) 723 val writeVCSR = IO(Input(Bool())) 724 val isVirtMode = IO(Input(Bool())) 725} 726 727trait HasMachineEnvBundle { self: CSRModule[_] => 728 val menvcfg = IO(Input(new MEnvCfg)) 729} 730 731trait HasPerfCounterBundle { self: CSRModule[_] => 732 val countingEn = IO(Input(Bool())) 733 val perf = IO(Input(new PerfEvent)) 734 val toMhpmeventOF = IO(Output(Bool())) 735} 736 737trait HasPerfEventBundle { self: CSRModule[_] => 738 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 739} 740 741trait HasLocalInterruptReqBundle { self: CSRModule[_] => 742 val lcofiReq = IO(Input(Bool())) 743}