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