xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/PMAEntryModule.scala (revision 011d262c490b7fd9c718724a21daceb78ad6689a)
1*011d262cSZhaoyang Youpackage xiangshan.backend.fu.NewCSR
2*011d262cSZhaoyang You
3*011d262cSZhaoyang Youimport chisel3._
4*011d262cSZhaoyang Youimport chisel3.util._
5*011d262cSZhaoyang Youimport freechips.rocketchip.rocket.CSRs
6*011d262cSZhaoyang Youimport org.chipsalliance.cde.config.Parameters
7*011d262cSZhaoyang Youimport xiangshan.backend.fu.PMAConfigEntry
8*011d262cSZhaoyang Youimport xiangshan.backend.fu.util.CSRConst
9*011d262cSZhaoyang Youimport xiangshan.{HasPMParameters, PMParameKey}
10*011d262cSZhaoyang Youimport CSRConfig._
11*011d262cSZhaoyang You
12*011d262cSZhaoyang Youtrait PMAConst extends PMPConst
13*011d262cSZhaoyang You
14*011d262cSZhaoyang Youabstract class PMABundle(implicit val p: Parameters) extends Bundle with PMAConst
15*011d262cSZhaoyang Youabstract class PMAModule(implicit val p: Parameters) extends Module with PMAConst
16*011d262cSZhaoyang You
17*011d262cSZhaoyang Youclass PMAEntryHandleModule(implicit p: Parameters) extends PMAModule with PMAInit with PMAReadWrite {
18*011d262cSZhaoyang You  val io = IO(new PMAEntryHandleIOBundle)
19*011d262cSZhaoyang You
20*011d262cSZhaoyang You  val pmaCfg  = io.in.pmaCfg
21*011d262cSZhaoyang You
22*011d262cSZhaoyang You  val ren   = io.in.ren
23*011d262cSZhaoyang You  val wen   = io.in.wen
24*011d262cSZhaoyang You  val addr  = io.in.addr
25*011d262cSZhaoyang You  val wdata = io.in.wdata
26*011d262cSZhaoyang You
27*011d262cSZhaoyang You  require(NumPMA >= 16, "The number of PMA should be greater than or equal to 16.")
28*011d262cSZhaoyang You
29*011d262cSZhaoyang You  val pmaAddrInit = VecInit(Seq.fill(p(PMParameKey).NumPMA)(0.U((PMPAddrWidth-PMPOffBits).W)))
30*011d262cSZhaoyang You  val pmaMaskInit = VecInit(Seq.fill(p(PMParameKey).NumPMA)(0.U(PMPAddrWidth.W)))
31*011d262cSZhaoyang You
32*011d262cSZhaoyang You  pmaAddrInit.zip(pmaMaskInit).zip(pmaInit).foreach { case ((addr, mask), init) =>
33*011d262cSZhaoyang You    addr := genAddr(init).U((PMPAddrWidth-PMPOffBits).W)
34*011d262cSZhaoyang You    mask := genMask(init.a, genAddr(init))
35*011d262cSZhaoyang You  }
36*011d262cSZhaoyang You
37*011d262cSZhaoyang You  val pmaAddr = RegInit(pmaAddrInit)
38*011d262cSZhaoyang You  val pmaMask = RegInit(pmaMaskInit)
39*011d262cSZhaoyang You
40*011d262cSZhaoyang You  val pmaEntry = Wire(Vec(p(PMParameKey).NumPMA, new PMAEntry))
41*011d262cSZhaoyang You
42*011d262cSZhaoyang You  for (i <- pmaEntry.indices) {
43*011d262cSZhaoyang You    pmaEntry(i).gen(pmaCfg(i), pmaAddr(i), pmaMask(i))
44*011d262cSZhaoyang You  }
45*011d262cSZhaoyang You
46*011d262cSZhaoyang You  // write pmaCfg
47*011d262cSZhaoyang You  val cfgVec = WireInit(VecInit(Seq.fill(8)(0.U.asTypeOf(new PMACfgBundle))))
48*011d262cSZhaoyang You  for (i <- 0 until (p(PMParameKey).NumPMA/8+1) by 2) {
49*011d262cSZhaoyang You    when (wen && (addr === (CSRConst.PmacfgBase + i).U)) {
50*011d262cSZhaoyang You      for (j <- cfgVec.indices) {
51*011d262cSZhaoyang You        val cfgOldTmp = pmaEntry(8*i/2+j).cfg
52*011d262cSZhaoyang You        val cfgNewTmp = Wire(new PMACfgBundle)
53*011d262cSZhaoyang You        cfgNewTmp := wdata(8*(j+1)-1, 8*j)
54*011d262cSZhaoyang You        cfgVec(j) := cfgOldTmp
55*011d262cSZhaoyang You        when (!cfgOldTmp.L.asBool) {
56*011d262cSZhaoyang You          cfgVec(j) := cfgNewTmp
57*011d262cSZhaoyang You          cfgVec(j).W := cfgNewTmp.W.asBool && cfgNewTmp.R.asBool
58*011d262cSZhaoyang You          if (CoarserGrain) {
59*011d262cSZhaoyang You            cfgVec(j).A := Cat(cfgNewTmp.A.asUInt(1), cfgNewTmp.A.asUInt.orR)
60*011d262cSZhaoyang You          }
61*011d262cSZhaoyang You          when (PMPCfgAField.isNa4OrNapot(cfgVec(j))) {
62*011d262cSZhaoyang You            pmaMask(8*i/2+j) := pmaEntry(8*i/2+j).matchMask(cfgVec(j), pmaEntry(8*i/2+j).addr)
63*011d262cSZhaoyang You          }
64*011d262cSZhaoyang You        }
65*011d262cSZhaoyang You      }
66*011d262cSZhaoyang You    }
67*011d262cSZhaoyang You  }
68*011d262cSZhaoyang You
69*011d262cSZhaoyang You  io.out.pmaCfgWdata := Cat(cfgVec.map(_.asUInt).reverse)
70*011d262cSZhaoyang You
71*011d262cSZhaoyang You
72*011d262cSZhaoyang You  val pmaAddrR = Wire(Vec(p(PMParameKey).NumPMA, UInt(64.W)))
73*011d262cSZhaoyang You
74*011d262cSZhaoyang You  for (i <- 0 until p(PMParameKey).NumPMA) {
75*011d262cSZhaoyang You    pmaAddrR(i) := pmaEntry(i).addr
76*011d262cSZhaoyang You    // write pmaAddr
77*011d262cSZhaoyang You    when (wen && (addr === (CSRConst.PmaaddrBase + i).U)) {
78*011d262cSZhaoyang You      if (i != (p(PMParameKey).NumPMA - 1)) {
79*011d262cSZhaoyang You        val addrNextLocked: Bool = PMPCfgLField.addrLocked(pmaEntry(i).cfg, pmaEntry(i + 1).cfg)
80*011d262cSZhaoyang You        pmaMask(i) := Mux(!addrNextLocked, pmaEntry(i).matchMask(wdata), pmaEntry(i).mask)
81*011d262cSZhaoyang You        pmaAddr(i) := Mux(!addrNextLocked, wdata, pmaEntry(i).addr)
82*011d262cSZhaoyang You      } else {
83*011d262cSZhaoyang You        val addrLocked: Bool = PMPCfgLField.addrLocked(pmaEntry(i).cfg)
84*011d262cSZhaoyang You        pmaMask(i) := Mux(!addrLocked, pmaEntry(i).matchMask(wdata), pmaEntry(i).mask)
85*011d262cSZhaoyang You        pmaAddr(i) := Mux(!addrLocked, wdata, pmaEntry(i).addr)
86*011d262cSZhaoyang You      }
87*011d262cSZhaoyang You    }
88*011d262cSZhaoyang You    // read pmaAddr
89*011d262cSZhaoyang You    when (ren && (addr === (CSRConst.PmaaddrBase + i).U)) {
90*011d262cSZhaoyang You      pmaAddrR(i) := pmaEntry(i).readAddr(pmaEntry(i).cfg, pmaEntry(i).addr)
91*011d262cSZhaoyang You    }
92*011d262cSZhaoyang You  }
93*011d262cSZhaoyang You
94*011d262cSZhaoyang You  io.out.pmaAddrRData := pmaAddrR
95*011d262cSZhaoyang You
96*011d262cSZhaoyang You}
97*011d262cSZhaoyang You
98*011d262cSZhaoyang Youclass PMAEntryHandleIOBundle(implicit p: Parameters) extends PMABundle {
99*011d262cSZhaoyang You  val in = Input(new Bundle {
100*011d262cSZhaoyang You    val wen = Bool()
101*011d262cSZhaoyang You    val ren = Bool()
102*011d262cSZhaoyang You    val addr = UInt(12.W)
103*011d262cSZhaoyang You    val wdata = UInt(64.W)
104*011d262cSZhaoyang You    val pmaCfg = Vec(NumPMA, new PMACfgBundle)
105*011d262cSZhaoyang You  })
106*011d262cSZhaoyang You
107*011d262cSZhaoyang You  val out = Output(new Bundle {
108*011d262cSZhaoyang You    val pmaCfgWdata = UInt(PMXLEN.W)
109*011d262cSZhaoyang You    val pmaAddrRData = Vec(NumPMA, UInt(64.W))
110*011d262cSZhaoyang You  })
111*011d262cSZhaoyang You}
112*011d262cSZhaoyang You
113*011d262cSZhaoyang Youtrait PMAReadWrite extends PMAConst with PMPReadWrite {
114*011d262cSZhaoyang You  def shift_addr(addr: BigInt): BigInt = {
115*011d262cSZhaoyang You    addr >> 2
116*011d262cSZhaoyang You  }
117*011d262cSZhaoyang You
118*011d262cSZhaoyang You  def get_napot(base: BigInt, range: BigInt): BigInt = {
119*011d262cSZhaoyang You    val PlatformGrainBytes = 1 << PlatformGrain
120*011d262cSZhaoyang You    if ((base % PlatformGrainBytes) != 0) {
121*011d262cSZhaoyang You      println("base: %x", base)
122*011d262cSZhaoyang You    }
123*011d262cSZhaoyang You    if ((range % PlatformGrainBytes) != 0) {
124*011d262cSZhaoyang You      println("range: %x", range)
125*011d262cSZhaoyang You    }
126*011d262cSZhaoyang You    require((base % PlatformGrainBytes) == 0)
127*011d262cSZhaoyang You    require((range % PlatformGrainBytes) == 0)
128*011d262cSZhaoyang You
129*011d262cSZhaoyang You    (base + (range/2 - 1)) >> PMPOffBits
130*011d262cSZhaoyang You  }
131*011d262cSZhaoyang You
132*011d262cSZhaoyang You  def matchMask(cfgA0: Bool, paddr: UInt): UInt = {
133*011d262cSZhaoyang You    val matchMaskCAddr = Cat(paddr, cfgA0) | (((1 << PlatformGrain) - 1) >> PMPOffBits).U((paddr.getWidth + 1).W)
134*011d262cSZhaoyang You    Cat(matchMaskCAddr & (~(matchMaskCAddr + 1.U)).asUInt, ((1 << PMPOffBits) - 1).U(PMPOffBits.W))
135*011d262cSZhaoyang You  }
136*011d262cSZhaoyang You
137*011d262cSZhaoyang You  def readAddr(cfg: PMACfgBundle, addr: UInt): UInt = {
138*011d262cSZhaoyang You    val G = PlatformGrain - PMPOffBits
139*011d262cSZhaoyang You    require(G >= 0)
140*011d262cSZhaoyang You    if (G == 0) {
141*011d262cSZhaoyang You      addr
142*011d262cSZhaoyang You    } else if (G >= 2) {
143*011d262cSZhaoyang You      Mux(PMPCfgAField.isNa4OrNapot(cfg), setLowBits(addr, G-1), clearLowBits(addr, G))
144*011d262cSZhaoyang You    } else {
145*011d262cSZhaoyang You      Mux(PMPCfgAField.isOffOrTor(cfg), clearLowBits(addr, G), addr)
146*011d262cSZhaoyang You    }
147*011d262cSZhaoyang You  }
148*011d262cSZhaoyang You
149*011d262cSZhaoyang You  def genAddr(init: PMAConfigEntry): BigInt = {
150*011d262cSZhaoyang You    if (init.a < 2) {
151*011d262cSZhaoyang You      shift_addr(init.base_addr)
152*011d262cSZhaoyang You    } else {
153*011d262cSZhaoyang You      get_napot(init.base_addr, init.range)
154*011d262cSZhaoyang You    }
155*011d262cSZhaoyang You  }
156*011d262cSZhaoyang You
157*011d262cSZhaoyang You  def genMask(a: BigInt, initAddr: BigInt) = {
158*011d262cSZhaoyang You    val matchMaskAddr = (initAddr << 1) | (a & 0x1) | (((1 << PlatformGrain) - 1) >> PMPOffBits)
159*011d262cSZhaoyang You    val mask = ((matchMaskAddr & ~(matchMaskAddr + 1)) << PMPOffBits) | ((1 << PMPOffBits) - 1)
160*011d262cSZhaoyang You    mask.U(PMPAddrWidth.W)
161*011d262cSZhaoyang You  }
162*011d262cSZhaoyang You}
163*011d262cSZhaoyang You
164*011d262cSZhaoyang Youclass PMAEntry(implicit p: Parameters) extends PMABundle with PMAReadWrite {
165*011d262cSZhaoyang You  val cfg  = new PMACfgBundle
166*011d262cSZhaoyang You  val addr = UInt((PMPAddrWidth-PMPOffBits).W)
167*011d262cSZhaoyang You  val mask = UInt(PMPAddrBits.W)
168*011d262cSZhaoyang You
169*011d262cSZhaoyang You  def gen(cfg: PMACfgBundle, addr: UInt, mask: UInt) = {
170*011d262cSZhaoyang You    this.cfg := cfg
171*011d262cSZhaoyang You    this.addr := addr
172*011d262cSZhaoyang You    this.mask := mask
173*011d262cSZhaoyang You  }
174*011d262cSZhaoyang You
175*011d262cSZhaoyang You  def matchMask(paddr: UInt): UInt = {
176*011d262cSZhaoyang You    matchMask(cfg.A.asUInt(0), paddr)
177*011d262cSZhaoyang You  }
178*011d262cSZhaoyang You}
179