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 210class MstatusBundle extends CSRBundle { 211 212 val SIE = CSRRWField (1).withReset(0.U) 213 val MIE = CSRRWField (3).withReset(0.U) 214 val SPIE = CSRRWField (5).withReset(0.U) 215 val UBE = CSRROField (6).withReset(0.U) 216 val MPIE = CSRRWField (7).withReset(0.U) 217 val SPP = CSRRWField (8).withReset(0.U) 218 val VS = ContextStatus (10, 9).withReset(ContextStatus.Initial) 219 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 220 val FS = ContextStatus (14, 13).withReset(ContextStatus.Initial) 221 val XS = ContextStatusRO(16, 15).withReset(0.U) 222 val MPRV = CSRRWField (17).withReset(0.U) 223 val SUM = CSRRWField (18).withReset(0.U) 224 val MXR = CSRRWField (19).withReset(0.U) 225 val TVM = CSRRWField (20).withReset(0.U) 226 val TW = CSRRWField (21).withReset(0.U) 227 val TSR = CSRRWField (22).withReset(0.U) 228 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 229 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 230 val SBE = CSRROField (36).withReset(0.U) 231 val MBE = CSRROField (37).withReset(0.U) 232 val GVA = CSRRWField (38).withReset(0.U) 233 val MPV = VirtMode (39).withReset(0.U) 234 val SD = CSRROField (63, 235 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 236 ) 237} 238 239class MstatusModule extends CSRModule("MStatus", new MstatusBundle) 240 with TrapEntryMEventSinkBundle 241 with TrapEntryHSEventSinkBundle 242 with MretEventSinkBundle 243 with SretEventSinkBundle 244{ 245 val mstatus = IO(Output(bundle)) 246 val sstatus = IO(Output(new SstatusBundle)) 247 248 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 249 250 // write connection 251 this.wfn(reg)(Seq(wAliasSstatus)) 252 253 // read connection 254 mstatus :|= reg 255 sstatus := mstatus 256 rdata := mstatus.asUInt 257} 258 259class MisaBundle extends CSRBundle { 260 // Todo: reset with ISA string 261 val A = RO( 0).withReset(1.U) // Atomic extension 262 val B = RO( 1).withReset(0.U) // Reserved 263 val C = RO( 2).withReset(1.U) // Compressed extension 264 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 265 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 266 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 267 val G = RO( 6).withReset(0.U) // Reserved 268 val H = RO( 7).withReset(1.U) // Hypervisor extension 269 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 270 val J = RO( 9).withReset(0.U) // Reserved 271 val K = RO(10).withReset(0.U) // Reserved 272 val L = RO(11).withReset(0.U) // Reserved 273 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 274 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 275 val O = RO(14).withReset(0.U) // Reserved 276 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 277 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 278 val R = RO(17).withReset(0.U) // Reserved 279 val S = RO(18).withReset(1.U) // Supervisor mode implemented 280 val T = RO(19).withReset(0.U) // Reserved 281 val U = RO(20).withReset(1.U) // User mode implemented 282 val V = RO(21).withReset(1.U) // Vector extension 283 val W = RO(22).withReset(0.U) // Reserved 284 val X = RO(23).withReset(0.U) // Non-standard extensions present 285 val Y = RO(24).withReset(0.U) // Reserved 286 val Z = RO(25).withReset(0.U) // Reserved 287 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 288 289 def getISAString = this.getFields.filter(x => x != MXL && x.init.get.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 290} 291 292class MedelegBundle extends ExceptionBundle { 293 this.EX_MCALL.setRO() // never delegate machine level ecall 294} 295 296class MidelegBundle extends InterruptBundle { 297 // Don't delegate Machine level interrupts 298 this.getM.foreach(_.setRO().withReset(0.U)) 299 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 300 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 301 // interrupts) are each read-only one. 302 this.getVS.foreach(_.setRO().withReset(1.U)) 303 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 304 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 305 this.SGEI.setRO().withReset(1.U) 306} 307 308class MieBundle extends InterruptEnableBundle { 309 this.SGEIE.setRO() 310 this.getVS.foreach(_.setRO()) 311} 312 313class MipBundle extends InterruptPendingBundle { 314 this.getM.foreach(_.setRO()) 315} 316 317class MvienBundle extends CSRBundle { 318 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 319 // It is strongly recommended that bit 9 of mvien be writable. 320 // It is strongly recommended that bit 1 of mvien also be writable. 321 val SSIE = RW(1) 322 val SEIE = RW(9) 323 val OTHERIE = RW(63, 13) 324} 325 326class MvipBundle extends CSRBundle { 327 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 328 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 329 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 330 val SSIP = RW(1) 331 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 332 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 333 val STIP = RW(5) 334 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 335 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 336 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 337 val SEIP = RW(9) 338 val OTHERIP = RW(63, 13) 339} 340 341class Epc extends CSRBundle { 342 // TODO: configure it with VAddrBits 343 val ALL = RW(63, 1) 344} 345 346class McountinhibitBundle extends CSRBundle { 347 val CY = RW(0) 348 val IR = RW(2) 349 val HPM3 = RW(31, 3) 350} 351 352object MarchidField extends CSREnum with CSRROApply { 353 val XSArchid = Value(25.U) 354} 355 356class MieToHie extends Bundle { 357 val VSSIE = ValidIO(RW(0)) 358 val VSTIE = ValidIO(RW(0)) 359 val VSEIE = ValidIO(RW(0)) 360 val SGEIE = ValidIO(RW(0)) 361} 362 363class MvipToMip extends Bundle { 364 val SSIP = ValidIO(RW(0)) 365 val STIP = ValidIO(RW(0)) 366 val SEIP = ValidIO(RW(0)) 367} 368 369trait HasMachineInterruptBundle { self: CSRModule[_] => 370 val mvien = IO(Input(new MvienBundle)) 371 val mvip = IO(Input(new MvipBundle)) 372 val mip = IO(Input(new MipBundle)) 373 val mie = IO(Input(new MieBundle)) 374} 375 376trait HasMachineDelegBundle { self: CSRModule[_] => 377 val mideleg = IO(Input(new MidelegBundle)) 378 val medeleg = IO(Input(new MedelegBundle)) 379} 380 381trait HasExternalInterruptBundle { 382 val platformIRP = IO(new Bundle { 383 val MEIP = Input(Bool()) 384 val MTIP = Input(Bool()) 385 val MSIP = Input(Bool()) 386 val SEIP = Input(Bool()) 387 val VSEIP = Input(Bool()) 388 val VSTIP = Input(Bool()) 389 }) 390} 391 392trait HasMachineCounterControlBundle { self: CSRModule[_] => 393 val mcountinhibit = IO(Input(new McountinhibitBundle)) 394} 395 396trait HasInstCommitBundle { 397 val commitValid = IO(Input(Bool())) 398 // need contain 8x8 399 val commitInstNum = IO(Input(UInt(7.W))) 400}