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 mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 179 val ALL = RO(0).withReset(0.U) 180 })) 181 .setAddr(0xF13) 182 183 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 184 val ALL = RO(7, 0) 185 }) { 186 val hartid = IO(Input(UInt(hartIdLen.W))) 187 this.reg.ALL := RegEnable(hartid, reset.asBool) 188 }) 189 .setAddr(0xF14) 190 191 val mconfigptr = Module(new CSRModule("Mconfigptr")) 192 .setAddr(0xF15) 193 194 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 195 mstatus, 196 misa, 197 medeleg, 198 mideleg, 199 mie, 200 mtvec, 201 mcounteren, 202 mvien, 203 mvip, 204 menvcfg, 205 mcountinhibit, 206 mscratch, 207 mepc, 208 mcause, 209 mtval, 210 mip, 211 mtinst, 212 mtval2, 213 mseccfg, 214 mcycle, 215 minstret, 216 mvendorid, 217 marchid, 218 mimpid, 219 mhartid, 220 mconfigptr, 221 ) ++ mhpmevents ++ mhpmcounters 222 223 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from( 224 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt))).iterator 225 ) 226 227 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 228 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 229 ) 230} 231 232class MstatusBundle extends CSRBundle { 233 234 val SIE = CSRRWField (1).withReset(0.U) 235 val MIE = CSRRWField (3).withReset(0.U) 236 val SPIE = CSRRWField (5).withReset(0.U) 237 val UBE = CSRROField (6).withReset(0.U) 238 val MPIE = CSRRWField (7).withReset(0.U) 239 val SPP = CSRRWField (8).withReset(0.U) 240 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 241 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 242 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 243 val XS = ContextStatusRO(16, 15).withReset(0.U) 244 val MPRV = CSRRWField (17).withReset(0.U) 245 val SUM = CSRRWField (18).withReset(0.U) 246 val MXR = CSRRWField (19).withReset(0.U) 247 val TVM = CSRRWField (20).withReset(0.U) 248 val TW = CSRRWField (21).withReset(0.U) 249 val TSR = CSRRWField (22).withReset(0.U) 250 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 251 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 252 val SBE = CSRROField (36).withReset(0.U) 253 val MBE = CSRROField (37).withReset(0.U) 254 val GVA = CSRRWField (38).withReset(0.U) 255 val MPV = VirtMode (39).withReset(0.U) 256 val SD = CSRROField (63, 257 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 258 ) 259} 260 261class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 262 with TrapEntryMEventSinkBundle 263 with TrapEntryHSEventSinkBundle 264 with MretEventSinkBundle 265 with SretEventSinkBundle 266 with HasRobCommitBundle 267{ 268 val mstatus = IO(Output(bundle)) 269 val sstatus = IO(Output(new SstatusBundle)) 270 271 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 272 273 // write connection 274 this.wfn(reg)(Seq(wAliasSstatus)) 275 276 when (robCommit.fsDirty) { 277 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 278 reg.FS := ContextStatus.Dirty 279 } 280 281 when (robCommit.vsDirty) { 282 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 283 reg.VS := ContextStatus.Dirty 284 } 285 286 // read connection 287 mstatus :|= reg 288 sstatus := mstatus 289 rdata := mstatus.asUInt 290} 291 292class MisaBundle extends CSRBundle { 293 // Todo: reset with ISA string 294 val A = RO( 0).withReset(1.U) // Atomic extension 295 val B = RO( 1).withReset(0.U) // Reserved 296 val C = RO( 2).withReset(1.U) // Compressed extension 297 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 298 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 299 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 300 val G = RO( 6).withReset(0.U) // Reserved 301 val H = RO( 7).withReset(1.U) // Hypervisor extension 302 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 303 val J = RO( 9).withReset(0.U) // Reserved 304 val K = RO(10).withReset(0.U) // Reserved 305 val L = RO(11).withReset(0.U) // Reserved 306 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 307 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 308 val O = RO(14).withReset(0.U) // Reserved 309 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 310 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 311 val R = RO(17).withReset(0.U) // Reserved 312 val S = RO(18).withReset(1.U) // Supervisor mode implemented 313 val T = RO(19).withReset(0.U) // Reserved 314 val U = RO(20).withReset(1.U) // User mode implemented 315 val V = RO(21).withReset(1.U) // Vector extension 316 val W = RO(22).withReset(0.U) // Reserved 317 val X = RO(23).withReset(0.U) // Non-standard extensions present 318 val Y = RO(24).withReset(0.U) // Reserved 319 val Z = RO(25).withReset(0.U) // Reserved 320 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 321 322 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 323} 324 325class MedelegBundle extends ExceptionBundle { 326 this.EX_MCALL.setRO() // never delegate machine level ecall 327} 328 329class MidelegBundle extends InterruptBundle { 330 // Don't delegate Machine level interrupts 331 this.getM.foreach(_.setRO().withReset(0.U)) 332 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 333 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 334 // interrupts) are each read-only one. 335 this.getVS.foreach(_.setRO().withReset(1.U)) 336 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 337 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 338 this.SGEI.setRO().withReset(1.U) 339} 340 341class MieBundle extends InterruptEnableBundle { 342 this.SGEIE.setRO() 343 this.getVS.foreach(_.setRO()) 344} 345 346class MipBundle extends InterruptPendingBundle { 347 this.getM.foreach(_.setRO()) 348} 349 350class MvienBundle extends CSRBundle { 351 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 352 // It is strongly recommended that bit 9 of mvien be writable. 353 // It is strongly recommended that bit 1 of mvien also be writable. 354 val SSIE = RW(1) 355 val SEIE = RW(9) 356 val OTHERIE = RW(63, 13) 357} 358 359class MvipBundle extends CSRBundle { 360 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 361 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 362 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 363 val SSIP = RW(1) 364 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 365 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 366 val STIP = RW(5) 367 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 368 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 369 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 370 val SEIP = RW(9) 371 val OTHERIP = RW(63, 13) 372} 373 374class Epc extends CSRBundle { 375 // TODO: configure it with VAddrBits 376 val ALL = RW(63, 1) 377} 378 379class McountinhibitBundle extends CSRBundle { 380 val CY = RW(0) 381 val IR = RW(2) 382 val HPM3 = RW(31, 3) 383} 384 385object MarchidField extends CSREnum with ROApply { 386 val XSArchid = Value(25.U) 387} 388 389class MieToHie extends Bundle { 390 val VSSIE = ValidIO(RW(0)) 391 val VSTIE = ValidIO(RW(0)) 392 val VSEIE = ValidIO(RW(0)) 393 val SGEIE = ValidIO(RW(0)) 394} 395 396class MvipToMip extends Bundle { 397 val SSIP = ValidIO(RW(0)) 398 val STIP = ValidIO(RW(0)) 399 val SEIP = ValidIO(RW(0)) 400} 401 402trait HasMachineInterruptBundle { self: CSRModule[_] => 403 val mvien = IO(Input(new MvienBundle)) 404 val mvip = IO(Input(new MvipBundle)) 405 val mip = IO(Input(new MipBundle)) 406 val mie = IO(Input(new MieBundle)) 407} 408 409trait HasMachineDelegBundle { self: CSRModule[_] => 410 val mideleg = IO(Input(new MidelegBundle)) 411 val medeleg = IO(Input(new MedelegBundle)) 412} 413 414trait HasExternalInterruptBundle { 415 val platformIRP = IO(new Bundle { 416 val MEIP = Input(Bool()) 417 val MTIP = Input(Bool()) 418 val MSIP = Input(Bool()) 419 val SEIP = Input(Bool()) 420 val VSEIP = Input(Bool()) 421 val VSTIP = Input(Bool()) 422 // debug interrupt from debug module 423 val debugIP = Input(Bool()) 424 }) 425} 426 427trait HasMachineCounterControlBundle { self: CSRModule[_] => 428 val mcountinhibit = IO(Input(new McountinhibitBundle)) 429} 430 431trait HasRobCommitBundle { self: CSRModule[_] => 432 val robCommit = IO(Input(new RobCommitCSR)) 433}