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