1package xiangshan 2 3import chisel3._ 4import chisel3.util._ 5import top.Parameters 6import xiangshan.backend._ 7import xiangshan.backend.dispatch.DispatchParameters 8import xiangshan.backend.exu.ExuParameters 9import xiangshan.frontend._ 10import xiangshan.mem._ 11import xiangshan.backend.fu.HasExceptionNO 12import xiangshan.cache.{ICache, DCache, L1plusCache, DCacheParameters, ICacheParameters, L1plusCacheParameters, PTW, Uncache} 13import chipsalliance.rocketchip.config 14import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressSet} 15import freechips.rocketchip.tilelink.{TLBundleParameters, TLCacheCork, TLBuffer, TLClientNode, TLIdentityNode, TLXbar, TLWidthWidget, TLFilter, TLToAXI4} 16import freechips.rocketchip.devices.tilelink.{TLError, DevNullParams} 17import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} 18import freechips.rocketchip.amba.axi4.{AXI4ToTL, AXI4IdentityNode, AXI4UserYanker, AXI4Fragmenter, AXI4IdIndexer, AXI4Deinterleaver} 19import utils._ 20 21case class XSCoreParameters 22( 23 XLEN: Int = 64, 24 HasMExtension: Boolean = true, 25 HasCExtension: Boolean = true, 26 HasDiv: Boolean = true, 27 HasICache: Boolean = true, 28 HasDCache: Boolean = true, 29 EnableStoreQueue: Boolean = true, 30 AddrBits: Int = 64, 31 VAddrBits: Int = 39, 32 PAddrBits: Int = 40, 33 HasFPU: Boolean = true, 34 FectchWidth: Int = 8, 35 EnableBPU: Boolean = true, 36 EnableBPD: Boolean = true, 37 EnableRAS: Boolean = true, 38 EnableLB: Boolean = true, 39 EnableLoop: Boolean = true, 40 HistoryLength: Int = 64, 41 BtbSize: Int = 2048, 42 JbtacSize: Int = 1024, 43 JbtacBanks: Int = 8, 44 RasSize: Int = 16, 45 CacheLineSize: Int = 512, 46 UBtbWays: Int = 16, 47 BtbWays: Int = 2, 48 IBufSize: Int = 64, 49 DecodeWidth: Int = 6, 50 RenameWidth: Int = 6, 51 CommitWidth: Int = 6, 52 BrqSize: Int = 12, 53 IssQueSize: Int = 8, 54 NRPhyRegs: Int = 128, 55 NRIntReadPorts: Int = 14, 56 NRIntWritePorts: Int = 8, 57 NRFpReadPorts: Int = 14, 58 NRFpWritePorts: Int = 8, 59 EnableUnifiedLSQ: Boolean = false, 60 LsroqSize: Int = 16, 61 LoadQueueSize: Int = 12, 62 StoreQueueSize: Int = 10, 63 RoqSize: Int = 32, 64 dpParams: DispatchParameters = DispatchParameters( 65 DqEnqWidth = 4, 66 IntDqSize = 24, 67 FpDqSize = 16, 68 LsDqSize = 16, 69 IntDqDeqWidth = 4, 70 FpDqDeqWidth = 4, 71 LsDqDeqWidth = 4, 72 IntDqReplayWidth = 4, 73 FpDqReplayWidth = 4, 74 LsDqReplayWidth = 4 75 ), 76 exuParameters: ExuParameters = ExuParameters( 77 JmpCnt = 1, 78 AluCnt = 4, 79 MulCnt = 0, 80 MduCnt = 2, 81 FmacCnt = 4, 82 FmiscCnt = 2, 83 FmiscDivSqrtCnt = 0, 84 LduCnt = 2, 85 StuCnt = 2 86 ), 87 LoadPipelineWidth: Int = 2, 88 StorePipelineWidth: Int = 2, 89 StoreBufferSize: Int = 16, 90 RefillSize: Int = 512, 91 TlbEntrySize: Int = 32, 92 TlbL2EntrySize: Int = 256, // or 512 93 PtwL1EntrySize: Int = 16, 94 PtwL2EntrySize: Int = 256, 95 NumPerfCounters: Int = 16 96) 97 98trait HasXSParameter { 99 100 val core = Parameters.get.coreParameters 101 val env = Parameters.get.envParameters 102 103 val XLEN = core.XLEN 104 val HasMExtension = core.HasMExtension 105 val HasCExtension = core.HasCExtension 106 val HasDiv = core.HasDiv 107 val HasIcache = core.HasICache 108 val HasDcache = core.HasDCache 109 val EnableStoreQueue = core.EnableStoreQueue 110 val AddrBits = core.AddrBits // AddrBits is used in some cases 111 val VAddrBits = core.VAddrBits // VAddrBits is Virtual Memory addr bits 112 val PAddrBits = core.PAddrBits // PAddrBits is Phyical Memory addr bits 113 val AddrBytes = AddrBits / 8 // unused 114 val DataBits = XLEN 115 val DataBytes = DataBits / 8 116 val HasFPU = core.HasFPU 117 val FetchWidth = core.FectchWidth 118 val PredictWidth = FetchWidth * 2 119 val EnableBPU = core.EnableBPU 120 val EnableBPD = core.EnableBPD // enable backing predictor(like Tage) in BPUStage3 121 val EnableRAS = core.EnableRAS 122 val EnableLB = core.EnableLB 123 val EnableLoop = core.EnableLoop 124 val HistoryLength = core.HistoryLength 125 val BtbSize = core.BtbSize 126 // val BtbWays = 4 127 val BtbBanks = PredictWidth 128 // val BtbSets = BtbSize / BtbWays 129 val JbtacSize = core.JbtacSize 130 val JbtacBanks = core.JbtacBanks 131 val RasSize = core.RasSize 132 val CacheLineSize = core.CacheLineSize 133 val CacheLineHalfWord = CacheLineSize / 16 134 val ExtHistoryLength = HistoryLength + 64 135 val UBtbWays = core.UBtbWays 136 val BtbWays = core.BtbWays 137 val IBufSize = core.IBufSize 138 val DecodeWidth = core.DecodeWidth 139 val RenameWidth = core.RenameWidth 140 val CommitWidth = core.CommitWidth 141 val BrqSize = core.BrqSize 142 val IssQueSize = core.IssQueSize 143 val BrTagWidth = log2Up(BrqSize) 144 val NRPhyRegs = core.NRPhyRegs 145 val PhyRegIdxWidth = log2Up(NRPhyRegs) 146 val RoqSize = core.RoqSize 147 val EnableUnifiedLSQ = core.EnableUnifiedLSQ 148 val LsroqSize = core.LsroqSize // 64 149 val InnerLsroqIdxWidth = log2Up(LsroqSize) 150 val LsroqIdxWidth = InnerLsroqIdxWidth + 1 151 val LoadQueueSize = core.LoadQueueSize 152 val StoreQueueSize = core.StoreQueueSize 153 val dpParams = core.dpParams 154 val ReplayWidth = dpParams.IntDqReplayWidth + dpParams.FpDqReplayWidth + dpParams.LsDqReplayWidth 155 val exuParameters = core.exuParameters 156 val NRIntReadPorts = core.NRIntReadPorts 157 val NRIntWritePorts = core.NRIntWritePorts 158 val NRMemReadPorts = exuParameters.LduCnt + 2*exuParameters.StuCnt 159 val NRFpReadPorts = core.NRFpReadPorts 160 val NRFpWritePorts = core.NRFpWritePorts 161 val LoadPipelineWidth = core.LoadPipelineWidth 162 val StorePipelineWidth = core.StorePipelineWidth 163 val StoreBufferSize = core.StoreBufferSize 164 val RefillSize = core.RefillSize 165 val DTLBWidth = core.LoadPipelineWidth + core.StorePipelineWidth 166 val TlbEntrySize = core.TlbEntrySize 167 val TlbL2EntrySize = core.TlbL2EntrySize 168 val PtwL1EntrySize = core.PtwL1EntrySize 169 val PtwL2EntrySize = core.PtwL2EntrySize 170 val NumPerfCounters = core.NumPerfCounters 171 172 val icacheParameters = ICacheParameters( 173 nMissEntries = 2 174 ) 175 176 val l1plusCacheParameters = L1plusCacheParameters( 177 tagECC = Some("secded"), 178 dataECC = Some("secded"), 179 nMissEntries = 8 180 ) 181 182 val dcacheParameters = DCacheParameters( 183 tagECC = Some("secded"), 184 dataECC = Some("secded"), 185 nMissEntries = 16, 186 nLoadMissEntries = 8, 187 nStoreMissEntries = 8 188 ) 189 190 val LRSCCycles = 100 191 192 193 // cache hierarchy configurations 194 val l1BusDataWidth = 256 195 196 // L2 configurations 197 val L1BusWidth = 256 198 val L2Size = 512 * 1024 // 512KB 199 val L2BlockSize = 64 200 val L2NWays = 8 201 val L2NSets = L2Size / L2BlockSize / L2NWays 202 203 // L3 configurations 204 val L2BusWidth = 256 205 val L3Size = 4 * 1024 * 1024 // 4MB 206 val L3BlockSize = 64 207 val L3NBanks = 4 208 val L3NWays = 8 209 val L3NSets = L3Size / L3BlockSize / L3NBanks / L3NWays 210 211 // on chip network configurations 212 val L3BusWidth = 256 213} 214 215trait HasXSLog { this: RawModule => 216 implicit val moduleName: String = this.name 217} 218 219abstract class XSModule extends MultiIOModule 220 with HasXSParameter 221 with HasExceptionNO 222 with HasXSLog 223{ 224 def io: Record 225} 226 227//remove this trait after impl module logic 228trait NeedImpl { this: RawModule => 229 override protected def IO[T <: Data](iodef: T): T = { 230 println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module") 231 val io = chisel3.experimental.IO(iodef) 232 io <> DontCare 233 io 234 } 235} 236 237abstract class XSBundle extends Bundle 238 with HasXSParameter 239 240case class EnviromentParameters 241( 242 FPGAPlatform: Boolean = true, 243 EnableDebug: Boolean = false 244) 245 246object AddressSpace extends HasXSParameter { 247 // (start, size) 248 // address out of MMIO will be considered as DRAM 249 def mmio = List( 250 (0x30000000L, 0x10000000L), // internal devices, such as CLINT and PLIC 251 (0x40000000L, 0x40000000L) // external devices 252 ) 253 254 def isMMIO(addr: UInt): Bool = mmio.map(range => { 255 require(isPow2(range._2)) 256 val bits = log2Up(range._2) 257 (addr ^ range._1.U)(PAddrBits-1, bits) === 0.U 258 }).reduce(_ || _) 259} 260 261 262 263class XSCore()(implicit p: config.Parameters) extends LazyModule with HasXSParameter { 264 265 // inner nodes 266 val dcache = LazyModule(new DCache()) 267 val uncache = LazyModule(new Uncache()) 268 val l1pluscache = LazyModule(new L1plusCache()) 269 val ptw = LazyModule(new PTW()) 270 271 // out facing nodes 272 val mem = Seq.fill(L3NBanks)(AXI4IdentityNode()) 273 val dma = AXI4IdentityNode() 274 val mmio = uncache.clientNode 275 276 // L1 to L2 network 277 // ------------------------------------------------- 278 private val l2_xbar = TLXbar() 279 280 private val l2 = LazyModule(new InclusiveCache( 281 CacheParameters( 282 level = 2, 283 ways = L2NWays, 284 sets = L2NSets, 285 blockBytes = L2BlockSize, 286 beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8 287 cacheName = s"L2" 288 ), 289 InclusiveCacheMicroParameters( 290 writeBytes = 8 291 ) 292 )) 293 294 l2_xbar := TLBuffer() := DebugIdentityNode() := dcache.clientNode 295 l2_xbar := TLBuffer() := DebugIdentityNode() := l1pluscache.clientNode 296 l2_xbar := TLBuffer() := DebugIdentityNode() := ptw.node 297 l2.node := TLBuffer() := DebugIdentityNode() := l2_xbar 298 299 300 // L2 to L3 network 301 // ------------------------------------------------- 302 private val l3_xbar = TLXbar() 303 304 private val l3_banks = (0 until L3NBanks) map (i => 305 LazyModule(new InclusiveCache( 306 CacheParameters( 307 level = 3, 308 ways = L3NWays, 309 sets = L3NSets, 310 blockBytes = L3BlockSize, 311 beatBytes = L2BusWidth / 8, 312 cacheName = s"L3_$i" 313 ), 314 InclusiveCacheMicroParameters( 315 writeBytes = 8 316 ) 317 ))) 318 319 l3_xbar := TLBuffer() := DebugIdentityNode() := l2.node 320 321 // DMA should not go to MMIO 322 val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL) 323 // AXI4ToTL needs a TLError device to route error requests, 324 // add one here to make it happy. 325 val tlErrorParams = DevNullParams( 326 address = Seq(mmioRange), 327 maxAtomic = 8, 328 maxTransfer = 64) 329 val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8)) 330 private val tlError_xbar = TLXbar() 331 tlError_xbar := 332 AXI4ToTL() := 333 AXI4UserYanker(Some(1)) := 334 AXI4Fragmenter() := 335 AXI4IdIndexer(1) := 336 dma 337 tlError.node := tlError_xbar 338 339 l3_xbar := 340 TLBuffer() := 341 DebugIdentityNode() := 342 tlError_xbar 343 344 def bankFilter(bank: Int) = AddressSet( 345 base = bank * L3BlockSize, 346 mask = ~BigInt((L3NBanks -1) * L3BlockSize)) 347 348 for(i <- 0 until L3NBanks) { 349 val filter = TLFilter(TLFilter.mSelectIntersect(bankFilter(i))) 350 l3_banks(i).node := TLBuffer() := DebugIdentityNode() := filter := l3_xbar 351 } 352 353 354 // L3 to memory network 355 // ------------------------------------------------- 356 private val memory_xbar = TLXbar() 357 358 for(i <- 0 until L3NBanks) { 359 mem(i) := 360 AXI4UserYanker() := 361 TLToAXI4() := 362 TLWidthWidget(L3BusWidth / 8) := 363 TLCacheCork() := 364 DebugIdentityNode() := 365 l3_banks(i).node 366 } 367 368 lazy val module = new XSCoreImp(this) 369} 370 371class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer) with HasXSParameter { 372 val io = IO(new Bundle { 373 val externalInterrupt = new ExternalInterruptIO 374 }) 375 376 val front = Module(new Frontend) 377 val backend = Module(new Backend) 378 val mem = Module(new Memend) 379 380 val dcache = outer.dcache.module 381 val uncache = outer.uncache.module 382 val l1pluscache = outer.l1pluscache.module 383 val ptw = outer.ptw.module 384 val icache = Module(new ICache) 385 386 front.io.backend <> backend.io.frontend 387 front.io.icacheResp <> icache.io.resp 388 front.io.icacheToTlb <> icache.io.tlb 389 icache.io.req <> front.io.icacheReq 390 icache.io.flush <> front.io.icacheFlush 391 392 icache.io.mem_acquire <> l1pluscache.io.req 393 l1pluscache.io.resp <> icache.io.mem_grant 394 l1pluscache.io.flush := icache.io.l1plusflush 395 icache.io.fencei := backend.io.fencei 396 397 mem.io.backend <> backend.io.mem 398 io.externalInterrupt <> backend.io.externalInterrupt 399 400 ptw.io.tlb(0) <> mem.io.ptw 401 ptw.io.tlb(1) <> front.io.ptw 402 ptw.io.sfence <> backend.io.mem.sfence//sfence 403 ptw.io.csr <> backend.io.tlbCsrIO 404 405 dcache.io.lsu.load <> mem.io.loadUnitToDcacheVec 406 dcache.io.lsu.lsroq <> mem.io.loadMiss 407 dcache.io.lsu.atomics <> mem.io.atomics 408 dcache.io.lsu.store <> mem.io.sbufferToDcache 409 uncache.io.lsroq <> mem.io.uncache 410 411} 412