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