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 // icache prefetcher 187 val l1plusPrefetcherParameters = L1plusPrefetcherParameters( 188 enable = false, 189 _type = "stream", 190 streamParams = StreamPrefetchParameters( 191 streamCnt = 4, 192 streamSize = 4, 193 ageWidth = 4, 194 blockBytes = l1plusCacheParameters.blockBytes, 195 reallocStreamOnMissInstantly = true 196 ) 197 ) 198 199 // dcache prefetcher 200 val l2PrefetcherParameters = L2PrefetcherParameters( 201 enable = true, 202 _type = "stream", 203 streamParams = StreamPrefetchParameters( 204 streamCnt = 4, 205 streamSize = 4, 206 ageWidth = 4, 207 blockBytes = L2BlockSize, 208 reallocStreamOnMissInstantly = true 209 ) 210 ) 211 212 val dcacheParameters = DCacheParameters( 213 tagECC = Some("secded"), 214 dataECC = Some("secded"), 215 nMissEntries = 16, 216 nLoadMissEntries = 8, 217 nStoreMissEntries = 8 218 ) 219 220 val LRSCCycles = 100 221 222 223 // cache hierarchy configurations 224 val l1BusDataWidth = 256 225 226 // L2 configurations 227 val L1BusWidth = 256 228 val L2Size = 512 * 1024 // 512KB 229 val L2BlockSize = 64 230 val L2NWays = 8 231 val L2NSets = L2Size / L2BlockSize / L2NWays 232 233 // L3 configurations 234 val L2BusWidth = 256 235 val L3Size = 4 * 1024 * 1024 // 4MB 236 val L3BlockSize = 64 237 val L3NBanks = 4 238 val L3NWays = 8 239 val L3NSets = L3Size / L3BlockSize / L3NBanks / L3NWays 240 241 // on chip network configurations 242 val L3BusWidth = 256 243} 244 245trait HasXSLog { this: RawModule => 246 implicit val moduleName: String = this.name 247} 248 249abstract class XSModule extends MultiIOModule 250 with HasXSParameter 251 with HasExceptionNO 252 with HasXSLog 253 with HasFPUParameters 254{ 255 def io: Record 256} 257 258//remove this trait after impl module logic 259trait NeedImpl { this: RawModule => 260 override protected def IO[T <: Data](iodef: T): T = { 261 println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module") 262 val io = chisel3.experimental.IO(iodef) 263 io <> DontCare 264 io 265 } 266} 267 268abstract class XSBundle extends Bundle 269 with HasXSParameter 270 271case class EnviromentParameters 272( 273 FPGAPlatform: Boolean = true, 274 EnableDebug: Boolean = false 275) 276 277object AddressSpace extends HasXSParameter { 278 // (start, size) 279 // address out of MMIO will be considered as DRAM 280 def mmio = List( 281 (0x00000000L, 0x40000000L), // internal devices, such as CLINT and PLIC 282 (0x40000000L, 0x40000000L) // external devices 283 ) 284 285 def isMMIO(addr: UInt): Bool = mmio.map(range => { 286 require(isPow2(range._2)) 287 val bits = log2Up(range._2) 288 (addr ^ range._1.U)(PAddrBits-1, bits) === 0.U 289 }).reduce(_ || _) 290} 291 292 293 294class XSCore()(implicit p: config.Parameters) extends LazyModule 295 with HasXSParameter 296 with HasExeBlockHelper 297{ 298 299 // to fast wake up fp, mem rs 300 val intBlockFastWakeUpFp = intExuConfigs.filter(fpFastFilter) 301 val intBlockSlowWakeUpFp = intExuConfigs.filter(fpSlowFilter) 302 val intBlockFastWakeUpInt = intExuConfigs.filter(intFastFilter) 303 val intBlockSlowWakeUpInt = intExuConfigs.filter(intSlowFilter) 304 305 val fpBlockFastWakeUpFp = fpExuConfigs.filter(fpFastFilter) 306 val fpBlockSlowWakeUpFp = fpExuConfigs.filter(fpSlowFilter) 307 val fpBlockFastWakeUpInt = fpExuConfigs.filter(intFastFilter) 308 val fpBlockSlowWakeUpInt = fpExuConfigs.filter(intSlowFilter) 309 310 // outer facing nodes 311 val l1pluscache = LazyModule(new L1plusCache()) 312 val ptw = LazyModule(new PTW()) 313 val l2Prefetcher = LazyModule(new L2Prefetcher()) 314 val memBlock = LazyModule(new MemBlock( 315 fastWakeUpIn = intBlockFastWakeUpInt ++ intBlockFastWakeUpFp ++ fpBlockFastWakeUpInt ++ fpBlockFastWakeUpFp, 316 slowWakeUpIn = intBlockSlowWakeUpInt ++ intBlockSlowWakeUpFp ++ fpBlockSlowWakeUpInt ++ fpBlockSlowWakeUpFp, 317 fastFpOut = Seq(), 318 slowFpOut = loadExuConfigs, 319 fastIntOut = Seq(), 320 slowIntOut = loadExuConfigs 321 )) 322 323 lazy val module = new XSCoreImp(this) 324} 325 326class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer) 327 with HasXSParameter 328 with HasExeBlockHelper 329{ 330 val io = IO(new Bundle { 331 val externalInterrupt = new ExternalInterruptIO 332 }) 333 334 println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}") 335 336 // to fast wake up fp, mem rs 337 val intBlockFastWakeUpFp = intExuConfigs.filter(fpFastFilter) 338 val intBlockSlowWakeUpFp = intExuConfigs.filter(fpSlowFilter) 339 val intBlockFastWakeUpInt = intExuConfigs.filter(intFastFilter) 340 val intBlockSlowWakeUpInt = intExuConfigs.filter(intSlowFilter) 341 342 val fpBlockFastWakeUpFp = fpExuConfigs.filter(fpFastFilter) 343 val fpBlockSlowWakeUpFp = fpExuConfigs.filter(fpSlowFilter) 344 val fpBlockFastWakeUpInt = fpExuConfigs.filter(intFastFilter) 345 val fpBlockSlowWakeUpInt = fpExuConfigs.filter(intSlowFilter) 346 347 val frontend = Module(new Frontend) 348 val ctrlBlock = Module(new CtrlBlock) 349 val integerBlock = Module(new IntegerBlock( 350 fastWakeUpIn = fpBlockFastWakeUpInt, 351 slowWakeUpIn = fpBlockSlowWakeUpInt ++ loadExuConfigs, 352 fastFpOut = intBlockFastWakeUpFp, 353 slowFpOut = intBlockSlowWakeUpFp, 354 fastIntOut = intBlockFastWakeUpInt, 355 slowIntOut = intBlockSlowWakeUpInt 356 )) 357 val floatBlock = Module(new FloatBlock( 358 fastWakeUpIn = intBlockFastWakeUpFp, 359 slowWakeUpIn = intBlockSlowWakeUpFp ++ loadExuConfigs, 360 fastFpOut = fpBlockFastWakeUpFp, 361 slowFpOut = fpBlockSlowWakeUpFp, 362 fastIntOut = fpBlockFastWakeUpInt, 363 slowIntOut = fpBlockSlowWakeUpInt 364 )) 365 366 val memBlock = outer.memBlock.module 367 val l1pluscache = outer.l1pluscache.module 368 val ptw = outer.ptw.module 369 val l2Prefetcher = outer.l2Prefetcher.module 370 371 frontend.io.backend <> ctrlBlock.io.frontend 372 frontend.io.sfence <> integerBlock.io.fenceio.sfence 373 frontend.io.tlbCsr <> integerBlock.io.csrio.tlb 374 375 frontend.io.icacheMemAcq <> l1pluscache.io.req 376 l1pluscache.io.resp <> frontend.io.icacheMemGrant 377 l1pluscache.io.flush := frontend.io.l1plusFlush 378 frontend.io.fencei := integerBlock.io.fenceio.fencei 379 380 ctrlBlock.io.fromIntBlock <> integerBlock.io.toCtrlBlock 381 ctrlBlock.io.fromFpBlock <> floatBlock.io.toCtrlBlock 382 ctrlBlock.io.fromLsBlock <> memBlock.io.toCtrlBlock 383 ctrlBlock.io.toIntBlock <> integerBlock.io.fromCtrlBlock 384 ctrlBlock.io.toFpBlock <> floatBlock.io.fromCtrlBlock 385 ctrlBlock.io.toLsBlock <> memBlock.io.fromCtrlBlock 386 387 integerBlock.io.wakeUpIn.fastUops <> floatBlock.io.wakeUpIntOut.fastUops 388 integerBlock.io.wakeUpIn.fast <> floatBlock.io.wakeUpIntOut.fast 389 integerBlock.io.wakeUpIn.slow <> floatBlock.io.wakeUpIntOut.slow ++ memBlock.io.wakeUpIntOut.slow 390 integerBlock.io.toMemBlock <> memBlock.io.fromIntBlock 391 392 floatBlock.io.wakeUpIn.fastUops <> integerBlock.io.wakeUpFpOut.fastUops 393 floatBlock.io.wakeUpIn.fast <> integerBlock.io.wakeUpFpOut.fast 394 floatBlock.io.wakeUpIn.slow <> integerBlock.io.wakeUpFpOut.slow ++ memBlock.io.wakeUpFpOut.slow 395 floatBlock.io.toMemBlock <> memBlock.io.fromFpBlock 396 397 398 integerBlock.io.wakeUpIntOut.fast.map(_.ready := true.B) 399 integerBlock.io.wakeUpIntOut.slow.map(_.ready := true.B) 400 floatBlock.io.wakeUpFpOut.fast.map(_.ready := true.B) 401 floatBlock.io.wakeUpFpOut.slow.map(_.ready := true.B) 402 403 val wakeUpMem = Seq( 404 integerBlock.io.wakeUpIntOut, 405 integerBlock.io.wakeUpFpOut, 406 floatBlock.io.wakeUpIntOut, 407 floatBlock.io.wakeUpFpOut 408 ) 409 memBlock.io.wakeUpIn.fastUops <> wakeUpMem.flatMap(_.fastUops) 410 memBlock.io.wakeUpIn.fast <> wakeUpMem.flatMap(w => w.fast.map(f => { 411 val raw = WireInit(f) 412 raw 413 })) 414 memBlock.io.wakeUpIn.slow <> wakeUpMem.flatMap(w => w.slow.map(s => { 415 val raw = WireInit(s) 416 raw 417 })) 418 419 integerBlock.io.csrio.fflags <> ctrlBlock.io.roqio.toCSR.fflags 420 integerBlock.io.csrio.dirty_fs <> ctrlBlock.io.roqio.toCSR.dirty_fs 421 integerBlock.io.csrio.exception <> ctrlBlock.io.roqio.exception 422 integerBlock.io.csrio.isInterrupt <> ctrlBlock.io.roqio.isInterrupt 423 integerBlock.io.csrio.trapTarget <> ctrlBlock.io.roqio.toCSR.trapTarget 424 integerBlock.io.csrio.interrupt <> ctrlBlock.io.roqio.toCSR.intrBitSet 425 integerBlock.io.csrio.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr 426 integerBlock.io.csrio.externalInterrupt <> io.externalInterrupt 427 integerBlock.io.csrio.tlb <> memBlock.io.tlbCsr 428 integerBlock.io.fenceio.sfence <> memBlock.io.sfence 429 integerBlock.io.fenceio.sbuffer <> memBlock.io.fenceToSbuffer 430 431 floatBlock.io.frm <> integerBlock.io.csrio.frm 432 433 memBlock.io.lsqio.commits <> ctrlBlock.io.roqio.commits 434 memBlock.io.lsqio.roqDeqPtr <> ctrlBlock.io.roqio.roqDeqPtr 435 memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.lqIdx 436 memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.sqIdx 437 memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.ctrl.commitType) 438 439 ptw.io.tlb(0) <> memBlock.io.ptw 440 ptw.io.tlb(1) <> frontend.io.ptw 441 ptw.io.sfence <> integerBlock.io.fenceio.sfence 442 ptw.io.csr <> integerBlock.io.csrio.tlb 443 444 l2Prefetcher.io.in <> memBlock.io.toDCachePrefetch 445 446 if (!env.FPGAPlatform) { 447 val debugIntReg, debugFpReg = WireInit(VecInit(Seq.fill(32)(0.U(XLEN.W)))) 448 ExcitingUtils.addSink(debugIntReg, "DEBUG_INT_ARCH_REG", ExcitingUtils.Debug) 449 ExcitingUtils.addSink(debugFpReg, "DEBUG_FP_ARCH_REG", ExcitingUtils.Debug) 450 val debugArchReg = WireInit(VecInit(debugIntReg ++ debugFpReg)) 451 ExcitingUtils.addSource(debugArchReg, "difftestRegs", ExcitingUtils.Debug) 452 } 453 454} 455