xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 6683fc49ec7b83860c24b77ed5d96eb0bee19928)
1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR
2039cdc35SXuan Hu
3039cdc35SXuan Huimport chisel3._
4c2a2229dSlewislzhimport chisel3.experimental.SourceInfo
5039cdc35SXuan Huimport chisel3.util._
601cdded8SXuan Huimport org.chipsalliance.cde.config.Parameters
72c054816SsinceforYyimport freechips.rocketchip.rocket.CSRs
844f2941bSJiru Sunimport utility.{SignExt, PerfEvent}
9039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles._
10039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines._
111d192ad8SXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _}
12237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSREvents._
130b4c00ffSXuan Huimport xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
141d192ad8SXuan Huimport xiangshan.backend.fu.NewCSR.ChiselRecordForField._
15b51a1abdSchengguanghuiimport xiangshan.backend.fu.PerfCounterIO
16b51a1abdSchengguanghuiimport xiangshan.backend.fu.NewCSR.CSRConfig._
17b8e923e6Schengguanghuiimport xiangshan.backend.fu.NewCSR.CSRFunc._
188882eb68SXin Tianimport xiangshan.backend.fu.util.CSRConst._
19039cdc35SXuan Hu
20039cdc35SXuan Huimport scala.collection.immutable.SeqMap
21039cdc35SXuan Hu
22039cdc35SXuan Hutrait MachineLevel { self: NewCSR =>
238882eb68SXin Tian  // Machine level Custom Read/Write
248882eb68SXin Tian  val mbmc = if (HasBitmapCheck) Some(Module(new CSRModule("Mbmc", new MbmcBundle) {
258882eb68SXin Tian    val mbmc_lock = reg.BME.asBool
268882eb68SXin Tian    if (!HasBitmapCheckDefault) {
278882eb68SXin Tian      reg.BME := Mux(wen && !mbmc_lock, wdata.BME, reg.BME)
288882eb68SXin Tian      reg.CMODE := Mux(wen, wdata.CMODE, reg.CMODE)
298882eb68SXin Tian      reg.BMA := Mux(wen && !mbmc_lock, wdata.BMA, reg.BMA)
308882eb68SXin Tian    } else {
318882eb68SXin Tian      reg.BME := 1.U
328882eb68SXin Tian      reg.CMODE := 0.U
338882eb68SXin Tian      reg.BMA := BMAField.TestBMA
348882eb68SXin Tian    }
358882eb68SXin Tian    reg.BCLEAR := Mux(reg.BCLEAR.asBool, 0.U, Mux(wen && wdata.BCLEAR.asBool, 1.U, 0.U))
368882eb68SXin Tian  })
378882eb68SXin Tian    .setAddr(Mbmc))  else  None
388882eb68SXin Tian
39039cdc35SXuan Hu  val mstatus = Module(new MstatusModule)
402c054816SsinceforYy    .setAddr(CSRs.mstatus)
41039cdc35SXuan Hu
42039cdc35SXuan Hu  val misa = Module(new CSRModule("Misa", new MisaBundle))
432c054816SsinceforYy    .setAddr(CSRs.misa)
44039cdc35SXuan Hu
45039cdc35SXuan Hu  println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}")
46039cdc35SXuan Hu
47039cdc35SXuan Hu  val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle))
482c054816SsinceforYy    .setAddr(CSRs.medeleg)
49039cdc35SXuan Hu
50039cdc35SXuan Hu  val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle))
512c054816SsinceforYy    .setAddr(CSRs.mideleg)
52039cdc35SXuan Hu
531d192ad8SXuan Hu  val mie = Module(new CSRModule("Mie", new MieBundle) with HasIpIeBundle {
541d192ad8SXuan Hu    val fromHie  = IO(Flipped(new HieToMie))
55039cdc35SXuan Hu    val fromSie  = IO(Flipped(new SieToMie))
561d192ad8SXuan Hu    val fromVSie = IO(Flipped(new VSieToMie))
57039cdc35SXuan Hu
581d192ad8SXuan Hu    // bit 1 SSIE
591d192ad8SXuan Hu    when (fromSie.SSIE.valid) {
601d192ad8SXuan Hu      reg.SSIE := fromSie.SSIE.bits
611d192ad8SXuan Hu    }
62039cdc35SXuan Hu
631d192ad8SXuan Hu    // bit 2 VSSIE
641d192ad8SXuan Hu    when (fromHie.VSSIE.valid || fromVSie.VSSIE.valid) {
651d192ad8SXuan Hu      reg.VSSIE := Mux1H(Seq(
661d192ad8SXuan Hu        fromHie .VSSIE.valid -> fromHie .VSSIE.bits,
671d192ad8SXuan Hu        fromVSie.VSSIE.valid -> fromVSie.VSSIE.bits,
681d192ad8SXuan Hu      ))
691d192ad8SXuan Hu    }
70039cdc35SXuan Hu
711d192ad8SXuan Hu    // bit 5 STIE
721d192ad8SXuan Hu    when(fromSie.STIE.valid) {
731d192ad8SXuan Hu      reg.STIE := fromSie.STIE.bits
741d192ad8SXuan Hu    }
751d192ad8SXuan Hu
761d192ad8SXuan Hu    // bit 6 VSTIE
771d192ad8SXuan Hu    when(fromHie.VSTIE.valid || fromVSie.VSTIE.valid) {
781d192ad8SXuan Hu      reg.VSTIE := Mux1H(Seq(
791d192ad8SXuan Hu        fromHie .VSTIE.valid -> fromHie .VSTIE.bits,
801d192ad8SXuan Hu        fromVSie.VSTIE.valid -> fromVSie.VSTIE.bits,
811d192ad8SXuan Hu      ))
821d192ad8SXuan Hu    }
831d192ad8SXuan Hu
841d192ad8SXuan Hu    // bit 9 SEIE
851d192ad8SXuan Hu    when(fromSie.SEIE.valid) {
861d192ad8SXuan Hu      reg.SEIE := fromSie.SEIE.bits
871d192ad8SXuan Hu    }
881d192ad8SXuan Hu
891d192ad8SXuan Hu    // bit 10 VSEIE
901d192ad8SXuan Hu    when(fromHie.VSEIE.valid || fromVSie.VSEIE.valid) {
911d192ad8SXuan Hu      reg.VSEIE := Mux1H(Seq(
921d192ad8SXuan Hu        fromHie .VSEIE.valid -> fromHie .VSEIE.bits,
931d192ad8SXuan Hu        fromVSie.VSEIE.valid -> fromVSie.VSEIE.bits,
941d192ad8SXuan Hu      ))
951d192ad8SXuan Hu    }
961d192ad8SXuan Hu
971d192ad8SXuan Hu    // bit 12 SGEIE
981d192ad8SXuan Hu    when(fromHie.SGEIE.valid) {
991d192ad8SXuan Hu      reg.SGEIE := fromHie.SGEIE.bits
1001d192ad8SXuan Hu    }
1011d192ad8SXuan Hu
1021d192ad8SXuan Hu    // bit 13~63 LCIP
1031d192ad8SXuan Hu    reg.getLocal lazyZip fromSie.getLocal lazyZip fromVSie.getLocal foreach { case (rLCIE, sieLCIE, vsieLCIE) =>
1041d192ad8SXuan Hu      when (sieLCIE.valid || vsieLCIE.valid) {
1051d192ad8SXuan Hu        rLCIE := Mux1H(Seq(
1061d192ad8SXuan Hu          sieLCIE .valid -> sieLCIE .bits,
1071d192ad8SXuan Hu          vsieLCIE.valid -> vsieLCIE.bits,
1081d192ad8SXuan Hu        ))
1091d192ad8SXuan Hu      }
1101d192ad8SXuan Hu    }
1111d192ad8SXuan Hu
1121d192ad8SXuan Hu    // 14~63 read only 0
1131d192ad8SXuan Hu    regOut.getLocal.filterNot(_.lsb == InterruptNO.COI).foreach(_ := 0.U)
1142c054816SsinceforYy  }).setAddr(CSRs.mie)
115039cdc35SXuan Hu
116039cdc35SXuan Hu  val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle))
1172c054816SsinceforYy    .setAddr(CSRs.mtvec)
118039cdc35SXuan Hu
119039cdc35SXuan Hu  // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0
120039cdc35SXuan Hu  // Todo: support Sscounterenw Extension
121039cdc35SXuan Hu  val mcounteren = Module(new CSRModule("Mcounteren", new Counteren))
1222c054816SsinceforYy    .setAddr(CSRs.mcounteren)
123039cdc35SXuan Hu
124039cdc35SXuan Hu  val mvien = Module(new CSRModule("Mvien", new MvienBundle))
1252c054816SsinceforYy    .setAddr(CSRs.mvien)
126039cdc35SXuan Hu
1270b4c00ffSXuan Hu  val mvip = Module(new CSRModule("Mvip", new MvipBundle)
1281d192ad8SXuan Hu    with HasIpIeBundle
1290b4c00ffSXuan Hu    with HasMachineEnvBundle
1300b4c00ffSXuan Hu  {
1311d192ad8SXuan Hu    val toMip = IO(new MvipToMip).connectZeroNonRW
1321d192ad8SXuan Hu    val fromMip = IO(Flipped(new MipToMvip))
1331d192ad8SXuan Hu    val fromSip = IO(Flipped(new SipToMvip))
1341d192ad8SXuan Hu    val fromVSip = IO(Flipped(new VSipToMvip))
135039cdc35SXuan Hu
136039cdc35SXuan Hu    // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
137039cdc35SXuan Hu    // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
138039cdc35SXuan Hu    // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
1391d192ad8SXuan Hu    // XiangShan will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one
140e3da8badSTang Haojin    reg.SSIP := Mux(wen && this.mvien.SSIE.asBool, wdata.SSIP, reg.SSIP)
141e3da8badSTang Haojin    regOut.SSIP := Mux(this.mvien.SSIE.asBool, reg.SSIP, this.mip.SSIP)
142e3da8badSTang Haojin    toMip.SSIP.valid := wen && !this.mvien.SSIE.asBool
143039cdc35SXuan Hu    toMip.SSIP.bits := wdata.SSIP
144039cdc35SXuan Hu
145039cdc35SXuan Hu    // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
146039cdc35SXuan Hu    // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
147039cdc35SXuan Hu    // Todo: check mip writable when menvcfg.STCE = 1
1485d045f85SXuan Hu    regOut.STIP := Mux(this.menvcfg.STCE.asBool, 0.U, this.mip.STIP.asBool)
1490b4c00ffSXuan Hu    // Don't update mip.STIP when menvcfg.STCE is 1
1500b4c00ffSXuan Hu    toMip.STIP.valid := wen && !this.menvcfg.STCE.asBool
151039cdc35SXuan Hu    toMip.STIP.bits := wdata.STIP
152039cdc35SXuan Hu
153039cdc35SXuan Hu    // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
154039cdc35SXuan Hu    // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
155039cdc35SXuan Hu    // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
156e3da8badSTang Haojin    toMip.SEIP.valid := wen && !this.mvien.SEIE.asUInt.asBool
157039cdc35SXuan Hu    toMip.SEIP.bits := wdata.SEIP
1581d192ad8SXuan Hu    when (fromMip.SEIP.valid) {
1591d192ad8SXuan Hu      reg.SEIP := fromMip.SEIP.bits
1601d192ad8SXuan Hu    }
1611d192ad8SXuan Hu
1621d192ad8SXuan Hu    // write from sip
1631d192ad8SXuan Hu    when (fromSip.SSIP.valid) {
1641d192ad8SXuan Hu      reg.SSIP := fromSip.SSIP.bits
1651d192ad8SXuan Hu    }
1661d192ad8SXuan Hu
1671d192ad8SXuan Hu    reg.getLocal lazyZip fromSip.getLocal lazyZip fromVSip.getLocal foreach { case (rLCIP, sipLCIP, vsipLCIP) =>
1681d192ad8SXuan Hu      // sip should assert valid when mideleg=0 && mvien=1
1691d192ad8SXuan Hu      when (sipLCIP.valid || vsipLCIP.valid) {
1701d192ad8SXuan Hu        rLCIP := Mux1H(Seq(
1711d192ad8SXuan Hu          sipLCIP .valid -> sipLCIP .bits,
1721d192ad8SXuan Hu          vsipLCIP.valid -> vsipLCIP.bits,
1731d192ad8SXuan Hu        ))
1741d192ad8SXuan Hu      }
1751d192ad8SXuan Hu    }
1762c054816SsinceforYy  }).setAddr(CSRs.mvip)
177039cdc35SXuan Hu
1780b4c00ffSXuan Hu  val menvcfg = Module(new CSRModule("Menvcfg", new MEnvCfg))
1792c054816SsinceforYy    .setAddr(CSRs.menvcfg)
180039cdc35SXuan Hu
181039cdc35SXuan Hu  val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle))
1822c054816SsinceforYy    .setAddr(CSRs.mcountinhibit)
183039cdc35SXuan Hu
184039cdc35SXuan Hu  val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
185a67fd0f5SGuanghui Cheng    Module(new CSRModule(s"Mhpmevent", new MhpmeventBundle) with HasOfFromPerfCntBundle {
186b8e923e6Schengguanghui      when(wen){
187b8e923e6Schengguanghui        reg.OF := wdata.OF
188b8e923e6Schengguanghui      }.elsewhen(ofFromPerfCnt) {
189b8e923e6Schengguanghui        reg.OF := ofFromPerfCnt
190b8e923e6Schengguanghui      }
191b51a1abdSchengguanghui    })
192a67fd0f5SGuanghui Cheng      .setAddr(CSRs.mhpmevent3 - 3 + num).suggestName(s"Mhpmevent$num")
193039cdc35SXuan Hu  )
194039cdc35SXuan Hu
195039cdc35SXuan Hu  val mscratch = Module(new CSRModule("Mscratch"))
1962c054816SsinceforYy    .setAddr(CSRs.mscratch)
197039cdc35SXuan Hu
1983e8a0170SXuan Hu  val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle)
1992c054816SsinceforYy    .setAddr(CSRs.mepc)
200039cdc35SXuan Hu
201499d09b3SsinceforYy  val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle)
2022c054816SsinceforYy    .setAddr(CSRs.mcause)
203039cdc35SXuan Hu
204499d09b3SsinceforYy  val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle)
2052c054816SsinceforYy    .setAddr(CSRs.mtval)
206039cdc35SXuan Hu
2070b4c00ffSXuan Hu  val mip = Module(new CSRModule("Mip", new MipBundle)
2081d192ad8SXuan Hu    with HasIpIeBundle
2090b4c00ffSXuan Hu    with HasExternalInterruptBundle
2100b4c00ffSXuan Hu    with HasMachineEnvBundle
211202093f4Schengguanghui    with HasLocalInterruptReqBundle
21289bb2535SXuan Hu    with HasAIABundle
2130b4c00ffSXuan Hu  {
2141d192ad8SXuan Hu    // Alias write in
215039cdc35SXuan Hu    val fromMvip = IO(Flipped(new MvipToMip))
216039cdc35SXuan Hu    val fromSip  = IO(Flipped(new SipToMip))
2171d192ad8SXuan Hu    val fromVSip = IO(Flipped(new VSipToMip))
2181d192ad8SXuan Hu    // Alias write out
2191d192ad8SXuan Hu    val toMvip   = IO(new MipToMvip).connectZeroNonRW
2201d192ad8SXuan Hu    val toHvip   = IO(new MipToHvip).connectZeroNonRW
221039cdc35SXuan Hu
2221d192ad8SXuan Hu    // bit 1 SSIP
2231d192ad8SXuan Hu    when (fromMvip.SSIP.valid || fromSip.SSIP.valid) {
2241d192ad8SXuan Hu      reg.SSIP := Mux1H(Seq(
2251d192ad8SXuan Hu        fromMvip.SSIP.valid -> fromMvip.SSIP.bits,
2261d192ad8SXuan Hu        fromSip .SSIP.valid -> fromSip .SSIP.bits,
2271d192ad8SXuan Hu      ))
2281d192ad8SXuan Hu    }
229039cdc35SXuan Hu
2301d192ad8SXuan Hu    // bit 2 VSSIP reg in hvip
2311d192ad8SXuan Hu    // alias of hvip.VSSIP
2321d192ad8SXuan Hu    toHvip.VSSIP.valid := wen
2331d192ad8SXuan Hu    toHvip.VSSIP.bits  := wdata.VSSIP
2341d192ad8SXuan Hu    regOut.VSSIP := hvip.VSSIP
2351d192ad8SXuan Hu
2361d192ad8SXuan Hu    // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers,
2371d192ad8SXuan Hu    // which are used by remote harts to provide machine-level interprocessor interrupts.
2381d192ad8SXuan Hu    regOut.MSIP := platformIRP.MSIP
2391d192ad8SXuan Hu
2401d192ad8SXuan Hu    // bit 5 STIP
2410b4c00ffSXuan Hu    // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip.
2420b4c00ffSXuan Hu    regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool)
2431d192ad8SXuan Hu    when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) {
2441d192ad8SXuan Hu      reg.STIP := Mux1H(Seq(
2451d192ad8SXuan Hu        wen -> wdata.STIP,
2461d192ad8SXuan Hu        fromMvip.STIP.valid -> fromMvip.STIP.bits,
2471d192ad8SXuan Hu      ))
248d372710aSsinceforYy    }.otherwise {
249d372710aSsinceforYy      reg.STIP := reg.STIP
2501d192ad8SXuan Hu    }
2511d192ad8SXuan Hu
2521d192ad8SXuan Hu    // bit 6 VSTIP
2531d192ad8SXuan Hu    regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP
2541d192ad8SXuan Hu
2551d192ad8SXuan Hu    // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register
2561d192ad8SXuan Hu    regOut.MTIP := platformIRP.MTIP
2571d192ad8SXuan Hu
2581d192ad8SXuan Hu    // bit 9 SEIP
2591d192ad8SXuan Hu    // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP.
2601d192ad8SXuan Hu    // 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.
2611d192ad8SXuan Hu    //
2621d192ad8SXuan Hu    // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64),
2631d192ad8SXuan Hu    // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of
2641d192ad8SXuan Hu    // mip.SEIP reg and other source from the interrupt controller.
2651d192ad8SXuan Hu    // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller.
2661d192ad8SXuan Hu    //
2671d192ad8SXuan Hu    // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0
2681d192ad8SXuan Hu    // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller.
2691d192ad8SXuan Hu
27055a6515dSsinceforYy    toMvip.SEIP.valid := wen && !this.mvien.SEIE
2711d192ad8SXuan Hu    toMvip.SEIP.bits := wdata.SEIP
2721d192ad8SXuan Hu    // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP.
2731d192ad8SXuan Hu    // Otherwise, mip.SEIP is read only 0
274e3da8badSTang Haojin    regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U)
27589bb2535SXuan Hu    rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip
2761d192ad8SXuan Hu
2771d192ad8SXuan Hu    // bit 10 VSEIP
278389236bfSXuan Hu    regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt)
2791d192ad8SXuan Hu
2801d192ad8SXuan Hu    // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller.
28189bb2535SXuan Hu    // MEIP can from PLIC and IMSIC
28289bb2535SXuan Hu    regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip
2831d192ad8SXuan Hu
2841d192ad8SXuan Hu    // bit 12 SGEIP
2851d192ad8SXuan Hu    regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR
2861d192ad8SXuan Hu
2871d192ad8SXuan Hu    // bit 13 LCOFIP
2883acccecbSsinceforYy    when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) {
2891d192ad8SXuan Hu      reg.LCOFIP := Mux1H(Seq(
2901d192ad8SXuan Hu        fromSip.LCOFIP.valid  -> fromSip.LCOFIP.bits,
2911d192ad8SXuan Hu        fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits,
2923acccecbSsinceforYy        wen -> wdata.LCOFIP,
2931d192ad8SXuan Hu      ))
29414d856d9SXuan Hu    }.elsewhen(lcofiReq) {
29514d856d9SXuan Hu      reg.LCOFIP := lcofiReq
296d372710aSsinceforYy    }.otherwise {
297d372710aSsinceforYy      reg.LCOFIP := reg.LCOFIP
2981d192ad8SXuan Hu    }
2992c054816SsinceforYy  }).setAddr(CSRs.mip)
300039cdc35SXuan Hu
301499d09b3SsinceforYy  val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle)
3022c054816SsinceforYy    .setAddr(CSRs.mtinst)
303039cdc35SXuan Hu
304499d09b3SsinceforYy  val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle)
3052c054816SsinceforYy    .setAddr(CSRs.mtval2)
306039cdc35SXuan Hu
307039cdc35SXuan Hu  val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle {
308189833a1SHaoyuan Feng    val PMM   = EnvPMM(33, 32, wNoEffect).withReset(EnvPMM.Disable)  // Smmpm extension
309cb36ac0fSXuan Hu    val MLPE  = RO(10) // Landing pand, Zicfilp extension
310cb36ac0fSXuan Hu    val SSEED = RO( 9) // Zkr extension
311cb36ac0fSXuan Hu    val USEED = RO( 8) // Zkr extension
312cb36ac0fSXuan Hu    val RLB   = RO( 2) // Smepmp
313cb36ac0fSXuan Hu    val MMWP  = RO( 1) // Smepmp
314cb36ac0fSXuan Hu    val MML   = RO( 0) // Smepmp
3152c054816SsinceforYy  })).setAddr(CSRs.mseccfg)
316039cdc35SXuan Hu
317039cdc35SXuan Hu  val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle {
31846c32738SXuan Hu    when(w.wen) {
31946c32738SXuan Hu      reg := w.wdata
320e3da8badSTang Haojin    }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) {
32146c32738SXuan Hu      reg := reg.ALL.asUInt + 1.U
32246c32738SXuan Hu    }.otherwise {
32346c32738SXuan Hu      reg := reg
32446c32738SXuan Hu    }
3252c054816SsinceforYy  }).setAddr(CSRs.mcycle)
326039cdc35SXuan Hu
3271d192ad8SXuan Hu
32801cdded8SXuan Hu  val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle {
32946c32738SXuan Hu    when(w.wen) {
33046c32738SXuan Hu      reg := w.wdata
331e3da8badSTang Haojin    }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) {
33246c32738SXuan Hu      reg := reg.ALL.asUInt + robCommit.instNum.bits
33346c32738SXuan Hu    }.otherwise {
33446c32738SXuan Hu      reg := reg
33546c32738SXuan Hu    }
3362c054816SsinceforYy  }).setAddr(CSRs.minstret)
337039cdc35SXuan Hu
338039cdc35SXuan Hu  val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
339499d09b3SsinceforYy    Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle {
340e3da8badSTang Haojin      val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn
341202093f4Schengguanghui      val counterAdd = reg.ALL.asUInt +& perf.value
34246c32738SXuan Hu      when (w.wen) {
34346c32738SXuan Hu        reg := w.wdata
34446c32738SXuan Hu      }.elsewhen (perf.value =/= 0.U && !countingInhibit) {
34546c32738SXuan Hu        reg := counterAdd.tail(1)
34646c32738SXuan Hu      }.otherwise {
34746c32738SXuan Hu        reg := reg
34846c32738SXuan Hu      }
349202093f4Schengguanghui      // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from
350202093f4Schengguanghui      // hardware increments of counter registers.
351202093f4Schengguanghui      toMhpmeventOF := !countingInhibit & counterAdd.head(1)
3522c054816SsinceforYy    }).setAddr(CSRs.mhpmcounter3 - 3 + num)
353039cdc35SXuan Hu  )
354039cdc35SXuan Hu
355*6683fc49SZhaoyang You  val mvendorid = Module(new CSRModule("Mvendorid", new CSRBundle {
356*6683fc49SZhaoyang You    val ALL = RO(63, 0)
357*6683fc49SZhaoyang You  }))
3582c054816SsinceforYy    .setAddr(CSRs.mvendorid)
359039cdc35SXuan Hu
360039cdc35SXuan Hu  // architecture id for XiangShan is 25
361039cdc35SXuan Hu  // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md
362039cdc35SXuan Hu  val marchid = Module(new CSRModule("Marchid", new CSRBundle {
363039cdc35SXuan Hu    val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid)
3642c054816SsinceforYy  })).setAddr(CSRs.marchid)
365039cdc35SXuan Hu
366cb4fe84bSXuan Hu  val mimpid = Module(new CSRModule("Mimpid", new CSRBundle {
367cb4fe84bSXuan Hu    val ALL = RO(0).withReset(0.U)
368cb4fe84bSXuan Hu  }))
3692c054816SsinceforYy    .setAddr(CSRs.mimpid)
370cb4fe84bSXuan Hu
371cb4fe84bSXuan Hu  val mhartid = Module(new CSRModule("Mhartid", new CSRBundle {
372bbaa6b7cSXuan Hu    val ALL = RO(hartIdLen - 1, 0)
373cb4fe84bSXuan Hu  }) {
374cb4fe84bSXuan Hu    val hartid = IO(Input(UInt(hartIdLen.W)))
375bbaa6b7cSXuan Hu    this.regOut.ALL := hartid
376cb4fe84bSXuan Hu  })
3772c054816SsinceforYy    .setAddr(CSRs.mhartid)
378cb4fe84bSXuan Hu
379499d09b3SsinceforYy  val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle {
380499d09b3SsinceforYy    val ALL = RO(63, 0)
381499d09b3SsinceforYy  }))
3822c054816SsinceforYy    .setAddr(CSRs.mconfigptr)
383cb4fe84bSXuan Hu
38426033c52Schengguanghui  val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0)
38526033c52Schengguanghui
386c2a2229dSlewislzh  // smrnmi extension
387c2a2229dSlewislzh  val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle {
388c2a2229dSlewislzh    rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
389c2a2229dSlewislzh  })
390c2a2229dSlewislzh    .setAddr(CSRs.mnepc)
391c2a2229dSlewislzh
392c2a2229dSlewislzh  val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle)
393c2a2229dSlewislzh    .setAddr(CSRs.mncause)
394c2a2229dSlewislzh  val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle)
395c2a2229dSlewislzh    with TrapEntryMNEventSinkBundle
396c2a2229dSlewislzh    with MNretEventSinkBundle{
397c2a2229dSlewislzh    // NMIE write 0 with no effect
398c2a2229dSlewislzh    // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing
399c2a2229dSlewislzh    // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered
400c2a2229dSlewislzh//    when(!wdata.NMIE.asBool) {
401c2a2229dSlewislzh//      reg.NMIE := reg.NMIE
402c2a2229dSlewislzh//    }
403c2a2229dSlewislzh  }).setAddr(CSRs.mnstatus)
404c2a2229dSlewislzh  val mnscratch = Module(new CSRModule("Mnscratch"))
405c2a2229dSlewislzh    .setAddr(CSRs.mnscratch)
406c2a2229dSlewislzh
407039cdc35SXuan Hu  val machineLevelCSRMods: Seq[CSRModule[_]] = Seq(
408039cdc35SXuan Hu    mstatus,
409039cdc35SXuan Hu    misa,
410039cdc35SXuan Hu    medeleg,
411039cdc35SXuan Hu    mideleg,
412039cdc35SXuan Hu    mie,
413039cdc35SXuan Hu    mtvec,
414039cdc35SXuan Hu    mcounteren,
415039cdc35SXuan Hu    mvien,
416039cdc35SXuan Hu    mvip,
417039cdc35SXuan Hu    menvcfg,
418039cdc35SXuan Hu    mcountinhibit,
419039cdc35SXuan Hu    mscratch,
420039cdc35SXuan Hu    mepc,
421039cdc35SXuan Hu    mcause,
422039cdc35SXuan Hu    mtval,
423039cdc35SXuan Hu    mip,
424039cdc35SXuan Hu    mtinst,
425039cdc35SXuan Hu    mtval2,
426039cdc35SXuan Hu    mseccfg,
427039cdc35SXuan Hu    mcycle,
428039cdc35SXuan Hu    minstret,
429039cdc35SXuan Hu    mvendorid,
430039cdc35SXuan Hu    marchid,
431cb4fe84bSXuan Hu    mimpid,
432cb4fe84bSXuan Hu    mhartid,
433cb4fe84bSXuan Hu    mconfigptr,
43426033c52Schengguanghui    mstateen0,
435c2a2229dSlewislzh    mnepc,
436c2a2229dSlewislzh    mncause,
437c2a2229dSlewislzh    mnstatus,
438c2a2229dSlewislzh    mnscratch,
4398882eb68SXin Tian  ) ++ mhpmevents ++ mhpmcounters ++ (if (HasBitmapCheck) Seq(mbmc.get) else Seq())
4408882eb68SXin Tian
441039cdc35SXuan Hu
44294895e77SXuan Hu  val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
4438aa89407SXuan Hu    machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
444039cdc35SXuan Hu  )
445e877d8bfSXuan Hu
446e877d8bfSXuan Hu  val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
447e877d8bfSXuan Hu    machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
448e877d8bfSXuan Hu  )
449b51a1abdSchengguanghui
450039cdc35SXuan Hu}
451039cdc35SXuan Hu
4528882eb68SXin Tianclass MbmcBundle extends  CSRBundle {
4538882eb68SXin Tian  val BMA  = BMAField(63,6,null).withReset(BMAField.ResetBMA)
4548882eb68SXin Tian  val BME  = RW(2).withReset(0.U)
4558882eb68SXin Tian  val BCLEAR = RW(1).withReset(0.U)
4568882eb68SXin Tian  val CMODE  = RW(0).withReset(0.U)
4578882eb68SXin Tian}
4588882eb68SXin Tian
459039cdc35SXuan Huclass MstatusBundle extends CSRBundle {
460039cdc35SXuan Hu
461039cdc35SXuan Hu  val SIE  = CSRRWField     (1).withReset(0.U)
462039cdc35SXuan Hu  val MIE  = CSRRWField     (3).withReset(0.U)
463039cdc35SXuan Hu  val SPIE = CSRRWField     (5).withReset(0.U)
464039cdc35SXuan Hu  val UBE  = CSRROField     (6).withReset(0.U)
465039cdc35SXuan Hu  val MPIE = CSRRWField     (7).withReset(0.U)
466039cdc35SXuan Hu  val SPP  = CSRRWField     (8).withReset(0.U)
46701cdded8SXuan Hu  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Off)
468039cdc35SXuan Hu  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
46901cdded8SXuan Hu  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
470039cdc35SXuan Hu  val XS   = ContextStatusRO(16, 15).withReset(0.U)
471039cdc35SXuan Hu  val MPRV = CSRRWField     (17).withReset(0.U)
472039cdc35SXuan Hu  val SUM  = CSRRWField     (18).withReset(0.U)
473039cdc35SXuan Hu  val MXR  = CSRRWField     (19).withReset(0.U)
474039cdc35SXuan Hu  val TVM  = CSRRWField     (20).withReset(0.U)
475039cdc35SXuan Hu  val TW   = CSRRWField     (21).withReset(0.U)
476039cdc35SXuan Hu  val TSR  = CSRRWField     (22).withReset(0.U)
4776808b803SZehao Liu  val SDT  = CSRRWField     (24).withReset(0.U)
478039cdc35SXuan Hu  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
479039cdc35SXuan Hu  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
480039cdc35SXuan Hu  val SBE  = CSRROField     (36).withReset(0.U)
481039cdc35SXuan Hu  val MBE  = CSRROField     (37).withReset(0.U)
482039cdc35SXuan Hu  val GVA  = CSRRWField     (38).withReset(0.U)
483237d4cfdSXuan Hu  val MPV  = VirtMode       (39).withReset(0.U)
4846808b803SZehao Liu  val MDT  = CSRRWField     (42).withReset(mdtInit.U)
485039cdc35SXuan Hu  val SD   = CSRROField     (63,
486039cdc35SXuan Hu    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
487039cdc35SXuan Hu  )
488039cdc35SXuan Hu}
489039cdc35SXuan Hu
49001cdded8SXuan Huclass MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
491237d4cfdSXuan Hu  with TrapEntryMEventSinkBundle
492237d4cfdSXuan Hu  with TrapEntryHSEventSinkBundle
493a7a6d0a6Schengguanghui  with DretEventSinkBundle
494237d4cfdSXuan Hu  with MretEventSinkBundle
495c2a2229dSlewislzh  with MNretEventSinkBundle
496237d4cfdSXuan Hu  with SretEventSinkBundle
49701cdded8SXuan Hu  with HasRobCommitBundle
4986808b803SZehao Liu  with HasMachineEnvBundle
499237d4cfdSXuan Hu{
500039cdc35SXuan Hu  val mstatus = IO(Output(bundle))
501039cdc35SXuan Hu  val sstatus = IO(Output(new SstatusBundle))
50294895e77SXuan Hu  val sstatusRdata = IO(Output(UInt(64.W)))
503039cdc35SXuan Hu
504039cdc35SXuan Hu  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
505cb36ac0fSXuan Hu  for ((name, field) <- wAliasSstatus.wdataFields.elements) {
506cb36ac0fSXuan Hu    reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
507cb36ac0fSXuan Hu      wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal,
508cb36ac0fSXuan Hu      field.asInstanceOf[CSREnumType]
509cb36ac0fSXuan Hu    )
510cb36ac0fSXuan Hu  }
511039cdc35SXuan Hu
512039cdc35SXuan Hu  // write connection
513cb36ac0fSXuan Hu  reconnectReg()
514039cdc35SXuan Hu
515a0231889SXuan Hu  when (robCommit.fsDirty || writeFCSR) {
51601cdded8SXuan Hu    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
51701cdded8SXuan Hu    reg.FS := ContextStatus.Dirty
51801cdded8SXuan Hu  }
51901cdded8SXuan Hu
520a0231889SXuan Hu  when (robCommit.vsDirty || writeVCSR) {
52101cdded8SXuan Hu    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
52201cdded8SXuan Hu    reg.VS := ContextStatus.Dirty
52301cdded8SXuan Hu  }
5246808b803SZehao Liu  // when MDT is explicitly written by 1, clear MIE
5256808b803SZehao Liu  // only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1
5266808b803SZehao Liu  when (w.wdataFields.MDT && w.wen) {
5276808b803SZehao Liu    reg.MIE := false.B
5286808b803SZehao Liu  }
5296808b803SZehao Liu  // when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block)
5303a0de677Slewislzh  val writeSstatusSDT = Wire(Bool())
5313a0de677Slewislzh  val writeMstatusSDT = Wire(Bool())
5326808b803SZehao Liu  val writeSDT        = Wire(Bool())
5333a0de677Slewislzh  writeMstatusSDT := w.wdataFields.SDT.asBool
5343a0de677Slewislzh  writeSstatusSDT := Mux(this.menvcfg.DTE.asBool, wAliasSstatus.wdataFields.SDT.asBool, reg.SDT.asBool)
5353a0de677Slewislzh  writeSDT        := Mux(w.wen, writeMstatusSDT, wAliasSstatus.wen && writeSstatusSDT)
5365e3dd635Slewislzh  // menvcfg.DTE only control Smode dbltrp. Thus mstatus.sdt will not control by DTE.
5375e3dd635Slewislzh  // as sstatus is alias of mstatus, when menvcfg.DTE close write,
5385e3dd635Slewislzh  // sstatus.sdt cannot lead to shadow write of mstatus.sdt. \
5395e3dd635Slewislzh  // As a result, we add wmask of sdt, when write source is from alias write.
5403a0de677Slewislzh  when (!this.menvcfg.DTE.asBool && wAliasSstatus.wen) {
5415e3dd635Slewislzh    reg.SDT := reg.SDT
5426808b803SZehao Liu  }
5436808b803SZehao Liu  // SDT and SIE is the same as MDT and MIE
5446808b803SZehao Liu  when (writeSDT) {
5456808b803SZehao Liu    reg.SIE := false.B
5466808b803SZehao Liu  }
547039cdc35SXuan Hu  // read connection
5486808b803SZehao Liu  mstatus :|= regOut
549039cdc35SXuan Hu  sstatus := mstatus
5505e3dd635Slewislzh  sstatus.SDT := regOut.SDT && menvcfg.DTE
551039cdc35SXuan Hu  rdata := mstatus.asUInt
55294895e77SXuan Hu  sstatusRdata := sstatus.asUInt
553039cdc35SXuan Hu}
554039cdc35SXuan Hu
555cb36ac0fSXuan Huclass MnstatusBundle extends CSRBundle {
556c2a2229dSlewislzh  val NMIE   = CSRRWField  (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open
557c2a2229dSlewislzh  val MNPV   = VirtMode    (7).withReset(0.U)
558cb36ac0fSXuan Hu  val MNPELP = RO          (9).withReset(0.U)
559c2a2229dSlewislzh  val MNPP   = PrivMode    (12, 11).withReset(PrivMode.U)
560c2a2229dSlewislzh}
561cb36ac0fSXuan Hu
562039cdc35SXuan Huclass MisaBundle extends CSRBundle {
563039cdc35SXuan Hu  // Todo: reset with ISA string
564039cdc35SXuan Hu  val A = RO( 0).withReset(1.U) // Atomic extension
56522a9a455Slinzhida  val B = RO( 1).withReset(1.U) // B extension
566039cdc35SXuan Hu  val C = RO( 2).withReset(1.U) // Compressed extension
567039cdc35SXuan Hu  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
568039cdc35SXuan Hu  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
569039cdc35SXuan Hu  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
570039cdc35SXuan Hu  val G = RO( 6).withReset(0.U) // Reserved
571039cdc35SXuan Hu  val H = RO( 7).withReset(1.U) // Hypervisor extension
572039cdc35SXuan Hu  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
573039cdc35SXuan Hu  val J = RO( 9).withReset(0.U) // Reserved
574039cdc35SXuan Hu  val K = RO(10).withReset(0.U) // Reserved
575039cdc35SXuan Hu  val L = RO(11).withReset(0.U) // Reserved
576039cdc35SXuan Hu  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
577039cdc35SXuan Hu  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
578039cdc35SXuan Hu  val O = RO(14).withReset(0.U) // Reserved
579039cdc35SXuan Hu  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
580039cdc35SXuan Hu  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
581039cdc35SXuan Hu  val R = RO(17).withReset(0.U) // Reserved
582039cdc35SXuan Hu  val S = RO(18).withReset(1.U) // Supervisor mode implemented
583039cdc35SXuan Hu  val T = RO(19).withReset(0.U) // Reserved
584039cdc35SXuan Hu  val U = RO(20).withReset(1.U) // User mode implemented
585039cdc35SXuan Hu  val V = RO(21).withReset(1.U) // Vector extension
586039cdc35SXuan Hu  val W = RO(22).withReset(0.U) // Reserved
587039cdc35SXuan Hu  val X = RO(23).withReset(0.U) // Non-standard extensions present
588039cdc35SXuan Hu  val Y = RO(24).withReset(0.U) // Reserved
589039cdc35SXuan Hu  val Z = RO(25).withReset(0.U) // Reserved
590039cdc35SXuan Hu  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
591039cdc35SXuan Hu
59225dc4a82SXuan Hu  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
593039cdc35SXuan Hu}
594039cdc35SXuan Hu
595039cdc35SXuan Huclass MedelegBundle extends ExceptionBundle {
596ab449222SsinceforYy  this.getALL.foreach(_.setRW().withReset(0.U))
597ab449222SsinceforYy  this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall
598ca0aa835SXuan Hu  this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable
599039cdc35SXuan Hu}
600039cdc35SXuan Hu
601039cdc35SXuan Huclass MidelegBundle extends InterruptBundle {
602ab449222SsinceforYy  this.getALL.foreach(_.setRW().withReset(0.U))
603039cdc35SXuan Hu  // Don't delegate Machine level interrupts
604039cdc35SXuan Hu  this.getM.foreach(_.setRO().withReset(0.U))
605039cdc35SXuan Hu  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
606039cdc35SXuan Hu  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
607039cdc35SXuan Hu  // interrupts) are each read-only one.
608039cdc35SXuan Hu  this.getVS.foreach(_.setRO().withReset(1.U))
609039cdc35SXuan Hu  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
610039cdc35SXuan Hu  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
611039cdc35SXuan Hu  this.SGEI.setRO().withReset(1.U)
6127cc30128SsinceforYy  this.getLocal.foreach(_.setRO().withReset(0.U))
6137cc30128SsinceforYy  this.LCOFI.setRW().withReset(0.U)
614039cdc35SXuan Hu}
615039cdc35SXuan Hu
616039cdc35SXuan Huclass MieBundle extends InterruptEnableBundle {
6171d192ad8SXuan Hu  this.getNonLocal.foreach(_.setRW().withReset(0.U))
618d8ae249aSsinceforYy  this.LCOFIE.setRW().withReset(0.U)
619039cdc35SXuan Hu}
620039cdc35SXuan Hu
621039cdc35SXuan Huclass MipBundle extends InterruptPendingBundle {
6221d192ad8SXuan Hu  // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers
6231d192ad8SXuan Hu  // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip
6241d192ad8SXuan Hu  //
6251d192ad8SXuan Hu  // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers,
6261d192ad8SXuan Hu  // while these bits in hip are aliases for the same bits in mip.
6271d192ad8SXuan Hu  //
6281d192ad8SXuan Hu  // Ref: riscv interrupt spec - 2.1 Machine-level CSRs
6291d192ad8SXuan Hu  // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes.
6301d192ad8SXuan Hu  this.getHS.foreach(_.setRW().withReset(0.U))
6311d192ad8SXuan Hu  this.getVS.foreach(_.setRW().withReset(0.U))
6321d192ad8SXuan Hu  this.LCOFIP.setRW().withReset(0.U)
633039cdc35SXuan Hu}
634039cdc35SXuan Hu
6351d192ad8SXuan Huclass MvienBundle extends InterruptEnableBundle {
636039cdc35SXuan Hu  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
637039cdc35SXuan Hu  // It is strongly recommended that bit 9 of mvien be writable.
638039cdc35SXuan Hu  // It is strongly recommended that bit 1 of mvien also be writable.
6391d192ad8SXuan Hu  // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63.
6401d192ad8SXuan Hu  this.SSIE.setRW().withReset(0.U)
6411d192ad8SXuan Hu  this.SEIE.setRW().withReset(0.U)
6421d192ad8SXuan Hu  this.getLocal.foreach(_.setRW().withReset(0.U))
643039cdc35SXuan Hu}
644039cdc35SXuan Hu
6451d192ad8SXuan Huclass MvipBundle extends InterruptPendingBundle {
6461d192ad8SXuan Hu  this.getHS.foreach(_.setRW().withReset(0.U))
6471d192ad8SXuan Hu  this.getLocal.foreach(_.setRW().withReset(0.U))
648039cdc35SXuan Hu}
649039cdc35SXuan Hu
650039cdc35SXuan Huclass Epc extends CSRBundle {
6513e8a0170SXuan Hu  val epc = RW(63, 1).withReset(0.U)
652039cdc35SXuan Hu}
653039cdc35SXuan Hu
654039cdc35SXuan Huclass McountinhibitBundle extends CSRBundle {
6551ee8f942SXuan Hu  val CY = RW(0).withReset(0.U)
6561ee8f942SXuan Hu  val IR = RW(2).withReset(0.U)
6571ee8f942SXuan Hu  val HPM3 = RW(31, 3).withReset(0.U)
658039cdc35SXuan Hu}
659039cdc35SXuan Hu
660499d09b3SsinceforYyclass Mtval2Bundle extends FieldInitBundle
661499d09b3SsinceforYy
662499d09b3SsinceforYyclass MhpmcounterBundle extends FieldInitBundle
663499d09b3SsinceforYy
6640b4c00ffSXuan Huclass MEnvCfg extends EnvCfg {
6650b4c00ffSXuan Hu  if (CSRConfig.EXT_SSTC) {
6660b4c00ffSXuan Hu    this.STCE.setRW().withReset(1.U)
6670b4c00ffSXuan Hu  }
66839db506bSXuan Hu  this.PBMTE.setRW().withReset(0.U)
6696808b803SZehao Liu  if (CSRConfig.EXT_DBLTRP) {
6706808b803SZehao Liu    // software write envcfg to open ssdbltrp if need
6716808b803SZehao Liu    // set 0 to pass ci
6726808b803SZehao Liu    this.DTE.setRW().withReset(0.U)
6736808b803SZehao Liu  }
6740b4c00ffSXuan Hu}
6750b4c00ffSXuan Hu
676436f48ccSXuan Huobject MarchidField extends CSREnum with ROApply {
677039cdc35SXuan Hu  val XSArchid = Value(25.U)
678039cdc35SXuan Hu}
679039cdc35SXuan Hu
680039cdc35SXuan Huclass MieToHie extends Bundle {
681039cdc35SXuan Hu  val VSSIE = ValidIO(RW(0))
682039cdc35SXuan Hu  val VSTIE = ValidIO(RW(0))
683039cdc35SXuan Hu  val VSEIE = ValidIO(RW(0))
684039cdc35SXuan Hu  val SGEIE = ValidIO(RW(0))
685039cdc35SXuan Hu}
686039cdc35SXuan Hu
6871d192ad8SXuan Huclass MvipToMip extends IpValidBundle {
6881d192ad8SXuan Hu  this.getHS.foreach(_.bits.setRW())
689039cdc35SXuan Hu}
690039cdc35SXuan Hu
6911d192ad8SXuan Huclass HipToMip extends IpValidBundle {
6921d192ad8SXuan Hu  // Only hip.VSSIP is writable
6931d192ad8SXuan Hu  this.VSSIP.bits.setRW()
6941d192ad8SXuan Hu}
6951d192ad8SXuan Hu
6961d192ad8SXuan Huclass VSipToMip extends IpValidBundle {
6971d192ad8SXuan Hu  this.LCOFIP.bits.setRW()
6981d192ad8SXuan Hu}
6991d192ad8SXuan Hu
7001d192ad8SXuan Huclass MipToHvip extends IpValidBundle {
7011d192ad8SXuan Hu  this.VSSIP.bits.setRW()
7021d192ad8SXuan Hu}
7031d192ad8SXuan Hu
7041d192ad8SXuan Huclass MipToMvip extends IpValidBundle {
7051d192ad8SXuan Hu  this.SEIP.bits.setRW()
7061d192ad8SXuan Hu}
7071d192ad8SXuan Hu
708b8e923e6Schengguanghuiclass MhpmeventBundle extends CSRBundle {
709b8e923e6Schengguanghui  val OF      = RW(63).withReset(0.U)
710b8e923e6Schengguanghui  val MINH    = RW(62).withReset(0.U)
711b8e923e6Schengguanghui  val SINH    = RW(61).withReset(0.U)
712b8e923e6Schengguanghui  val UINH    = RW(60).withReset(0.U)
713b8e923e6Schengguanghui  val VSINH   = RW(59).withReset(0.U)
714b8e923e6Schengguanghui  val VUINH   = RW(58).withReset(0.U)
715b8e923e6Schengguanghui  val OPTYPE2 = OPTYPE(54, 50, wNoFilter).withReset(OPTYPE.OR)
716b8e923e6Schengguanghui  val OPTYPE1 = OPTYPE(49, 45, wNoFilter).withReset(OPTYPE.OR)
717b8e923e6Schengguanghui  val OPTYPE0 = OPTYPE(44, 40, wNoFilter).withReset(OPTYPE.OR)
718b8e923e6Schengguanghui  val EVENT3  = RW(39, 30).withReset(0.U)
719b8e923e6Schengguanghui  val EVENT2  = RW(29, 20).withReset(0.U)
720b8e923e6Schengguanghui  val EVENT1  = RW(19, 10).withReset(0.U)
721b8e923e6Schengguanghui  val EVENT0  = RW(9, 0).withReset(0.U)
722b8e923e6Schengguanghui}
723b8e923e6Schengguanghui
724b8e923e6Schengguanghuiobject OPTYPE extends CSREnum with WARLApply {
725b8e923e6Schengguanghui  val OR = Value(0.U)
726b8e923e6Schengguanghui  val AND = Value(1.U)
727b8e923e6Schengguanghui  val XOR = Value(2.U)
728b8e923e6Schengguanghui  val ADD = Value(4.U)
729b8e923e6Schengguanghui
730b8e923e6Schengguanghui  override def isLegal(enumeration: CSREnumType): Bool = enumeration.isOneOf(OR, AND, XOR, ADD)
731b8e923e6Schengguanghui}
732b8e923e6Schengguanghui
733b8e923e6Schengguanghuitrait HasOfFromPerfCntBundle { self: CSRModule[_] =>
734b8e923e6Schengguanghui  val ofFromPerfCnt = IO(Input(Bool()))
735b8e923e6Schengguanghui}
736b8e923e6Schengguanghui
7371d192ad8SXuan Hutrait HasMipToAlias { self: CSRModule[_] =>
7381d192ad8SXuan Hu  val mipAlias = Output(new MipBundle)
739039cdc35SXuan Hu}
740039cdc35SXuan Hu
741039cdc35SXuan Hutrait HasMachineDelegBundle { self: CSRModule[_] =>
742039cdc35SXuan Hu  val mideleg = IO(Input(new MidelegBundle))
743039cdc35SXuan Hu  val medeleg = IO(Input(new MedelegBundle))
744039cdc35SXuan Hu}
745039cdc35SXuan Hu
746039cdc35SXuan Hutrait HasExternalInterruptBundle {
747039cdc35SXuan Hu  val platformIRP = IO(new Bundle {
748039cdc35SXuan Hu    val MEIP  = Input(Bool())
749039cdc35SXuan Hu    val MTIP  = Input(Bool())
750039cdc35SXuan Hu    val MSIP  = Input(Bool())
751039cdc35SXuan Hu    val SEIP  = Input(Bool())
7520b4c00ffSXuan Hu    val STIP  = Input(Bool())
753039cdc35SXuan Hu    val VSEIP = Input(Bool())
754039cdc35SXuan Hu    val VSTIP = Input(Bool())
7550e664306SXuan Hu    // debug interrupt from debug module
75647bb101bSXuan Hu    val debugIP = Input(Bool())
757039cdc35SXuan Hu  })
758039cdc35SXuan Hu}
759c2a2229dSlewislzhtrait HasNonMaskableIRPBundle {
760c2a2229dSlewislzh  val nonMaskableIRP = IO(new Bundle {
7618bc90631SZehao Liu    val NMI_43 = Input(Bool())
7628bc90631SZehao Liu    val NMI_31 = Input(Bool())
763c2a2229dSlewislzh  })
764c2a2229dSlewislzh}
765039cdc35SXuan Hu
766039cdc35SXuan Hutrait HasMachineCounterControlBundle { self: CSRModule[_] =>
767039cdc35SXuan Hu  val mcountinhibit = IO(Input(new McountinhibitBundle))
768039cdc35SXuan Hu}
769039cdc35SXuan Hu
77001cdded8SXuan Hutrait HasRobCommitBundle { self: CSRModule[_] =>
77101cdded8SXuan Hu  val robCommit = IO(Input(new RobCommitCSR))
772a0231889SXuan Hu  val writeFCSR = IO(Input(Bool()))
773a0231889SXuan Hu  val writeVCSR = IO(Input(Bool()))
77482f438edSXuan Hu  val isVirtMode = IO(Input(Bool()))
775039cdc35SXuan Hu}
7760b4c00ffSXuan Hu
7770b4c00ffSXuan Hutrait HasMachineEnvBundle { self: CSRModule[_] =>
7780b4c00ffSXuan Hu  val menvcfg = IO(Input(new MEnvCfg))
7790b4c00ffSXuan Hu}
7800b4c00ffSXuan Hu
781b51a1abdSchengguanghuitrait HasPerfCounterBundle { self: CSRModule[_] =>
782202093f4Schengguanghui  val countingEn    = IO(Input(Bool()))
783202093f4Schengguanghui  val perf          = IO(Input(new PerfEvent))
784202093f4Schengguanghui  val toMhpmeventOF = IO(Output(Bool()))
785b51a1abdSchengguanghui}
786b51a1abdSchengguanghui
787b51a1abdSchengguanghuitrait HasPerfEventBundle { self: CSRModule[_] =>
788b51a1abdSchengguanghui  val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W))))
789b51a1abdSchengguanghui}
790202093f4Schengguanghui
791202093f4Schengguanghuitrait HasLocalInterruptReqBundle { self: CSRModule[_] =>
792202093f4Schengguanghui  val lcofiReq = IO(Input(Bool()))
793202093f4Schengguanghui}
794b7a63495SNewPaulWalker
795b7a63495SNewPaulWalkertrait HasMachineFlushL2Bundle { self: CSRModule[_] =>
796b7a63495SNewPaulWalker  val l2FlushDone = IO(Input(Bool()))
797b7a63495SNewPaulWalker}
798