1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.cache.mmu 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import xiangshan._ 23import xiangshan.cache.{HasDCacheParameters, MemoryOpConstants} 24import utils._ 25import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 26import freechips.rocketchip.tilelink._ 27 28trait HasTlbConst extends HasXSParameter { 29 val Level = 3 30 31 val offLen = 12 32 val ppnLen = PAddrBits - offLen 33 val vpnnLen = 9 34 val vpnLen = VAddrBits - offLen 35 val flagLen = 8 36 val pteResLen = XLEN - ppnLen - 2 - flagLen 37 val asidLen = 16 38 39 def vaBundle = new Bundle { 40 val vpn = UInt(vpnLen.W) 41 val off = UInt(offLen.W) 42 } 43 def pteBundle = new Bundle { 44 val reserved = UInt(pteResLen.W) 45 val ppn = UInt(ppnLen.W) 46 val rsw = UInt(2.W) 47 val perm = new Bundle { 48 val d = Bool() 49 val a = Bool() 50 val g = Bool() 51 val u = Bool() 52 val x = Bool() 53 val w = Bool() 54 val r = Bool() 55 val v = Bool() 56 } 57 } 58 59 def replaceWrapper(v: UInt, lruIdx: UInt): UInt = { 60 val width = v.getWidth 61 val emptyIdx = ParallelPriorityMux((0 until width).map( i => (!v(i), i.U))) 62 val full = Cat(v).andR 63 Mux(full, lruIdx, emptyIdx) 64 } 65 66 def replaceWrapper(v: Seq[Bool], lruIdx: UInt): UInt = { 67 replaceWrapper(VecInit(v).asUInt, lruIdx) 68 } 69} 70 71trait HasPtwConst extends HasTlbConst with MemoryOpConstants{ 72 val PtwWidth = 2 73 val MemBandWidth = 256 // TODO: change to IO bandwidth param 74 val SramSinglePort = true // NOTE: ptwl2, ptwl3 sram single port or not 75 76 val bPtwWidth = log2Up(PtwWidth) 77 78 // ptwl1: fully-associated 79 val PtwL1TagLen = vpnnLen 80 val ptwl1Replacer = Some("plru") 81 82 /* +-------+----------+-------------+ 83 * | Tag | SetIdx | SectorIdx | 84 * +-------+----------+-------------+ 85 */ 86 // ptwl2: 8-way group-associated 87 val PtwL2WayNum = 8 88 val PtwL2WaySize = PtwL2EntrySize / PtwL2WayNum 89 val PtwL2SectorSize = MemBandWidth/XLEN 90 val PtwL2LineSize = PtwL2SectorSize * PtwL2WayNum 91 val PtwL2LineNum = PtwL2EntrySize / PtwL2LineSize 92 val PtwL2IdxLen = log2Up(PtwL2WaySize) 93 val PtwL2SectorIdxLen = log2Up(PtwL2SectorSize) 94 val PtwL2SetIdxLen = log2Up(PtwL2LineNum) 95 val PtwL2TagLen = vpnnLen * 2 - PtwL2IdxLen 96 val ptwl2Replacer = Some("setplru") 97 98 // ptwl3: 16-way group-associated 99 val PtwL3WayNum = 16 100 val PtwL3WaySize = PtwL3EntrySize / PtwL3WayNum 101 val PtwL3SectorSize = MemBandWidth / XLEN 102 val PtwL3LineSize = PtwL3SectorSize * PtwL3WayNum 103 val PtwL3LineNum = PtwL3EntrySize / PtwL3LineSize 104 val PtwL3IdxLen = log2Up(PtwL3WaySize) 105 val PtwL3SectorIdxLen = log2Up(PtwL3SectorSize) 106 val PtwL3SetIdxLen = log2Up(PtwL3LineNum) 107 val PtwL3TagLen = vpnnLen * 3 - PtwL3IdxLen 108 val ptwl3Replacer = Some("setplru") 109 110 // super page, including 1GB and 2MB page 111 val SPTagLen = vpnnLen * 2 112 val spReplacer = Some("plru") 113 114 val MSHRSize = PtwMissQueueSize 115 116 def genPtwL2Idx(vpn: UInt) = { 117 (vpn(vpnLen - 1, vpnnLen))(PtwL2IdxLen - 1, 0) 118 } 119 120 def genPtwL2SectorIdx(vpn: UInt) = { 121 genPtwL2Idx(vpn)(PtwL2SectorIdxLen - 1, 0) 122 } 123 124 def genPtwL2SetIdx(vpn: UInt) = { 125 genPtwL2Idx(vpn)(PtwL2SetIdxLen + PtwL2SectorIdxLen - 1, PtwL2SectorIdxLen) 126 } 127 128 def genPtwL3Idx(vpn: UInt) = { 129 vpn(PtwL3IdxLen - 1, 0) 130 } 131 132 def genPtwL3SectorIdx(vpn: UInt) = { 133 genPtwL3Idx(vpn)(PtwL3SectorIdxLen - 1, 0) 134 } 135 136 def genPtwL3SetIdx(vpn: UInt) = { 137 genPtwL3Idx(vpn)(PtwL3SetIdxLen + PtwL3SectorIdxLen - 1, PtwL3SectorIdxLen) 138 } 139 140 def MakeAddr(ppn: UInt, off: UInt) = { 141 require(off.getWidth == 9) 142 Cat(ppn, off, 0.U(log2Up(XLEN/8).W))(PAddrBits-1, 0) 143 } 144 145 def getVpnn(vpn: UInt, idx: Int) = { 146 vpn(vpnnLen*(idx+1)-1, vpnnLen*idx) 147 } 148 149 def getVpnClip(vpn: UInt, level: Int) = { 150 // level 0 /* vpnn2 */ 151 // level 1 /* vpnn2 * vpnn1 */ 152 // level 2 /* vpnn2 * vpnn1 * vpnn0*/ 153 vpn(vpnLen - 1, (2 - level) * vpnnLen) 154 } 155 156 def printVec[T <: Data](x: Seq[T]): Printable = { 157 (0 until x.length).map(i => p"(${i.U})${x(i)} ").reduce(_+_) 158 } 159 160}