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