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._ 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", new MhpmeventBundle) with HasOfFromPerfCntBundle { 169 when(wen){ 170 reg.OF := wdata.OF 171 }.elsewhen(ofFromPerfCnt) { 172 reg.OF := ofFromPerfCnt 173 } 174 }) 175 .setAddr(CSRs.mhpmevent3 - 3 + num) 176 ) 177 178 val mscratch = Module(new CSRModule("Mscratch")) 179 .setAddr(CSRs.mscratch) 180 181 val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle) 182 .setAddr(CSRs.mepc) 183 184 val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle) 185 .setAddr(CSRs.mcause) 186 187 val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle) 188 .setAddr(CSRs.mtval) 189 190 val mip = Module(new CSRModule("Mip", new MipBundle) 191 with HasIpIeBundle 192 with HasExternalInterruptBundle 193 with HasMachineEnvBundle 194 with HasLocalInterruptReqBundle 195 with HasAIABundle 196 { 197 // Alias write in 198 val fromMvip = IO(Flipped(new MvipToMip)) 199 val fromSip = IO(Flipped(new SipToMip)) 200 val fromVSip = IO(Flipped(new VSipToMip)) 201 // Alias write out 202 val toMvip = IO(new MipToMvip).connectZeroNonRW 203 val toHvip = IO(new MipToHvip).connectZeroNonRW 204 205 // bit 1 SSIP 206 when (fromMvip.SSIP.valid || fromSip.SSIP.valid) { 207 reg.SSIP := Mux1H(Seq( 208 fromMvip.SSIP.valid -> fromMvip.SSIP.bits, 209 fromSip .SSIP.valid -> fromSip .SSIP.bits, 210 )) 211 } 212 213 // bit 2 VSSIP reg in hvip 214 // alias of hvip.VSSIP 215 toHvip.VSSIP.valid := wen 216 toHvip.VSSIP.bits := wdata.VSSIP 217 regOut.VSSIP := hvip.VSSIP 218 219 // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 220 // which are used by remote harts to provide machine-level interprocessor interrupts. 221 regOut.MSIP := platformIRP.MSIP 222 223 // bit 5 STIP 224 // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip. 225 regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool) 226 when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) { 227 reg.STIP := Mux1H(Seq( 228 wen -> wdata.STIP, 229 fromMvip.STIP.valid -> fromMvip.STIP.bits, 230 )) 231 }.otherwise { 232 reg.STIP := reg.STIP 233 } 234 235 // bit 6 VSTIP 236 regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP 237 238 // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 239 regOut.MTIP := platformIRP.MTIP 240 241 // bit 9 SEIP 242 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 243 // 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. 244 // 245 // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64), 246 // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of 247 // mip.SEIP reg and other source from the interrupt controller. 248 // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller. 249 // 250 // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0 251 // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller. 252 253 toMvip.SEIP.valid := wen && !this.mvien.SEIE 254 toMvip.SEIP.bits := wdata.SEIP 255 // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP. 256 // Otherwise, mip.SEIP is read only 0 257 regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U) 258 rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip 259 260 // bit 10 VSEIP 261 regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt) 262 263 // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 264 // MEIP can from PLIC and IMSIC 265 regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip 266 267 // bit 12 SGEIP 268 regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR 269 270 // bit 13 LCOFIP 271 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) { 272 reg.LCOFIP := Mux1H(Seq( 273 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 274 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 275 wen -> wdata.LCOFIP, 276 )) 277 }.elsewhen(lcofiReq) { 278 reg.LCOFIP := lcofiReq 279 }.otherwise { 280 reg.LCOFIP := reg.LCOFIP 281 } 282 }).setAddr(CSRs.mip) 283 284 val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle) 285 .setAddr(CSRs.mtinst) 286 287 val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle) 288 .setAddr(CSRs.mtval2) 289 290 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 291 val PMM = EnvPMM(33, 32, wNoEffect).withReset(EnvPMM.Disable) // Smmpm extension 292 val MLPE = RO(10) // Landing pand, Zicfilp extension 293 val SSEED = RO( 9) // Zkr extension 294 val USEED = RO( 8) // Zkr extension 295 val RLB = RO( 2) // Smepmp 296 val MMWP = RO( 1) // Smepmp 297 val MML = RO( 0) // Smepmp 298 })).setAddr(CSRs.mseccfg) 299 300 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 301 when(w.wen) { 302 reg := w.wdata 303 }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) { 304 reg := reg.ALL.asUInt + 1.U 305 }.otherwise { 306 reg := reg 307 } 308 }).setAddr(CSRs.mcycle) 309 310 311 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 312 when(w.wen) { 313 reg := w.wdata 314 }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) { 315 reg := reg.ALL.asUInt + robCommit.instNum.bits 316 }.otherwise { 317 reg := reg 318 } 319 }).setAddr(CSRs.minstret) 320 321 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 322 Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle { 323 val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn 324 val counterAdd = reg.ALL.asUInt +& perf.value 325 when (w.wen) { 326 reg := w.wdata 327 }.elsewhen (perf.value =/= 0.U && !countingInhibit) { 328 reg := counterAdd.tail(1) 329 }.otherwise { 330 reg := reg 331 } 332 // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from 333 // hardware increments of counter registers. 334 toMhpmeventOF := !countingInhibit & counterAdd.head(1) 335 }).setAddr(CSRs.mhpmcounter3 - 3 + num) 336 ) 337 338 val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U }) 339 .setAddr(CSRs.mvendorid) 340 341 // architecture id for XiangShan is 25 342 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 343 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 344 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 345 })).setAddr(CSRs.marchid) 346 347 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 348 val ALL = RO(0).withReset(0.U) 349 })) 350 .setAddr(CSRs.mimpid) 351 352 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 353 val ALL = RO(hartIdLen - 1, 0) 354 }) { 355 val hartid = IO(Input(UInt(hartIdLen.W))) 356 this.regOut.ALL := hartid 357 }) 358 .setAddr(CSRs.mhartid) 359 360 val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle { 361 val ALL = RO(63, 0) 362 })) 363 .setAddr(CSRs.mconfigptr) 364 365 val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0) 366 367 // smrnmi extension 368 val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle { 369 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 370 }) 371 .setAddr(CSRs.mnepc) 372 373 val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle) 374 .setAddr(CSRs.mncause) 375 val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle) 376 with TrapEntryMNEventSinkBundle 377 with MNretEventSinkBundle{ 378 // NMIE write 0 with no effect 379 // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing 380 // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered 381// when(!wdata.NMIE.asBool) { 382// reg.NMIE := reg.NMIE 383// } 384 }).setAddr(CSRs.mnstatus) 385 val mnscratch = Module(new CSRModule("Mnscratch")) 386 .setAddr(CSRs.mnscratch) 387 388 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 389 mstatus, 390 misa, 391 medeleg, 392 mideleg, 393 mie, 394 mtvec, 395 mcounteren, 396 mvien, 397 mvip, 398 menvcfg, 399 mcountinhibit, 400 mscratch, 401 mepc, 402 mcause, 403 mtval, 404 mip, 405 mtinst, 406 mtval2, 407 mseccfg, 408 mcycle, 409 minstret, 410 mvendorid, 411 marchid, 412 mimpid, 413 mhartid, 414 mconfigptr, 415 mstateen0, 416 mnepc, 417 mncause, 418 mnstatus, 419 mnscratch, 420 ) ++ mhpmevents ++ mhpmcounters 421 422 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 423 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 424 ) 425 426 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 427 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 428 ) 429 430} 431 432class MstatusBundle extends CSRBundle { 433 434 val SIE = CSRRWField (1).withReset(0.U) 435 val MIE = CSRRWField (3).withReset(0.U) 436 val SPIE = CSRRWField (5).withReset(0.U) 437 val UBE = CSRROField (6).withReset(0.U) 438 val MPIE = CSRRWField (7).withReset(0.U) 439 val SPP = CSRRWField (8).withReset(0.U) 440 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 441 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 442 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 443 val XS = ContextStatusRO(16, 15).withReset(0.U) 444 val MPRV = CSRRWField (17).withReset(0.U) 445 val SUM = CSRRWField (18).withReset(0.U) 446 val MXR = CSRRWField (19).withReset(0.U) 447 val TVM = CSRRWField (20).withReset(0.U) 448 val TW = CSRRWField (21).withReset(0.U) 449 val TSR = CSRRWField (22).withReset(0.U) 450 val SDT = CSRRWField (24).withReset(0.U) 451 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 452 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 453 val SBE = CSRROField (36).withReset(0.U) 454 val MBE = CSRROField (37).withReset(0.U) 455 val GVA = CSRRWField (38).withReset(0.U) 456 val MPV = VirtMode (39).withReset(0.U) 457 val MDT = CSRRWField (42).withReset(mdtInit.U) 458 val SD = CSRROField (63, 459 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 460 ) 461} 462 463class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 464 with TrapEntryMEventSinkBundle 465 with TrapEntryHSEventSinkBundle 466 with DretEventSinkBundle 467 with MretEventSinkBundle 468 with MNretEventSinkBundle 469 with SretEventSinkBundle 470 with HasRobCommitBundle 471 with HasMachineEnvBundle 472{ 473 val mstatus = IO(Output(bundle)) 474 val sstatus = IO(Output(new SstatusBundle)) 475 val sstatusRdata = IO(Output(UInt(64.W))) 476 477 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 478 for ((name, field) <- wAliasSstatus.wdataFields.elements) { 479 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 480 wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal, 481 field.asInstanceOf[CSREnumType] 482 ) 483 } 484 485 // write connection 486 reconnectReg() 487 488 when (robCommit.fsDirty || writeFCSR) { 489 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 490 reg.FS := ContextStatus.Dirty 491 } 492 493 when (robCommit.vsDirty || writeVCSR) { 494 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 495 reg.VS := ContextStatus.Dirty 496 } 497 // when MDT is explicitly written by 1, clear MIE 498 // only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1 499 when (w.wdataFields.MDT && w.wen) { 500 reg.MIE := false.B 501 } 502 // when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block) 503 val writeSstatusSDT = Wire(Bool()) 504 val writeMstatusSDT = Wire(Bool()) 505 val writeSDT = Wire(Bool()) 506 writeMstatusSDT := w.wdataFields.SDT.asBool 507 writeSstatusSDT := Mux(this.menvcfg.DTE.asBool, wAliasSstatus.wdataFields.SDT.asBool, reg.SDT.asBool) 508 writeSDT := Mux(w.wen, writeMstatusSDT, wAliasSstatus.wen && writeSstatusSDT) 509 // menvcfg.DTE only control Smode dbltrp. Thus mstatus.sdt will not control by DTE. 510 // as sstatus is alias of mstatus, when menvcfg.DTE close write, 511 // sstatus.sdt cannot lead to shadow write of mstatus.sdt. \ 512 // As a result, we add wmask of sdt, when write source is from alias write. 513 when (!this.menvcfg.DTE.asBool && wAliasSstatus.wen) { 514 reg.SDT := reg.SDT 515 } 516 // SDT and SIE is the same as MDT and MIE 517 when (writeSDT) { 518 reg.SIE := false.B 519 } 520 // read connection 521 mstatus :|= regOut 522 sstatus := mstatus 523 sstatus.SDT := regOut.SDT && menvcfg.DTE 524 rdata := mstatus.asUInt 525 sstatusRdata := sstatus.asUInt 526} 527 528class MnstatusBundle extends CSRBundle { 529 val NMIE = CSRRWField (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open 530 val MNPV = VirtMode (7).withReset(0.U) 531 val MNPELP = RO (9).withReset(0.U) 532 val MNPP = PrivMode (12, 11).withReset(PrivMode.U) 533} 534 535class MisaBundle extends CSRBundle { 536 // Todo: reset with ISA string 537 val A = RO( 0).withReset(1.U) // Atomic extension 538 val B = RO( 1).withReset(1.U) // B extension 539 val C = RO( 2).withReset(1.U) // Compressed extension 540 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 541 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 542 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 543 val G = RO( 6).withReset(0.U) // Reserved 544 val H = RO( 7).withReset(1.U) // Hypervisor extension 545 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 546 val J = RO( 9).withReset(0.U) // Reserved 547 val K = RO(10).withReset(0.U) // Reserved 548 val L = RO(11).withReset(0.U) // Reserved 549 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 550 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 551 val O = RO(14).withReset(0.U) // Reserved 552 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 553 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 554 val R = RO(17).withReset(0.U) // Reserved 555 val S = RO(18).withReset(1.U) // Supervisor mode implemented 556 val T = RO(19).withReset(0.U) // Reserved 557 val U = RO(20).withReset(1.U) // User mode implemented 558 val V = RO(21).withReset(1.U) // Vector extension 559 val W = RO(22).withReset(0.U) // Reserved 560 val X = RO(23).withReset(0.U) // Non-standard extensions present 561 val Y = RO(24).withReset(0.U) // Reserved 562 val Z = RO(25).withReset(0.U) // Reserved 563 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 564 565 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 566} 567 568class MedelegBundle extends ExceptionBundle { 569 this.getALL.foreach(_.setRW().withReset(0.U)) 570 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 571 this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable 572} 573 574class MidelegBundle extends InterruptBundle { 575 this.getALL.foreach(_.setRW().withReset(0.U)) 576 // Don't delegate Machine level interrupts 577 this.getM.foreach(_.setRO().withReset(0.U)) 578 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 579 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 580 // interrupts) are each read-only one. 581 this.getVS.foreach(_.setRO().withReset(1.U)) 582 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 583 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 584 this.SGEI.setRO().withReset(1.U) 585 this.getLocal.foreach(_.setRO().withReset(0.U)) 586 this.LCOFI.setRW().withReset(0.U) 587} 588 589class MieBundle extends InterruptEnableBundle { 590 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 591 this.LCOFIE.setRW().withReset(0.U) 592} 593 594class MipBundle extends InterruptPendingBundle { 595 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 596 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 597 // 598 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 599 // while these bits in hip are aliases for the same bits in mip. 600 // 601 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 602 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 603 this.getHS.foreach(_.setRW().withReset(0.U)) 604 this.getVS.foreach(_.setRW().withReset(0.U)) 605 this.LCOFIP.setRW().withReset(0.U) 606} 607 608class MvienBundle extends InterruptEnableBundle { 609 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 610 // It is strongly recommended that bit 9 of mvien be writable. 611 // It is strongly recommended that bit 1 of mvien also be writable. 612 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 613 this.SSIE.setRW().withReset(0.U) 614 this.SEIE.setRW().withReset(0.U) 615 this.getLocal.foreach(_.setRW().withReset(0.U)) 616} 617 618class MvipBundle extends InterruptPendingBundle { 619 this.getHS.foreach(_.setRW().withReset(0.U)) 620 this.getLocal.foreach(_.setRW().withReset(0.U)) 621} 622 623class Epc extends CSRBundle { 624 val epc = RW(63, 1).withReset(0.U) 625} 626 627class McountinhibitBundle extends CSRBundle { 628 val CY = RW(0).withReset(0.U) 629 val IR = RW(2).withReset(0.U) 630 val HPM3 = RW(31, 3).withReset(0.U) 631} 632 633class Mtval2Bundle extends FieldInitBundle 634 635class MhpmcounterBundle extends FieldInitBundle 636 637class MEnvCfg extends EnvCfg { 638 if (CSRConfig.EXT_SSTC) { 639 this.STCE.setRW().withReset(1.U) 640 } 641 this.PBMTE.setRW().withReset(0.U) 642 if (CSRConfig.EXT_DBLTRP) { 643 // software write envcfg to open ssdbltrp if need 644 // set 0 to pass ci 645 this.DTE.setRW().withReset(0.U) 646 } 647} 648 649object MarchidField extends CSREnum with ROApply { 650 val XSArchid = Value(25.U) 651} 652 653class MieToHie extends Bundle { 654 val VSSIE = ValidIO(RW(0)) 655 val VSTIE = ValidIO(RW(0)) 656 val VSEIE = ValidIO(RW(0)) 657 val SGEIE = ValidIO(RW(0)) 658} 659 660class MvipToMip extends IpValidBundle { 661 this.getHS.foreach(_.bits.setRW()) 662} 663 664class HipToMip extends IpValidBundle { 665 // Only hip.VSSIP is writable 666 this.VSSIP.bits.setRW() 667} 668 669class VSipToMip extends IpValidBundle { 670 this.LCOFIP.bits.setRW() 671} 672 673class MipToHvip extends IpValidBundle { 674 this.VSSIP.bits.setRW() 675} 676 677class MipToMvip extends IpValidBundle { 678 this.SEIP.bits.setRW() 679} 680 681class MhpmeventBundle extends CSRBundle { 682 val OF = RW(63).withReset(0.U) 683 val MINH = RW(62).withReset(0.U) 684 val SINH = RW(61).withReset(0.U) 685 val UINH = RW(60).withReset(0.U) 686 val VSINH = RW(59).withReset(0.U) 687 val VUINH = RW(58).withReset(0.U) 688 val OPTYPE2 = OPTYPE(54, 50, wNoFilter).withReset(OPTYPE.OR) 689 val OPTYPE1 = OPTYPE(49, 45, wNoFilter).withReset(OPTYPE.OR) 690 val OPTYPE0 = OPTYPE(44, 40, wNoFilter).withReset(OPTYPE.OR) 691 val EVENT3 = RW(39, 30).withReset(0.U) 692 val EVENT2 = RW(29, 20).withReset(0.U) 693 val EVENT1 = RW(19, 10).withReset(0.U) 694 val EVENT0 = RW(9, 0).withReset(0.U) 695} 696 697object OPTYPE extends CSREnum with WARLApply { 698 val OR = Value(0.U) 699 val AND = Value(1.U) 700 val XOR = Value(2.U) 701 val ADD = Value(4.U) 702 703 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(OR, AND, XOR, ADD) 704} 705 706trait HasOfFromPerfCntBundle { self: CSRModule[_] => 707 val ofFromPerfCnt = IO(Input(Bool())) 708} 709 710trait HasMipToAlias { self: CSRModule[_] => 711 val mipAlias = Output(new MipBundle) 712} 713 714trait HasMachineDelegBundle { self: CSRModule[_] => 715 val mideleg = IO(Input(new MidelegBundle)) 716 val medeleg = IO(Input(new MedelegBundle)) 717} 718 719trait HasExternalInterruptBundle { 720 val platformIRP = IO(new Bundle { 721 val MEIP = Input(Bool()) 722 val MTIP = Input(Bool()) 723 val MSIP = Input(Bool()) 724 val SEIP = Input(Bool()) 725 val STIP = Input(Bool()) 726 val VSEIP = Input(Bool()) 727 val VSTIP = Input(Bool()) 728 // debug interrupt from debug module 729 val debugIP = Input(Bool()) 730 }) 731} 732trait HasNonMaskableIRPBundle { 733 val nonMaskableIRP = IO(new Bundle { 734 val NMI_43 = Input(Bool()) 735 val NMI_31 = Input(Bool()) 736 }) 737} 738 739trait HasMachineCounterControlBundle { self: CSRModule[_] => 740 val mcountinhibit = IO(Input(new McountinhibitBundle)) 741} 742 743trait HasRobCommitBundle { self: CSRModule[_] => 744 val robCommit = IO(Input(new RobCommitCSR)) 745 val writeFCSR = IO(Input(Bool())) 746 val writeVCSR = IO(Input(Bool())) 747 val isVirtMode = IO(Input(Bool())) 748} 749 750trait HasMachineEnvBundle { self: CSRModule[_] => 751 val menvcfg = IO(Input(new MEnvCfg)) 752} 753 754trait HasPerfCounterBundle { self: CSRModule[_] => 755 val countingEn = IO(Input(Bool())) 756 val perf = IO(Input(new PerfEvent)) 757 val toMhpmeventOF = IO(Output(Bool())) 758} 759 760trait HasPerfEventBundle { self: CSRModule[_] => 761 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 762} 763 764trait HasLocalInterruptReqBundle { self: CSRModule[_] => 765 val lcofiReq = IO(Input(Bool())) 766}