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") { rdata := 0.U }) 356 .setAddr(CSRs.mvendorid) 357 358 // architecture id for XiangShan is 25 359 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 360 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 361 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 362 })).setAddr(CSRs.marchid) 363 364 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 365 val ALL = RO(0).withReset(0.U) 366 })) 367 .setAddr(CSRs.mimpid) 368 369 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 370 val ALL = RO(hartIdLen - 1, 0) 371 }) { 372 val hartid = IO(Input(UInt(hartIdLen.W))) 373 this.regOut.ALL := hartid 374 }) 375 .setAddr(CSRs.mhartid) 376 377 val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle { 378 val ALL = RO(63, 0) 379 })) 380 .setAddr(CSRs.mconfigptr) 381 382 val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0) 383 384 // smrnmi extension 385 val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle { 386 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 387 }) 388 .setAddr(CSRs.mnepc) 389 390 val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle) 391 .setAddr(CSRs.mncause) 392 val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle) 393 with TrapEntryMNEventSinkBundle 394 with MNretEventSinkBundle{ 395 // NMIE write 0 with no effect 396 // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing 397 // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered 398// when(!wdata.NMIE.asBool) { 399// reg.NMIE := reg.NMIE 400// } 401 }).setAddr(CSRs.mnstatus) 402 val mnscratch = Module(new CSRModule("Mnscratch")) 403 .setAddr(CSRs.mnscratch) 404 405 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 406 mstatus, 407 misa, 408 medeleg, 409 mideleg, 410 mie, 411 mtvec, 412 mcounteren, 413 mvien, 414 mvip, 415 menvcfg, 416 mcountinhibit, 417 mscratch, 418 mepc, 419 mcause, 420 mtval, 421 mip, 422 mtinst, 423 mtval2, 424 mseccfg, 425 mcycle, 426 minstret, 427 mvendorid, 428 marchid, 429 mimpid, 430 mhartid, 431 mconfigptr, 432 mstateen0, 433 mnepc, 434 mncause, 435 mnstatus, 436 mnscratch, 437 ) ++ mhpmevents ++ mhpmcounters ++ (if (HasBitmapCheck) Seq(mbmc.get) else Seq()) 438 439 440 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 441 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 442 ) 443 444 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 445 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 446 ) 447 448} 449 450class MbmcBundle extends CSRBundle { 451 val BMA = BMAField(63,6,null).withReset(BMAField.ResetBMA) 452 val BME = RW(2).withReset(0.U) 453 val BCLEAR = RW(1).withReset(0.U) 454 val CMODE = RW(0).withReset(0.U) 455} 456 457class MstatusBundle extends CSRBundle { 458 459 val SIE = CSRRWField (1).withReset(0.U) 460 val MIE = CSRRWField (3).withReset(0.U) 461 val SPIE = CSRRWField (5).withReset(0.U) 462 val UBE = CSRROField (6).withReset(0.U) 463 val MPIE = CSRRWField (7).withReset(0.U) 464 val SPP = CSRRWField (8).withReset(0.U) 465 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 466 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 467 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 468 val XS = ContextStatusRO(16, 15).withReset(0.U) 469 val MPRV = CSRRWField (17).withReset(0.U) 470 val SUM = CSRRWField (18).withReset(0.U) 471 val MXR = CSRRWField (19).withReset(0.U) 472 val TVM = CSRRWField (20).withReset(0.U) 473 val TW = CSRRWField (21).withReset(0.U) 474 val TSR = CSRRWField (22).withReset(0.U) 475 val SDT = CSRRWField (24).withReset(0.U) 476 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 477 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 478 val SBE = CSRROField (36).withReset(0.U) 479 val MBE = CSRROField (37).withReset(0.U) 480 val GVA = CSRRWField (38).withReset(0.U) 481 val MPV = VirtMode (39).withReset(0.U) 482 val MDT = CSRRWField (42).withReset(mdtInit.U) 483 val SD = CSRROField (63, 484 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 485 ) 486} 487 488class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 489 with TrapEntryMEventSinkBundle 490 with TrapEntryHSEventSinkBundle 491 with DretEventSinkBundle 492 with MretEventSinkBundle 493 with MNretEventSinkBundle 494 with SretEventSinkBundle 495 with HasRobCommitBundle 496 with HasMachineEnvBundle 497{ 498 val mstatus = IO(Output(bundle)) 499 val sstatus = IO(Output(new SstatusBundle)) 500 val sstatusRdata = IO(Output(UInt(64.W))) 501 502 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 503 for ((name, field) <- wAliasSstatus.wdataFields.elements) { 504 reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate( 505 wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal, 506 field.asInstanceOf[CSREnumType] 507 ) 508 } 509 510 // write connection 511 reconnectReg() 512 513 when (robCommit.fsDirty || writeFCSR) { 514 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 515 reg.FS := ContextStatus.Dirty 516 } 517 518 when (robCommit.vsDirty || writeVCSR) { 519 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 520 reg.VS := ContextStatus.Dirty 521 } 522 // when MDT is explicitly written by 1, clear MIE 523 // only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1 524 when (w.wdataFields.MDT && w.wen) { 525 reg.MIE := false.B 526 } 527 // when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block) 528 val writeSstatusSDT = Wire(Bool()) 529 val writeMstatusSDT = Wire(Bool()) 530 val writeSDT = Wire(Bool()) 531 writeMstatusSDT := w.wdataFields.SDT.asBool 532 writeSstatusSDT := Mux(this.menvcfg.DTE.asBool, wAliasSstatus.wdataFields.SDT.asBool, reg.SDT.asBool) 533 writeSDT := Mux(w.wen, writeMstatusSDT, wAliasSstatus.wen && writeSstatusSDT) 534 // menvcfg.DTE only control Smode dbltrp. Thus mstatus.sdt will not control by DTE. 535 // as sstatus is alias of mstatus, when menvcfg.DTE close write, 536 // sstatus.sdt cannot lead to shadow write of mstatus.sdt. \ 537 // As a result, we add wmask of sdt, when write source is from alias write. 538 when (!this.menvcfg.DTE.asBool && wAliasSstatus.wen) { 539 reg.SDT := reg.SDT 540 } 541 // SDT and SIE is the same as MDT and MIE 542 when (writeSDT) { 543 reg.SIE := false.B 544 } 545 // read connection 546 mstatus :|= regOut 547 sstatus := mstatus 548 sstatus.SDT := regOut.SDT && menvcfg.DTE 549 rdata := mstatus.asUInt 550 sstatusRdata := sstatus.asUInt 551} 552 553class MnstatusBundle extends CSRBundle { 554 val NMIE = CSRRWField (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open 555 val MNPV = VirtMode (7).withReset(0.U) 556 val MNPELP = RO (9).withReset(0.U) 557 val MNPP = PrivMode (12, 11).withReset(PrivMode.U) 558} 559 560class MisaBundle extends CSRBundle { 561 // Todo: reset with ISA string 562 val A = RO( 0).withReset(1.U) // Atomic extension 563 val B = RO( 1).withReset(1.U) // B extension 564 val C = RO( 2).withReset(1.U) // Compressed extension 565 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 566 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 567 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 568 val G = RO( 6).withReset(0.U) // Reserved 569 val H = RO( 7).withReset(1.U) // Hypervisor extension 570 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 571 val J = RO( 9).withReset(0.U) // Reserved 572 val K = RO(10).withReset(0.U) // Reserved 573 val L = RO(11).withReset(0.U) // Reserved 574 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 575 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 576 val O = RO(14).withReset(0.U) // Reserved 577 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 578 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 579 val R = RO(17).withReset(0.U) // Reserved 580 val S = RO(18).withReset(1.U) // Supervisor mode implemented 581 val T = RO(19).withReset(0.U) // Reserved 582 val U = RO(20).withReset(1.U) // User mode implemented 583 val V = RO(21).withReset(1.U) // Vector extension 584 val W = RO(22).withReset(0.U) // Reserved 585 val X = RO(23).withReset(0.U) // Non-standard extensions present 586 val Y = RO(24).withReset(0.U) // Reserved 587 val Z = RO(25).withReset(0.U) // Reserved 588 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 589 590 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 591} 592 593class MedelegBundle extends ExceptionBundle { 594 this.getALL.foreach(_.setRW().withReset(0.U)) 595 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 596 this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable 597} 598 599class MidelegBundle extends InterruptBundle { 600 this.getALL.foreach(_.setRW().withReset(0.U)) 601 // Don't delegate Machine level interrupts 602 this.getM.foreach(_.setRO().withReset(0.U)) 603 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 604 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 605 // interrupts) are each read-only one. 606 this.getVS.foreach(_.setRO().withReset(1.U)) 607 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 608 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 609 this.SGEI.setRO().withReset(1.U) 610 this.getLocal.foreach(_.setRO().withReset(0.U)) 611 this.LCOFI.setRW().withReset(0.U) 612} 613 614class MieBundle extends InterruptEnableBundle { 615 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 616 this.LCOFIE.setRW().withReset(0.U) 617} 618 619class MipBundle extends InterruptPendingBundle { 620 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 621 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 622 // 623 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 624 // while these bits in hip are aliases for the same bits in mip. 625 // 626 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 627 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 628 this.getHS.foreach(_.setRW().withReset(0.U)) 629 this.getVS.foreach(_.setRW().withReset(0.U)) 630 this.LCOFIP.setRW().withReset(0.U) 631} 632 633class MvienBundle extends InterruptEnableBundle { 634 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 635 // It is strongly recommended that bit 9 of mvien be writable. 636 // It is strongly recommended that bit 1 of mvien also be writable. 637 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 638 this.SSIE.setRW().withReset(0.U) 639 this.SEIE.setRW().withReset(0.U) 640 this.getLocal.foreach(_.setRW().withReset(0.U)) 641} 642 643class MvipBundle extends InterruptPendingBundle { 644 this.getHS.foreach(_.setRW().withReset(0.U)) 645 this.getLocal.foreach(_.setRW().withReset(0.U)) 646} 647 648class Epc extends CSRBundle { 649 val epc = RW(63, 1).withReset(0.U) 650} 651 652class McountinhibitBundle extends CSRBundle { 653 val CY = RW(0).withReset(0.U) 654 val IR = RW(2).withReset(0.U) 655 val HPM3 = RW(31, 3).withReset(0.U) 656} 657 658class Mtval2Bundle extends FieldInitBundle 659 660class MhpmcounterBundle extends FieldInitBundle 661 662class MEnvCfg extends EnvCfg { 663 if (CSRConfig.EXT_SSTC) { 664 this.STCE.setRW().withReset(1.U) 665 } 666 this.PBMTE.setRW().withReset(0.U) 667 if (CSRConfig.EXT_DBLTRP) { 668 // software write envcfg to open ssdbltrp if need 669 // set 0 to pass ci 670 this.DTE.setRW().withReset(0.U) 671 } 672} 673 674object MarchidField extends CSREnum with ROApply { 675 val XSArchid = Value(25.U) 676} 677 678class MieToHie extends Bundle { 679 val VSSIE = ValidIO(RW(0)) 680 val VSTIE = ValidIO(RW(0)) 681 val VSEIE = ValidIO(RW(0)) 682 val SGEIE = ValidIO(RW(0)) 683} 684 685class MvipToMip extends IpValidBundle { 686 this.getHS.foreach(_.bits.setRW()) 687} 688 689class HipToMip extends IpValidBundle { 690 // Only hip.VSSIP is writable 691 this.VSSIP.bits.setRW() 692} 693 694class VSipToMip extends IpValidBundle { 695 this.LCOFIP.bits.setRW() 696} 697 698class MipToHvip extends IpValidBundle { 699 this.VSSIP.bits.setRW() 700} 701 702class MipToMvip extends IpValidBundle { 703 this.SEIP.bits.setRW() 704} 705 706class MhpmeventBundle extends CSRBundle { 707 val OF = RW(63).withReset(0.U) 708 val MINH = RW(62).withReset(0.U) 709 val SINH = RW(61).withReset(0.U) 710 val UINH = RW(60).withReset(0.U) 711 val VSINH = RW(59).withReset(0.U) 712 val VUINH = RW(58).withReset(0.U) 713 val OPTYPE2 = OPTYPE(54, 50, wNoFilter).withReset(OPTYPE.OR) 714 val OPTYPE1 = OPTYPE(49, 45, wNoFilter).withReset(OPTYPE.OR) 715 val OPTYPE0 = OPTYPE(44, 40, wNoFilter).withReset(OPTYPE.OR) 716 val EVENT3 = RW(39, 30).withReset(0.U) 717 val EVENT2 = RW(29, 20).withReset(0.U) 718 val EVENT1 = RW(19, 10).withReset(0.U) 719 val EVENT0 = RW(9, 0).withReset(0.U) 720} 721 722object OPTYPE extends CSREnum with WARLApply { 723 val OR = Value(0.U) 724 val AND = Value(1.U) 725 val XOR = Value(2.U) 726 val ADD = Value(4.U) 727 728 override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(OR, AND, XOR, ADD) 729} 730 731trait HasOfFromPerfCntBundle { self: CSRModule[_] => 732 val ofFromPerfCnt = IO(Input(Bool())) 733} 734 735trait HasMipToAlias { self: CSRModule[_] => 736 val mipAlias = Output(new MipBundle) 737} 738 739trait HasMachineDelegBundle { self: CSRModule[_] => 740 val mideleg = IO(Input(new MidelegBundle)) 741 val medeleg = IO(Input(new MedelegBundle)) 742} 743 744trait HasExternalInterruptBundle { 745 val platformIRP = IO(new Bundle { 746 val MEIP = Input(Bool()) 747 val MTIP = Input(Bool()) 748 val MSIP = Input(Bool()) 749 val SEIP = Input(Bool()) 750 val STIP = Input(Bool()) 751 val VSEIP = Input(Bool()) 752 val VSTIP = Input(Bool()) 753 // debug interrupt from debug module 754 val debugIP = Input(Bool()) 755 }) 756} 757trait HasNonMaskableIRPBundle { 758 val nonMaskableIRP = IO(new Bundle { 759 val NMI_43 = Input(Bool()) 760 val NMI_31 = Input(Bool()) 761 }) 762} 763 764trait HasMachineCounterControlBundle { self: CSRModule[_] => 765 val mcountinhibit = IO(Input(new McountinhibitBundle)) 766} 767 768trait HasRobCommitBundle { self: CSRModule[_] => 769 val robCommit = IO(Input(new RobCommitCSR)) 770 val writeFCSR = IO(Input(Bool())) 771 val writeVCSR = IO(Input(Bool())) 772 val isVirtMode = IO(Input(Bool())) 773} 774 775trait HasMachineEnvBundle { self: CSRModule[_] => 776 val menvcfg = IO(Input(new MEnvCfg)) 777} 778 779trait HasPerfCounterBundle { self: CSRModule[_] => 780 val countingEn = IO(Input(Bool())) 781 val perf = IO(Input(new PerfEvent)) 782 val toMhpmeventOF = IO(Output(Bool())) 783} 784 785trait HasPerfEventBundle { self: CSRModule[_] => 786 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 787} 788 789trait HasLocalInterruptReqBundle { self: CSRModule[_] => 790 val lcofiReq = IO(Input(Bool())) 791} 792 793trait HasMachineFlushL2Bundle { self: CSRModule[_] => 794 val l2FlushDone = IO(Input(Bool())) 795} 796