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