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