1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import xiangshan.backend.fu.NewCSR.CSRBundles._ 7import xiangshan.backend.fu.NewCSR.CSRDefines._ 8import xiangshan.backend.fu.NewCSR.CSRDefines.{ 9 CSRROField => RO, 10 CSRRWField => RW, 11 _ 12} 13import xiangshan.backend.fu.NewCSR.CSREvents._ 14 15import scala.collection.immutable.SeqMap 16 17trait MachineLevel { self: NewCSR => 18 val mstatus = Module(new MstatusModule) 19 .setAddr(0x300) 20 21 val misa = Module(new CSRModule("Misa", new MisaBundle)) 22 .setAddr(0x301) 23 24 println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}") 25 26 val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle)) 27 .setAddr(0x302) 28 29 val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle)) 30 .setAddr(0x303) 31 32 val mie = Module(new CSRModule("Mie", new MieBundle) with HypervisorBundle { 33 val toHie = IO(new MieToHie) 34 val fromSie = IO(Flipped(new SieToMie)) 35 36 when (fromSie.SSIE.valid) { reg.SSIE := fromSie.SSIE.bits } 37 when (fromSie.STIE.valid) { reg.STIE := fromSie.STIE.bits } 38 when (fromSie.SEIE.valid) { reg.SEIE := fromSie.SEIE.bits } 39 40 toHie.VSSIE.valid := wen 41 toHie.VSTIE.valid := wen 42 toHie.VSEIE.valid := wen 43 toHie.SGEIE.valid := wen 44 toHie.VSSIE.bits := wdata.VSSIE 45 toHie.VSTIE.bits := wdata.VSTIE 46 toHie.VSEIE.bits := wdata.VSEIE 47 toHie.SGEIE.bits := wdata.SGEIE 48 49 rdata.VSSIE := hie.VSSIE 50 rdata.VSTIE := hie.VSTIE 51 rdata.VSEIE := hie.VSEIE 52 rdata.SGEIE := hie.SGEIE 53 }).setAddr(0x304) 54 55 val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle)) 56 .setAddr(0x305) 57 58 // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0 59 // Todo: support Sscounterenw Extension 60 val mcounteren = Module(new CSRModule("Mcounteren", new Counteren)) 61 .setAddr(0x306) 62 63 val mvien = Module(new CSRModule("Mvien", new MvienBundle)) 64 .setAddr(0x308) 65 66 val mvip = Module(new CSRModule("Mvip", new MvipBundle) with HasMachineInterruptBundle { 67 val toMip = IO(new MvipToMip) 68 69 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 70 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 71 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 72 // XS will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one 73 rdata.SSIP := Mux(!mvien.SSIE.asUInt.asBool, mip.SSIP, reg.SSIP) 74 toMip.SSIP.valid := wen && !mvien.SSIE.asUInt.asBool 75 toMip.SSIP.bits := wdata.SSIP 76 reg.SSIP := Mux(wen && mvien.SSIE.asUInt.asBool, wdata.SSIP, reg.SSIP) 77 78 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 79 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 80 // Todo: check mip writable when menvcfg.STCE = 1 81 rdata.STIP := mip.STIP 82 toMip.STIP.valid := wen 83 toMip.STIP.bits := wdata.STIP 84 85 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 86 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 87 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 88 rdata.SEIP := Mux(!mvien.SEIE.asUInt.asBool, mip.SEIP, reg.SEIP) 89 toMip.SEIP.valid := wen && !mvien.SEIE.asUInt.asBool 90 toMip.SEIP.bits := wdata.SEIP 91 reg.SEIP := Mux(wen && mvien.SEIE.asUInt.asBool, wdata.SEIP, reg.SEIP) 92 }).setAddr(0x309) 93 94 val menvcfg = Module(new CSRModule("Menvcfg", new Envcfg)) 95 .setAddr(0x30A) 96 97 val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle)) 98 .setAddr(0x320) 99 100 val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 101 Module(new CSRModule(s"Mhpmevent$num")) 102 .setAddr(0x320 + num) 103 ) 104 105 val mscratch = Module(new CSRModule("Mscratch")) 106 .setAddr(0x340) 107 108 val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle) 109 .setAddr(0x341) 110 111 val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle) 112 .setAddr(0x342) 113 114 val mtval = Module(new CSRModule("Mtval") with TrapEntryMEventSinkBundle) 115 .setAddr(0x343) 116 117 val mip = Module(new CSRModule("Mip", new MipBundle) with HasMachineInterruptBundle with HasExternalInterruptBundle { 118 val fromMvip = IO(Flipped(new MvipToMip)) 119 val fromSip = IO(Flipped(new SipToMip)) 120 121 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 122 // 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. 123 rdata.SEIP := Mux(!mvien.SEIE.asUInt.asBool, reg.SEIP.asUInt.asBool | mvip.SEIP.asUInt.asBool | platformIRP.SEIP, platformIRP.SEIP) 124 when (wen && !mvien.SEIE.asUInt.asBool) { reg.SEIP := reg.SEIP } 125 when (fromMvip.SSIP.valid) { reg.SSIP := fromMvip.SSIP.bits } 126 when (fromMvip.STIP.valid) { reg.STIP := fromMvip.STIP.bits } 127 when (fromMvip.SEIP.valid) { reg.SEIP := fromMvip.SEIP.bits } 128 when (fromSip.SSIP.valid) { reg.SSIP := fromSip.SSIP.bits } 129 130 // MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 131 rdata.MEIP := platformIRP.MEIP 132 // MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 133 rdata.MTIP := platformIRP.MTIP 134 // MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 135 // which are used by remote harts to provide machine-level interprocessor interrupts. 136 rdata.MSIP := platformIRP.MSIP 137 }).setAddr(0x344) 138 139 val mtinst = Module(new CSRModule("Mtinst") with TrapEntryMEventSinkBundle) 140 .setAddr(0x34A) 141 142 val mtval2 = Module(new CSRModule("Mtval2") with TrapEntryMEventSinkBundle) 143 .setAddr(0x34B) 144 145 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 146 val PMM = RO(33, 32) 147 val SSEED = RO( 9) 148 val USEED = RO( 8) 149 val RLB = RO( 2) 150 val MMWP = RO( 1) 151 val MML = RO( 0) 152 })).setAddr(0x747) 153 154 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 155 reg.ALL := Mux(!mcountinhibit.CY.asUInt.asBool, reg.ALL.asUInt + 1.U, reg.ALL.asUInt) 156 }).setAddr(0xB00) 157 158 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 159 reg.ALL := Mux(!mcountinhibit.IR.asUInt.asBool && robCommit.instNum.valid, reg.ALL.asUInt + robCommit.instNum.bits, reg.ALL.asUInt) 160 }) 161 162 // Todo: guarded by mcountinhibit 163 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 164 Module(new CSRModule(s"Mhpmcounter$num") { 165 166 }).setAddr(0xB00 + num) 167 ) 168 169 val mvendorid = Module(new CSRModule("Mvendorid") { rdata.ALL := 0.U }) 170 .setAddr(0xF11) 171 172 // architecture id for XiangShan is 25 173 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 174 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 175 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 176 })).setAddr(0xF12) 177 178 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 179 mstatus, 180 misa, 181 medeleg, 182 mideleg, 183 mie, 184 mtvec, 185 mcounteren, 186 mvien, 187 mvip, 188 menvcfg, 189 mcountinhibit, 190 mscratch, 191 mepc, 192 mcause, 193 mtval, 194 mip, 195 mtinst, 196 mtval2, 197 mseccfg, 198 mcycle, 199 minstret, 200 mvendorid, 201 marchid, 202 ) ++ mhpmevents ++ mhpmcounters 203 204 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from( 205 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt))).iterator 206 ) 207 208 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 209 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 210 ) 211} 212 213class MstatusBundle extends CSRBundle { 214 215 val SIE = CSRRWField (1).withReset(0.U) 216 val MIE = CSRRWField (3).withReset(0.U) 217 val SPIE = CSRRWField (5).withReset(0.U) 218 val UBE = CSRROField (6).withReset(0.U) 219 val MPIE = CSRRWField (7).withReset(0.U) 220 val SPP = CSRRWField (8).withReset(0.U) 221 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 222 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 223 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 224 val XS = ContextStatusRO(16, 15).withReset(0.U) 225 val MPRV = CSRRWField (17).withReset(0.U) 226 val SUM = CSRRWField (18).withReset(0.U) 227 val MXR = CSRRWField (19).withReset(0.U) 228 val TVM = CSRRWField (20).withReset(0.U) 229 val TW = CSRRWField (21).withReset(0.U) 230 val TSR = CSRRWField (22).withReset(0.U) 231 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 232 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 233 val SBE = CSRROField (36).withReset(0.U) 234 val MBE = CSRROField (37).withReset(0.U) 235 val GVA = CSRRWField (38).withReset(0.U) 236 val MPV = VirtMode (39).withReset(0.U) 237 val SD = CSRROField (63, 238 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 239 ) 240} 241 242class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 243 with TrapEntryMEventSinkBundle 244 with TrapEntryHSEventSinkBundle 245 with MretEventSinkBundle 246 with SretEventSinkBundle 247 with HasRobCommitBundle 248{ 249 val mstatus = IO(Output(bundle)) 250 val sstatus = IO(Output(new SstatusBundle)) 251 252 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 253 254 // write connection 255 this.wfn(reg)(Seq(wAliasSstatus)) 256 257 when (robCommit.fsDirty) { 258 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 259 reg.FS := ContextStatus.Dirty 260 } 261 262 when (robCommit.vsDirty) { 263 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 264 reg.VS := ContextStatus.Dirty 265 } 266 267 // read connection 268 mstatus :|= reg 269 sstatus := mstatus 270 rdata := mstatus.asUInt 271} 272 273class MisaBundle extends CSRBundle { 274 // Todo: reset with ISA string 275 val A = RO( 0).withReset(1.U) // Atomic extension 276 val B = RO( 1).withReset(0.U) // Reserved 277 val C = RO( 2).withReset(1.U) // Compressed extension 278 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 279 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 280 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 281 val G = RO( 6).withReset(0.U) // Reserved 282 val H = RO( 7).withReset(1.U) // Hypervisor extension 283 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 284 val J = RO( 9).withReset(0.U) // Reserved 285 val K = RO(10).withReset(0.U) // Reserved 286 val L = RO(11).withReset(0.U) // Reserved 287 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 288 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 289 val O = RO(14).withReset(0.U) // Reserved 290 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 291 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 292 val R = RO(17).withReset(0.U) // Reserved 293 val S = RO(18).withReset(1.U) // Supervisor mode implemented 294 val T = RO(19).withReset(0.U) // Reserved 295 val U = RO(20).withReset(1.U) // User mode implemented 296 val V = RO(21).withReset(1.U) // Vector extension 297 val W = RO(22).withReset(0.U) // Reserved 298 val X = RO(23).withReset(0.U) // Non-standard extensions present 299 val Y = RO(24).withReset(0.U) // Reserved 300 val Z = RO(25).withReset(0.U) // Reserved 301 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 302 303 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 304} 305 306class MedelegBundle extends ExceptionBundle { 307 this.EX_MCALL.setRO() // never delegate machine level ecall 308} 309 310class MidelegBundle extends InterruptBundle { 311 // Don't delegate Machine level interrupts 312 this.getM.foreach(_.setRO().withReset(0.U)) 313 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 314 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 315 // interrupts) are each read-only one. 316 this.getVS.foreach(_.setRO().withReset(1.U)) 317 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 318 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 319 this.SGEI.setRO().withReset(1.U) 320} 321 322class MieBundle extends InterruptEnableBundle { 323 this.SGEIE.setRO() 324 this.getVS.foreach(_.setRO()) 325} 326 327class MipBundle extends InterruptPendingBundle { 328 this.getM.foreach(_.setRO()) 329} 330 331class MvienBundle extends CSRBundle { 332 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 333 // It is strongly recommended that bit 9 of mvien be writable. 334 // It is strongly recommended that bit 1 of mvien also be writable. 335 val SSIE = RW(1) 336 val SEIE = RW(9) 337 val OTHERIE = RW(63, 13) 338} 339 340class MvipBundle extends CSRBundle { 341 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 342 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 343 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 344 val SSIP = RW(1) 345 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 346 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 347 val STIP = RW(5) 348 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 349 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 350 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 351 val SEIP = RW(9) 352 val OTHERIP = RW(63, 13) 353} 354 355class Epc extends CSRBundle { 356 // TODO: configure it with VAddrBits 357 val ALL = RW(63, 1) 358} 359 360class McountinhibitBundle extends CSRBundle { 361 val CY = RW(0) 362 val IR = RW(2) 363 val HPM3 = RW(31, 3) 364} 365 366object MarchidField extends CSREnum with ROApply { 367 val XSArchid = Value(25.U) 368} 369 370class MieToHie extends Bundle { 371 val VSSIE = ValidIO(RW(0)) 372 val VSTIE = ValidIO(RW(0)) 373 val VSEIE = ValidIO(RW(0)) 374 val SGEIE = ValidIO(RW(0)) 375} 376 377class MvipToMip extends Bundle { 378 val SSIP = ValidIO(RW(0)) 379 val STIP = ValidIO(RW(0)) 380 val SEIP = ValidIO(RW(0)) 381} 382 383trait HasMachineInterruptBundle { self: CSRModule[_] => 384 val mvien = IO(Input(new MvienBundle)) 385 val mvip = IO(Input(new MvipBundle)) 386 val mip = IO(Input(new MipBundle)) 387 val mie = IO(Input(new MieBundle)) 388} 389 390trait HasMachineDelegBundle { self: CSRModule[_] => 391 val mideleg = IO(Input(new MidelegBundle)) 392 val medeleg = IO(Input(new MedelegBundle)) 393} 394 395trait HasExternalInterruptBundle { 396 val platformIRP = IO(new Bundle { 397 val MEIP = Input(Bool()) 398 val MTIP = Input(Bool()) 399 val MSIP = Input(Bool()) 400 val SEIP = Input(Bool()) 401 val VSEIP = Input(Bool()) 402 val VSTIP = Input(Bool()) 403 val debugIP = Input(Bool()) 404 }) 405} 406 407trait HasMachineCounterControlBundle { self: CSRModule[_] => 408 val mcountinhibit = IO(Input(new McountinhibitBundle)) 409} 410 411trait HasRobCommitBundle { self: CSRModule[_] => 412 val robCommit = IO(Input(new RobCommitCSR)) 413}