xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPMP.scala (revision 011d262c490b7fd9c718724a21daceb78ad6689a)
19ff1c68fSsinceforYypackage xiangshan.backend.fu.NewCSR
29ff1c68fSsinceforYy
39ff1c68fSsinceforYyimport chisel3._
49ff1c68fSsinceforYyimport chisel3.util._
52c054816SsinceforYyimport freechips.rocketchip.rocket.CSRs
69ff1c68fSsinceforYyimport org.chipsalliance.cde.config.Parameters
79718f930SZhaoyang Youimport xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRWARLField => WARL}
89ff1c68fSsinceforYyimport xiangshan.backend.fu.NewCSR.CSRFunc._
99ff1c68fSsinceforYyimport xiangshan.PMParameKey
109ff1c68fSsinceforYyimport freechips.rocketchip.tile.XLen
119ff1c68fSsinceforYyimport CSRConfig._
129ff1c68fSsinceforYy
139ff1c68fSsinceforYyimport scala.collection.immutable.SeqMap
149ff1c68fSsinceforYy
159ff1c68fSsinceforYytrait CSRPMP { self: NewCSR =>
169ff1c68fSsinceforYy  val pmpcfg: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP/8+1, 2).map(num =>
179ff1c68fSsinceforYy    Module(new CSRModule(s"Pmpcfg$num") with HasPMPCfgRSink {
189ff1c68fSsinceforYy      // read condition
19a37e0a1fSsinceforYy      regOut := cfgRData(64*(num/2+1)-1, 64*num/2)
209ff1c68fSsinceforYy    })
212c054816SsinceforYy      .setAddr(CSRs.pmpcfg0 + num)
229ff1c68fSsinceforYy  )
239ff1c68fSsinceforYy
249ff1c68fSsinceforYy  // every pmpcfg has 8 cfgs
25*011d262cSZhaoyang You  val pmpcfgs: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP).map(num =>
269ff1c68fSsinceforYy    Module(new CSRModule(s"Pmp$num"+"cfg", new PMPCfgBundle) {
279ff1c68fSsinceforYy      when (w.wen && (!(!w.wdata(0).asBool && w.wdata(1).asBool))) {  // when R=0 W=1, reserved
289ff1c68fSsinceforYy        reg.W := w.wdata(1).asBool
299ff1c68fSsinceforYy      }.otherwise {
309ff1c68fSsinceforYy        reg.W := reg.W
319ff1c68fSsinceforYy      }
329ff1c68fSsinceforYy      reg.A := Mux(wen, Mux(w.wdata(4, 3) === 2.U, 3.U, w.wdata(4, 3).asUInt), reg.A.asUInt) // no support Na4
339ff1c68fSsinceforYy    })
349ff1c68fSsinceforYy  )
359ff1c68fSsinceforYy
369ff1c68fSsinceforYy  val pmpaddr: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP).map(num =>
379ff1c68fSsinceforYy    Module(new CSRModule(s"Pmpaddr$num", new PMPAddrBundle) with HasPMPAddrSink {
389ff1c68fSsinceforYy      // read condition
399ff1c68fSsinceforYy      rdata := addrRData(num)
409ff1c68fSsinceforYy    })
412c054816SsinceforYy      .setAddr(CSRs.pmpaddr0 + num)
429ff1c68fSsinceforYy  )
439ff1c68fSsinceforYy
449ff1c68fSsinceforYy  val pmpCSRMods: Seq[CSRModule[_]] = pmpcfg ++ pmpaddr
459ff1c68fSsinceforYy
4694895e77SXuan Hu  val pmpCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
478aa89407SXuan Hu    pmpCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata)).iterator
489ff1c68fSsinceforYy  )
499ff1c68fSsinceforYy
509ff1c68fSsinceforYy  val pmpCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
519ff1c68fSsinceforYy    pmpCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator
529ff1c68fSsinceforYy  )
539ff1c68fSsinceforYy
54*011d262cSZhaoyang You  private val pmpCfgRead = Cat(pmpcfgs.map(_.rdata(7, 0)).reverse)
559ff1c68fSsinceforYy
569ff1c68fSsinceforYy  pmpCSRMods.foreach { mod =>
579ff1c68fSsinceforYy    mod match {
589ff1c68fSsinceforYy      case m: HasPMPCfgRSink =>
599ff1c68fSsinceforYy        m.cfgRData := pmpCfgRead
609ff1c68fSsinceforYy      case _ =>
619ff1c68fSsinceforYy    }
629ff1c68fSsinceforYy  }
639ff1c68fSsinceforYy}
649ff1c68fSsinceforYy
659ff1c68fSsinceforYyclass PMPCfgBundle extends CSRBundle {
669ff1c68fSsinceforYy  override val len = 8
679ff1c68fSsinceforYy  val R      = WARL(           0, wNoFilter).withReset(false.B)
689ff1c68fSsinceforYy  val W      = WARL(           1, wNoFilter).withReset(false.B)
699ff1c68fSsinceforYy  val X      = WARL(           2, wNoFilter).withReset(false.B)
709ff1c68fSsinceforYy  val A      = PMPCfgAField(4, 3, wNoFilter).withReset(PMPCfgAField.OFF)
719718f930SZhaoyang You  val ATOMIC = RO(5).withReset(false.B)           // res(0), unuse in pmp
729718f930SZhaoyang You  val C      = RO(6).withReset(false.B)           // res(1), unuse in pmp
739ff1c68fSsinceforYy  val L      = PMPCfgLField(   7, wNoFilter).withReset(PMPCfgLField.UNLOCKED)
749ff1c68fSsinceforYy}
759ff1c68fSsinceforYy
769ff1c68fSsinceforYyobject PMPCfgLField extends CSREnum with WARLApply {
779ff1c68fSsinceforYy  val UNLOCKED = Value(0.U)
789ff1c68fSsinceforYy
799ff1c68fSsinceforYy  def locked(cfg: PMPCfgBundle): Bool = cfg.L.asBool
809ff1c68fSsinceforYy  def addrLocked(cfg: PMPCfgBundle): Bool = locked(cfg)
819ff1c68fSsinceforYy  def addrLocked(cfg: PMPCfgBundle, next: PMPCfgBundle): Bool = locked(cfg) || (locked(next) && PMPCfgAField.tor(next))
829ff1c68fSsinceforYy}
839ff1c68fSsinceforYy
849ff1c68fSsinceforYyobject PMPCfgAField extends CSREnum with WARLApply {
859ff1c68fSsinceforYy  val OFF   = Value(0.U)  // Null region(disabled)
869ff1c68fSsinceforYy  val TOR   = Value(1.U)  // Top of range
879ff1c68fSsinceforYy  val NA4   = Value(2.U)  // Naturally aligned four-byte region
889ff1c68fSsinceforYy  val NAPOT = Value(3.U)  // Naturally aligned power-of-two region, ≥ 8 bytes
899ff1c68fSsinceforYy
909ff1c68fSsinceforYy  def off(cfg: PMPCfgBundle): Bool = cfg.A.asUInt === 0.U
919ff1c68fSsinceforYy  def tor(cfg: PMPCfgBundle): Bool = cfg.A.asUInt === 1.U
929ff1c68fSsinceforYy  def na4  (cfg: PMPCfgBundle)(implicit p: Parameters): Bool = { if (CoarserGrain) false.B         else cfg.A.asUInt === 2.U }
939ff1c68fSsinceforYy  def napot(cfg: PMPCfgBundle)(implicit p: Parameters): Bool = { if (CoarserGrain) cfg.A.asUInt(1) else cfg.A.asUInt === 3.U }
949ff1c68fSsinceforYy  def isOffOrTor  (cfg: PMPCfgBundle): Bool = !cfg.A.asUInt(1)
959ff1c68fSsinceforYy  def isNa4OrNapot(cfg: PMPCfgBundle): Bool =  cfg.A.asUInt(1)
969ff1c68fSsinceforYy
979ff1c68fSsinceforYy  val PMPOffBits = 2 // minimal 4bytes
989ff1c68fSsinceforYy  def CoarserGrain(implicit p: Parameters): Boolean = p(PMParameKey).PlatformGrain > PMPOffBits
999ff1c68fSsinceforYy}
1009ff1c68fSsinceforYy
1019ff1c68fSsinceforYyclass PMPAddrBundle extends CSRBundle {
1029ff1c68fSsinceforYy  val ADDRESS  = WARL(PMPAddrBits-1,  0, wNoFilter).withReset(false.B)
1039ff1c68fSsinceforYy}
1049ff1c68fSsinceforYy
1059ff1c68fSsinceforYytrait HasPMPCfgRSink { self: CSRModule[_] =>
1069ff1c68fSsinceforYy  val cfgRData = IO(Input(UInt((p(PMParameKey).NumPMP/8 * p(XLen)).W)))
1079ff1c68fSsinceforYy}
1089ff1c68fSsinceforYy
1099ff1c68fSsinceforYytrait HasPMPAddrSink { self: CSRModule[_] =>
1109ff1c68fSsinceforYy  val addrRData = IO(Input(Vec(p(PMParameKey).NumPMP, UInt(64.W))))
1119ff1c68fSsinceforYy}