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