xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPMP.scala (revision 9ff1c68f4eb56b1d6cf555702bcb228a2282b43d)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRWARLField => WARL}
7import xiangshan.backend.fu.NewCSR.CSRFunc._
8import xiangshan.PMParameKey
9import freechips.rocketchip.tile.XLen
10import CSRConfig._
11
12import scala.collection.immutable.SeqMap
13
14trait CSRPMP { self: NewCSR =>
15  val pmpcfg: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP/8+1, 2).map(num =>
16    Module(new CSRModule(s"Pmpcfg$num") with HasPMPCfgRSink {
17      // read condition
18      rdata := cfgRData(64*(num/2+1)-1, 64*num/2)
19    })
20      .setAddr(0x3A0 + num)
21  )
22
23  // every pmpcfg has 8 cfgs
24  val cfgs: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP).map(num =>
25    Module(new CSRModule(s"Pmp$num"+"cfg", new PMPCfgBundle) {
26      when (w.wen && (!(!w.wdata(0).asBool && w.wdata(1).asBool))) {  // when R=0 W=1, reserved
27        reg.W := w.wdata(1).asBool
28      }.otherwise {
29        reg.W := reg.W
30      }
31      reg.A := Mux(wen, Mux(w.wdata(4, 3) === 2.U, 3.U, w.wdata(4, 3).asUInt), reg.A.asUInt) // no support Na4
32    })
33  )
34
35  val pmpaddr: Seq[CSRModule[_]] = Range(0, p(PMParameKey).NumPMP).map(num =>
36    Module(new CSRModule(s"Pmpaddr$num", new PMPAddrBundle) with HasPMPAddrSink {
37      // read condition
38      rdata := addrRData(num)
39    })
40      .setAddr(0x3B0 + num)
41  )
42
43  val pmpCSRMods: Seq[CSRModule[_]] = pmpcfg ++ pmpaddr
44
45  val pmpCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from(
46    pmpCSRMods.map(csr => csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt)).iterator
47  )
48
49  val pmpCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
50    pmpCSRMods.map(csr => csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt).iterator
51  )
52
53  private val pmpCfgRead = Cat(cfgs.map(_.rdata.asInstanceOf[CSRBundle].asUInt(7,0)).reverse)
54
55  pmpCSRMods.foreach { mod =>
56    mod match {
57      case m: HasPMPCfgRSink =>
58        m.cfgRData := pmpCfgRead
59      case _ =>
60    }
61  }
62}
63
64class PMPCfgBundle extends CSRBundle {
65  override val len = 8
66  val R      = WARL(           0, wNoFilter).withReset(false.B)
67  val W      = WARL(           1, wNoFilter).withReset(false.B)
68  val X      = WARL(           2, wNoFilter).withReset(false.B)
69  val A      = PMPCfgAField(4, 3, wNoFilter).withReset(PMPCfgAField.OFF)
70  val ATOMIC = WARL(           5, wNoFilter).withReset(false.B)           // res(0), unuse in pmp
71  val C      = WARL(           6, wNoFilter).withReset(false.B)           // res(1), unuse in pmp
72  val L      = PMPCfgLField(   7, wNoFilter).withReset(PMPCfgLField.UNLOCKED)
73}
74
75object PMPCfgLField extends CSREnum with WARLApply {
76  val UNLOCKED = Value(0.U)
77
78  def locked(cfg: PMPCfgBundle): Bool = cfg.L.asBool
79  def addrLocked(cfg: PMPCfgBundle): Bool = locked(cfg)
80  def addrLocked(cfg: PMPCfgBundle, next: PMPCfgBundle): Bool = locked(cfg) || (locked(next) && PMPCfgAField.tor(next))
81}
82
83object PMPCfgAField extends CSREnum with WARLApply {
84  val OFF   = Value(0.U)  // Null region(disabled)
85  val TOR   = Value(1.U)  // Top of range
86  val NA4   = Value(2.U)  // Naturally aligned four-byte region
87  val NAPOT = Value(3.U)  // Naturally aligned power-of-two region, ≥ 8 bytes
88
89  def off(cfg: PMPCfgBundle): Bool = cfg.A.asUInt === 0.U
90  def tor(cfg: PMPCfgBundle): Bool = cfg.A.asUInt === 1.U
91  def na4  (cfg: PMPCfgBundle)(implicit p: Parameters): Bool = { if (CoarserGrain) false.B         else cfg.A.asUInt === 2.U }
92  def napot(cfg: PMPCfgBundle)(implicit p: Parameters): Bool = { if (CoarserGrain) cfg.A.asUInt(1) else cfg.A.asUInt === 3.U }
93  def isOffOrTor  (cfg: PMPCfgBundle): Bool = !cfg.A.asUInt(1)
94  def isNa4OrNapot(cfg: PMPCfgBundle): Bool =  cfg.A.asUInt(1)
95
96  val PMPOffBits = 2 // minimal 4bytes
97  def CoarserGrain(implicit p: Parameters): Boolean = p(PMParameKey).PlatformGrain > PMPOffBits
98}
99
100class PMPAddrBundle extends CSRBundle {
101  val ADDRESS  = WARL(PMPAddrBits-1,  0, wNoFilter).withReset(false.B)
102}
103
104trait HasPMPCfgRSink { self: CSRModule[_] =>
105  val cfgRData = IO(Input(UInt((p(PMParameKey).NumPMP/8 * p(XLen)).W)))
106}
107
108trait HasPMPAddrSink { self: CSRModule[_] =>
109  val addrRData = IO(Input(Vec(p(PMParameKey).NumPMP, UInt(64.W))))
110}