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.backend.exu.Exu._ 10import xiangshan.frontend._ 11import xiangshan.mem._ 12import xiangshan.backend.fu.HasExceptionNO 13import xiangshan.cache.{DCache, DCacheParameters, ICache, ICacheParameters, L1plusCache, L1plusCacheParameters, PTW, Uncache} 14import xiangshan.cache.prefetch._ 15import chipsalliance.rocketchip.config 16import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp} 17import freechips.rocketchip.tilelink.{TLBuffer, TLBundleParameters, TLCacheCork, TLClientNode, TLFilter, TLIdentityNode, TLToAXI4, TLWidthWidget, TLXbar} 18import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError} 19import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} 20import freechips.rocketchip.amba.axi4.{AXI4Deinterleaver, AXI4Fragmenter, AXI4IdIndexer, AXI4IdentityNode, AXI4ToTL, AXI4UserYanker} 21import freechips.rocketchip.tile.HasFPUParameters 22import utils._ 23 24case class XSCoreParameters 25( 26 XLEN: Int = 64, 27 HasMExtension: Boolean = true, 28 HasCExtension: Boolean = true, 29 HasDiv: Boolean = true, 30 HasICache: Boolean = true, 31 HasDCache: Boolean = true, 32 EnableStoreQueue: Boolean = true, 33 AddrBits: Int = 64, 34 VAddrBits: Int = 39, 35 PAddrBits: Int = 40, 36 HasFPU: Boolean = true, 37 FectchWidth: Int = 8, 38 EnableBPU: Boolean = true, 39 EnableBPD: Boolean = true, 40 EnableRAS: Boolean = true, 41 EnableLB: Boolean = false, 42 EnableLoop: Boolean = true, 43 EnableSC: Boolean = false, 44 HistoryLength: Int = 64, 45 BtbSize: Int = 2048, 46 JbtacSize: Int = 1024, 47 JbtacBanks: Int = 8, 48 RasSize: Int = 16, 49 CacheLineSize: Int = 512, 50 UBtbWays: Int = 16, 51 BtbWays: Int = 2, 52 53 EnableL1plusPrefetcher: Boolean = true, 54 IBufSize: Int = 32, 55 DecodeWidth: Int = 6, 56 RenameWidth: Int = 6, 57 CommitWidth: Int = 6, 58 BrqSize: Int = 32, 59 IssQueSize: Int = 12, 60 NRPhyRegs: Int = 160, 61 NRIntReadPorts: Int = 14, 62 NRIntWritePorts: Int = 8, 63 NRFpReadPorts: Int = 14, 64 NRFpWritePorts: Int = 8, 65 LoadQueueSize: Int = 64, 66 StoreQueueSize: Int = 48, 67 RoqSize: Int = 192, 68 dpParams: DispatchParameters = DispatchParameters( 69 IntDqSize = 32, 70 FpDqSize = 32, 71 LsDqSize = 32, 72 IntDqDeqWidth = 4, 73 FpDqDeqWidth = 4, 74 LsDqDeqWidth = 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 NrExtIntr: Int = 1 97) 98 99trait HasXSParameter { 100 101 val core = Parameters.get.coreParameters 102 val env = Parameters.get.envParameters 103 104 val XLEN = 64 105 val minFLen = 32 106 val fLen = 64 107 def xLen = 64 108 val HasMExtension = core.HasMExtension 109 val HasCExtension = core.HasCExtension 110 val HasDiv = core.HasDiv 111 val HasIcache = core.HasICache 112 val HasDcache = core.HasDCache 113 val EnableStoreQueue = core.EnableStoreQueue 114 val AddrBits = core.AddrBits // AddrBits is used in some cases 115 val VAddrBits = core.VAddrBits // VAddrBits is Virtual Memory addr bits 116 val PAddrBits = core.PAddrBits // PAddrBits is Phyical Memory addr bits 117 val AddrBytes = AddrBits / 8 // unused 118 val DataBits = XLEN 119 val DataBytes = DataBits / 8 120 val HasFPU = core.HasFPU 121 val FetchWidth = core.FectchWidth 122 val PredictWidth = FetchWidth * (if (HasCExtension) 2 else 1) 123 val EnableBPU = core.EnableBPU 124 val EnableBPD = core.EnableBPD // enable backing predictor(like Tage) in BPUStage3 125 val EnableRAS = core.EnableRAS 126 val EnableLB = core.EnableLB 127 val EnableLoop = core.EnableLoop 128 val EnableSC = core.EnableSC 129 val HistoryLength = core.HistoryLength 130 val BtbSize = core.BtbSize 131 // val BtbWays = 4 132 val BtbBanks = PredictWidth 133 // val BtbSets = BtbSize / BtbWays 134 val JbtacSize = core.JbtacSize 135 val JbtacBanks = core.JbtacBanks 136 val RasSize = core.RasSize 137 val CacheLineSize = core.CacheLineSize 138 val CacheLineHalfWord = CacheLineSize / 16 139 val ExtHistoryLength = HistoryLength + 64 140 val UBtbWays = core.UBtbWays 141 val BtbWays = core.BtbWays 142 val EnableL1plusPrefetcher = core.EnableL1plusPrefetcher 143 val IBufSize = core.IBufSize 144 val DecodeWidth = core.DecodeWidth 145 val RenameWidth = core.RenameWidth 146 val CommitWidth = core.CommitWidth 147 val BrqSize = core.BrqSize 148 val IssQueSize = core.IssQueSize 149 val BrTagWidth = log2Up(BrqSize) 150 val NRPhyRegs = core.NRPhyRegs 151 val PhyRegIdxWidth = log2Up(NRPhyRegs) 152 val RoqSize = core.RoqSize 153 val LoadQueueSize = core.LoadQueueSize 154 val StoreQueueSize = core.StoreQueueSize 155 val dpParams = core.dpParams 156 val exuParameters = core.exuParameters 157 val NRIntReadPorts = core.NRIntReadPorts 158 val NRIntWritePorts = core.NRIntWritePorts 159 val NRMemReadPorts = exuParameters.LduCnt + 2*exuParameters.StuCnt 160 val NRFpReadPorts = core.NRFpReadPorts 161 val NRFpWritePorts = core.NRFpWritePorts 162 val LoadPipelineWidth = core.LoadPipelineWidth 163 val StorePipelineWidth = core.StorePipelineWidth 164 val StoreBufferSize = core.StoreBufferSize 165 val RefillSize = core.RefillSize 166 val DTLBWidth = core.LoadPipelineWidth + core.StorePipelineWidth 167 val TlbEntrySize = core.TlbEntrySize 168 val TlbL2EntrySize = core.TlbL2EntrySize 169 val PtwL1EntrySize = core.PtwL1EntrySize 170 val PtwL2EntrySize = core.PtwL2EntrySize 171 val NumPerfCounters = core.NumPerfCounters 172 val NrExtIntr = core.NrExtIntr 173 174 val icacheParameters = ICacheParameters( 175 tagECC = Some("parity"), 176 dataECC = Some("parity"), 177 nMissEntries = 2 178 ) 179 180 val l1plusCacheParameters = L1plusCacheParameters( 181 tagECC = Some("secded"), 182 dataECC = Some("secded"), 183 nMissEntries = 8 184 ) 185 186 val dcacheParameters = DCacheParameters( 187 tagECC = Some("secded"), 188 dataECC = Some("secded"), 189 nMissEntries = 16, 190 nLoadMissEntries = 8, 191 nStoreMissEntries = 8 192 ) 193 194 val LRSCCycles = 100 195 196 197 // cache hierarchy configurations 198 val l1BusDataWidth = 256 199 200 // L2 configurations 201 val L1BusWidth = 256 202 val L2Size = 512 * 1024 // 512KB 203 val L2BlockSize = 64 204 val L2NWays = 8 205 val L2NSets = L2Size / L2BlockSize / L2NWays 206 207 // L3 configurations 208 val L2BusWidth = 256 209 val L3Size = 4 * 1024 * 1024 // 4MB 210 val L3BlockSize = 64 211 val L3NBanks = 4 212 val L3NWays = 8 213 val L3NSets = L3Size / L3BlockSize / L3NBanks / L3NWays 214 215 // on chip network configurations 216 val L3BusWidth = 256 217 218 // icache prefetcher 219 val l1plusPrefetcherParameters = L1plusPrefetcherParameters( 220 enable = true, 221 _type = "stream", 222 streamParams = StreamPrefetchParameters( 223 streamCnt = 2, 224 streamSize = 4, 225 ageWidth = 4, 226 blockBytes = l1plusCacheParameters.blockBytes, 227 reallocStreamOnMissInstantly = true, 228 cacheName = "icache" 229 ) 230 ) 231 232 // dcache prefetcher 233 val l2PrefetcherParameters = L2PrefetcherParameters( 234 enable = true, 235 _type = "stream", 236 streamParams = StreamPrefetchParameters( 237 streamCnt = 4, 238 streamSize = 4, 239 ageWidth = 4, 240 blockBytes = L2BlockSize, 241 reallocStreamOnMissInstantly = true, 242 cacheName = "dcache" 243 ) 244 ) 245} 246 247trait HasXSLog { this: RawModule => 248 implicit val moduleName: String = this.name 249} 250 251abstract class XSModule extends MultiIOModule 252 with HasXSParameter 253 with HasExceptionNO 254 with HasXSLog 255 with HasFPUParameters 256{ 257 def io: Record 258} 259 260//remove this trait after impl module logic 261trait NeedImpl { this: RawModule => 262 override protected def IO[T <: Data](iodef: T): T = { 263 println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module") 264 val io = chisel3.experimental.IO(iodef) 265 io <> DontCare 266 io 267 } 268} 269 270abstract class XSBundle extends Bundle 271 with HasXSParameter 272 273case class EnviromentParameters 274( 275 FPGAPlatform: Boolean = true, 276 EnableDebug: Boolean = false 277) 278 279// object AddressSpace extends HasXSParameter { 280// // (start, size) 281// // address out of MMIO will be considered as DRAM 282// def mmio = List( 283// (0x00000000L, 0x40000000L), // internal devices, such as CLINT and PLIC 284// (0x40000000L, 0x40000000L) // external devices 285// ) 286 287// def isMMIO(addr: UInt): Bool = mmio.map(range => { 288// require(isPow2(range._2)) 289// val bits = log2Up(range._2) 290// (addr ^ range._1.U)(PAddrBits-1, bits) === 0.U 291// }).reduce(_ || _) 292// } 293 294 295 296class XSCore()(implicit p: config.Parameters) extends LazyModule 297 with HasXSParameter 298 with HasExeBlockHelper 299{ 300 301 // to fast wake up fp, mem rs 302 val intBlockFastWakeUpFp = intExuConfigs.filter(fpFastFilter) 303 val intBlockSlowWakeUpFp = intExuConfigs.filter(fpSlowFilter) 304 val intBlockFastWakeUpInt = intExuConfigs.filter(intFastFilter) 305 val intBlockSlowWakeUpInt = intExuConfigs.filter(intSlowFilter) 306 307 val fpBlockFastWakeUpFp = fpExuConfigs.filter(fpFastFilter) 308 val fpBlockSlowWakeUpFp = fpExuConfigs.filter(fpSlowFilter) 309 val fpBlockFastWakeUpInt = fpExuConfigs.filter(intFastFilter) 310 val fpBlockSlowWakeUpInt = fpExuConfigs.filter(intSlowFilter) 311 312 // outer facing nodes 313 val l1pluscache = LazyModule(new L1plusCache()) 314 val ptw = LazyModule(new PTW()) 315 val l2Prefetcher = LazyModule(new L2Prefetcher()) 316 val memBlock = LazyModule(new MemBlock( 317 fastWakeUpIn = intBlockFastWakeUpInt ++ intBlockFastWakeUpFp ++ fpBlockFastWakeUpInt ++ fpBlockFastWakeUpFp, 318 slowWakeUpIn = intBlockSlowWakeUpInt ++ intBlockSlowWakeUpFp ++ fpBlockSlowWakeUpInt ++ fpBlockSlowWakeUpFp, 319 fastFpOut = Seq(), 320 slowFpOut = loadExuConfigs, 321 fastIntOut = Seq(), 322 slowIntOut = loadExuConfigs 323 )) 324 325 lazy val module = new XSCoreImp(this) 326} 327 328class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer) 329 with HasXSParameter 330 with HasExeBlockHelper 331{ 332 val io = IO(new Bundle { 333 val externalInterrupt = new ExternalInterruptIO 334 }) 335 336 println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}") 337 AddressSpace.printMemmap() 338 339 // to fast wake up fp, mem rs 340 val intBlockFastWakeUpFp = intExuConfigs.filter(fpFastFilter) 341 val intBlockSlowWakeUpFp = intExuConfigs.filter(fpSlowFilter) 342 val intBlockFastWakeUpInt = intExuConfigs.filter(intFastFilter) 343 val intBlockSlowWakeUpInt = intExuConfigs.filter(intSlowFilter) 344 345 val fpBlockFastWakeUpFp = fpExuConfigs.filter(fpFastFilter) 346 val fpBlockSlowWakeUpFp = fpExuConfigs.filter(fpSlowFilter) 347 val fpBlockFastWakeUpInt = fpExuConfigs.filter(intFastFilter) 348 val fpBlockSlowWakeUpInt = fpExuConfigs.filter(intSlowFilter) 349 350 val frontend = Module(new Frontend) 351 val ctrlBlock = Module(new CtrlBlock) 352 val integerBlock = Module(new IntegerBlock( 353 fastWakeUpIn = fpBlockFastWakeUpInt, 354 slowWakeUpIn = fpBlockSlowWakeUpInt ++ loadExuConfigs, 355 fastFpOut = intBlockFastWakeUpFp, 356 slowFpOut = intBlockSlowWakeUpFp, 357 fastIntOut = intBlockFastWakeUpInt, 358 slowIntOut = intBlockSlowWakeUpInt 359 )) 360 val floatBlock = Module(new FloatBlock( 361 fastWakeUpIn = intBlockFastWakeUpFp, 362 slowWakeUpIn = intBlockSlowWakeUpFp ++ loadExuConfigs, 363 fastFpOut = fpBlockFastWakeUpFp, 364 slowFpOut = fpBlockSlowWakeUpFp, 365 fastIntOut = fpBlockFastWakeUpInt, 366 slowIntOut = fpBlockSlowWakeUpInt 367 )) 368 369 val memBlock = outer.memBlock.module 370 val l1pluscache = outer.l1pluscache.module 371 val ptw = outer.ptw.module 372 val l2Prefetcher = outer.l2Prefetcher.module 373 374 frontend.io.backend <> ctrlBlock.io.frontend 375 frontend.io.sfence <> integerBlock.io.fenceio.sfence 376 frontend.io.tlbCsr <> integerBlock.io.csrio.tlb 377 378 frontend.io.icacheMemAcq <> l1pluscache.io.req 379 l1pluscache.io.resp <> frontend.io.icacheMemGrant 380 l1pluscache.io.flush := frontend.io.l1plusFlush 381 frontend.io.fencei := integerBlock.io.fenceio.fencei 382 383 ctrlBlock.io.fromIntBlock <> integerBlock.io.toCtrlBlock 384 ctrlBlock.io.fromFpBlock <> floatBlock.io.toCtrlBlock 385 ctrlBlock.io.fromLsBlock <> memBlock.io.toCtrlBlock 386 ctrlBlock.io.toIntBlock <> integerBlock.io.fromCtrlBlock 387 ctrlBlock.io.toFpBlock <> floatBlock.io.fromCtrlBlock 388 ctrlBlock.io.toLsBlock <> memBlock.io.fromCtrlBlock 389 390 integerBlock.io.wakeUpIn.fastUops <> floatBlock.io.wakeUpIntOut.fastUops 391 integerBlock.io.wakeUpIn.fast <> floatBlock.io.wakeUpIntOut.fast 392 integerBlock.io.wakeUpIn.slow <> floatBlock.io.wakeUpIntOut.slow ++ memBlock.io.wakeUpIntOut.slow 393 integerBlock.io.toMemBlock <> memBlock.io.fromIntBlock 394 395 floatBlock.io.wakeUpIn.fastUops <> integerBlock.io.wakeUpFpOut.fastUops 396 floatBlock.io.wakeUpIn.fast <> integerBlock.io.wakeUpFpOut.fast 397 floatBlock.io.wakeUpIn.slow <> integerBlock.io.wakeUpFpOut.slow ++ memBlock.io.wakeUpFpOut.slow 398 floatBlock.io.toMemBlock <> memBlock.io.fromFpBlock 399 400 401 integerBlock.io.wakeUpIntOut.fast.map(_.ready := true.B) 402 integerBlock.io.wakeUpIntOut.slow.map(_.ready := true.B) 403 floatBlock.io.wakeUpFpOut.fast.map(_.ready := true.B) 404 floatBlock.io.wakeUpFpOut.slow.map(_.ready := true.B) 405 406 val wakeUpMem = Seq( 407 integerBlock.io.wakeUpIntOut, 408 integerBlock.io.wakeUpFpOut, 409 floatBlock.io.wakeUpIntOut, 410 floatBlock.io.wakeUpFpOut 411 ) 412 memBlock.io.wakeUpIn.fastUops <> wakeUpMem.flatMap(_.fastUops) 413 memBlock.io.wakeUpIn.fast <> wakeUpMem.flatMap(w => w.fast.map(f => { 414 val raw = WireInit(f) 415 raw 416 })) 417 memBlock.io.wakeUpIn.slow <> wakeUpMem.flatMap(w => w.slow.map(s => { 418 val raw = WireInit(s) 419 raw 420 })) 421 422 integerBlock.io.csrio.fflags <> ctrlBlock.io.roqio.toCSR.fflags 423 integerBlock.io.csrio.dirty_fs <> ctrlBlock.io.roqio.toCSR.dirty_fs 424 integerBlock.io.csrio.exception <> ctrlBlock.io.roqio.exception 425 integerBlock.io.csrio.isInterrupt <> ctrlBlock.io.roqio.isInterrupt 426 integerBlock.io.csrio.trapTarget <> ctrlBlock.io.roqio.toCSR.trapTarget 427 integerBlock.io.csrio.interrupt <> ctrlBlock.io.roqio.toCSR.intrBitSet 428 integerBlock.io.csrio.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr 429 integerBlock.io.csrio.externalInterrupt <> io.externalInterrupt 430 integerBlock.io.csrio.tlb <> memBlock.io.tlbCsr 431 integerBlock.io.csrio.perfinfo <> ctrlBlock.io.roqio.toCSR.perfinfo 432 integerBlock.io.fenceio.sfence <> memBlock.io.sfence 433 integerBlock.io.fenceio.sbuffer <> memBlock.io.fenceToSbuffer 434 435 floatBlock.io.frm <> integerBlock.io.csrio.frm 436 437 memBlock.io.lsqio.commits <> ctrlBlock.io.roqio.commits 438 memBlock.io.lsqio.roqDeqPtr <> ctrlBlock.io.roqio.roqDeqPtr 439 memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.lqIdx 440 memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.sqIdx 441 memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.ctrl.commitType) 442 443 ptw.io.tlb(0) <> memBlock.io.ptw 444 ptw.io.tlb(1) <> frontend.io.ptw 445 ptw.io.sfence <> integerBlock.io.fenceio.sfence 446 ptw.io.csr <> integerBlock.io.csrio.tlb 447 448 l2Prefetcher.io.in <> memBlock.io.toDCachePrefetch 449 450 if (!env.FPGAPlatform) { 451 val debugIntReg, debugFpReg = WireInit(VecInit(Seq.fill(32)(0.U(XLEN.W)))) 452 ExcitingUtils.addSink(debugIntReg, "DEBUG_INT_ARCH_REG", ExcitingUtils.Debug) 453 ExcitingUtils.addSink(debugFpReg, "DEBUG_FP_ARCH_REG", ExcitingUtils.Debug) 454 val debugArchReg = WireInit(VecInit(debugIntReg ++ debugFpReg)) 455 ExcitingUtils.addSource(debugArchReg, "difftestRegs", ExcitingUtils.Debug) 456 } 457 458} 459