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}