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.{ICache, DCache, L1plusCache, DCacheParameters, ICacheParameters, L1plusCacheParameters, PTW, Uncache} 14import chipsalliance.rocketchip.config 15import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 16import freechips.rocketchip.tilelink.{TLBundleParameters, TLCacheCork, TLBuffer, TLClientNode, TLIdentityNode, TLXbar} 17import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} 18import utils._ 19 20case class XSCoreParameters 21( 22 XLEN: Int = 64, 23 HasMExtension: Boolean = true, 24 HasCExtension: Boolean = true, 25 HasDiv: Boolean = true, 26 HasICache: Boolean = true, 27 HasDCache: Boolean = true, 28 EnableStoreQueue: Boolean = true, 29 AddrBits: Int = 64, 30 VAddrBits: Int = 39, 31 PAddrBits: Int = 40, 32 HasFPU: Boolean = true, 33 FectchWidth: Int = 8, 34 EnableBPU: Boolean = true, 35 EnableBPD: Boolean = true, 36 EnableRAS: Boolean = true, 37 EnableLB: Boolean = true, 38 EnableLoop: Boolean = true, 39 HistoryLength: Int = 64, 40 BtbSize: Int = 2048, 41 JbtacSize: Int = 1024, 42 JbtacBanks: Int = 8, 43 RasSize: Int = 16, 44 CacheLineSize: Int = 512, 45 UBtbWays: Int = 16, 46 BtbWays: Int = 2, 47 IBufSize: Int = 64, 48 DecodeWidth: Int = 6, 49 RenameWidth: Int = 6, 50 CommitWidth: Int = 6, 51 BrqSize: Int = 12, 52 IssQueSize: Int = 8, 53 NRPhyRegs: Int = 128, 54 NRIntReadPorts: Int = 14, 55 NRIntWritePorts: Int = 8, 56 NRFpReadPorts: Int = 14, 57 NRFpWritePorts: Int = 8, 58 LsroqSize: Int = 16, 59 LoadQueueSize: Int = 12, 60 StoreQueueSize: Int = 10, 61 RoqSize: Int = 32, 62 dpParams: DispatchParameters = DispatchParameters( 63 DqEnqWidth = 4, 64 IntDqSize = 24, 65 FpDqSize = 16, 66 LsDqSize = 16, 67 IntDqDeqWidth = 4, 68 FpDqDeqWidth = 4, 69 LsDqDeqWidth = 4, 70 IntDqReplayWidth = 4, 71 FpDqReplayWidth = 4, 72 LsDqReplayWidth = 4 73 ), 74 exuParameters: ExuParameters = ExuParameters( 75 JmpCnt = 1, 76 AluCnt = 4, 77 MulCnt = 0, 78 MduCnt = 2, 79 FmacCnt = 4, 80 FmiscCnt = 2, 81 FmiscDivSqrtCnt = 0, 82 LduCnt = 2, 83 StuCnt = 2 84 ), 85 LoadPipelineWidth: Int = 2, 86 StorePipelineWidth: Int = 2, 87 StoreBufferSize: Int = 16, 88 RefillSize: Int = 512, 89 TlbEntrySize: Int = 32, 90 TlbL2EntrySize: Int = 256, // or 512 91 PtwL1EntrySize: Int = 16, 92 PtwL2EntrySize: Int = 256, 93 NumPerfCounters: Int = 16 94) 95 96trait HasXSParameter { 97 98 val core = Parameters.get.coreParameters 99 val env = Parameters.get.envParameters 100 101 val XLEN = core.XLEN 102 val HasMExtension = core.HasMExtension 103 val HasCExtension = core.HasCExtension 104 val HasDiv = core.HasDiv 105 val HasIcache = core.HasICache 106 val HasDcache = core.HasDCache 107 val EnableStoreQueue = core.EnableStoreQueue 108 val AddrBits = core.AddrBits // AddrBits is used in some cases 109 val VAddrBits = core.VAddrBits // VAddrBits is Virtual Memory addr bits 110 val PAddrBits = core.PAddrBits // PAddrBits is Phyical Memory addr bits 111 val AddrBytes = AddrBits / 8 // unused 112 val DataBits = XLEN 113 val DataBytes = DataBits / 8 114 val HasFPU = core.HasFPU 115 val FetchWidth = core.FectchWidth 116 val PredictWidth = FetchWidth * 2 117 val EnableBPU = core.EnableBPU 118 val EnableBPD = core.EnableBPD // enable backing predictor(like Tage) in BPUStage3 119 val EnableRAS = core.EnableRAS 120 val EnableLB = core.EnableLB 121 val EnableLoop = core.EnableLoop 122 val HistoryLength = core.HistoryLength 123 val BtbSize = core.BtbSize 124 // val BtbWays = 4 125 val BtbBanks = PredictWidth 126 // val BtbSets = BtbSize / BtbWays 127 val JbtacSize = core.JbtacSize 128 val JbtacBanks = core.JbtacBanks 129 val RasSize = core.RasSize 130 val CacheLineSize = core.CacheLineSize 131 val CacheLineHalfWord = CacheLineSize / 16 132 val ExtHistoryLength = HistoryLength + 64 133 val UBtbWays = core.UBtbWays 134 val BtbWays = core.BtbWays 135 val IBufSize = core.IBufSize 136 val DecodeWidth = core.DecodeWidth 137 val RenameWidth = core.RenameWidth 138 val CommitWidth = core.CommitWidth 139 val BrqSize = core.BrqSize 140 val IssQueSize = core.IssQueSize 141 val BrTagWidth = log2Up(BrqSize) 142 val NRPhyRegs = core.NRPhyRegs 143 val PhyRegIdxWidth = log2Up(NRPhyRegs) 144 val RoqSize = core.RoqSize 145 val LsroqSize = core.LsroqSize // 64 146 val LoadQueueSize = core.LoadQueueSize 147 val StoreQueueSize = core.StoreQueueSize 148 val dpParams = core.dpParams 149 val ReplayWidth = dpParams.IntDqReplayWidth + dpParams.FpDqReplayWidth + dpParams.LsDqReplayWidth 150 val exuParameters = core.exuParameters 151 val NRIntReadPorts = core.NRIntReadPorts 152 val NRIntWritePorts = core.NRIntWritePorts 153 val NRMemReadPorts = exuParameters.LduCnt + 2*exuParameters.StuCnt 154 val NRFpReadPorts = core.NRFpReadPorts 155 val NRFpWritePorts = core.NRFpWritePorts 156 val LoadPipelineWidth = core.LoadPipelineWidth 157 val StorePipelineWidth = core.StorePipelineWidth 158 val StoreBufferSize = core.StoreBufferSize 159 val RefillSize = core.RefillSize 160 val DTLBWidth = core.LoadPipelineWidth + core.StorePipelineWidth 161 val TlbEntrySize = core.TlbEntrySize 162 val TlbL2EntrySize = core.TlbL2EntrySize 163 val PtwL1EntrySize = core.PtwL1EntrySize 164 val PtwL2EntrySize = core.PtwL2EntrySize 165 val NumPerfCounters = core.NumPerfCounters 166 167 val l1BusDataWidth = 256 168 169 val icacheParameters = ICacheParameters( 170 nMissEntries = 2 171 ) 172 173 val l1plusCacheParameters = L1plusCacheParameters( 174 tagECC = Some("secded"), 175 dataECC = Some("secded"), 176 nMissEntries = 8 177 ) 178 179 val dcacheParameters = DCacheParameters( 180 tagECC = Some("secded"), 181 dataECC = Some("secded"), 182 nMissEntries = 16, 183 nLoadMissEntries = 8, 184 nStoreMissEntries = 8 185 ) 186 187 val LRSCCycles = 100 188} 189 190trait HasXSLog { this: RawModule => 191 implicit val moduleName: String = this.name 192} 193 194abstract class XSModule extends MultiIOModule 195 with HasXSParameter 196 with HasExceptionNO 197 with HasXSLog 198{ 199 def io: Record 200} 201 202//remove this trait after impl module logic 203trait NeedImpl { this: RawModule => 204 override protected def IO[T <: Data](iodef: T): T = { 205 println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module") 206 val io = chisel3.experimental.IO(iodef) 207 io <> DontCare 208 io 209 } 210} 211 212abstract class XSBundle extends Bundle 213 with HasXSParameter 214 215case class EnviromentParameters 216( 217 FPGAPlatform: Boolean = true, 218 EnableDebug: Boolean = false 219) 220 221object AddressSpace extends HasXSParameter { 222 // (start, size) 223 // address out of MMIO will be considered as DRAM 224 def mmio = List( 225 (0x30000000L, 0x10000000L), // internal devices, such as CLINT and PLIC 226 (0x40000000L, 0x40000000L) // external devices 227 ) 228 229 def isMMIO(addr: UInt): Bool = mmio.map(range => { 230 require(isPow2(range._2)) 231 val bits = log2Up(range._2) 232 (addr ^ range._1.U)(PAddrBits-1, bits) === 0.U 233 }).reduce(_ || _) 234} 235 236 237 238class XSCore()(implicit p: config.Parameters) extends LazyModule { 239 240 val dcache = LazyModule(new DCache()) 241 val uncache = LazyModule(new Uncache()) 242 val l1pluscache = LazyModule(new L1plusCache()) 243 val ptw = LazyModule(new PTW()) 244 245 val mem = TLIdentityNode() 246 val mmio = uncache.clientNode 247 248 // TODO: refactor these params 249 private val l2 = LazyModule(new InclusiveCache( 250 CacheParameters( 251 level = 2, 252 ways = 4, 253 sets = 512 * 1024 / (64 * 4), 254 blockBytes = 64, 255 beatBytes = 32 // beatBytes = l1BusDataWidth / 8 256 ), 257 InclusiveCacheMicroParameters( 258 writeBytes = 8 259 ) 260 )) 261 262 private val xbar = TLXbar() 263 264 xbar := TLBuffer() := DebugIdentityNode() := dcache.clientNode 265 xbar := TLBuffer() := DebugIdentityNode() := l1pluscache.clientNode 266 xbar := TLBuffer() := DebugIdentityNode() := ptw.node 267 268 l2.node := xbar 269 270 mem := TLBuffer() := TLCacheCork() := TLBuffer() := l2.node 271 272 lazy val module = new XSCoreImp(this) 273} 274 275class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer) 276 with HasXSParameter 277 with HasExeBlockHelper 278{ 279 val io = IO(new Bundle { 280 val externalInterrupt = new ExternalInterruptIO 281 }) 282 283 // to fast wake up fp, mem rs 284 val intBlockFastWakeUpFp = intExuConfigs.filter(fpFastFilter) 285 val intBlockSlowWakeUpFp = intExuConfigs.filter(fpSlowFilter) 286 val intBlockFastWakeUpInt = intExuConfigs.filter(intFastFilter) 287 val intBlockSlowWakeUpInt = intExuConfigs.filter(intSlowFilter) 288 289 val fpBlockFastWakeUpFp = fpExuConfigs.filter(fpFastFilter) 290 val fpBlockSlowWakeUpFp = fpExuConfigs.filter(fpSlowFilter) 291 val fpBlockFastWakeUpInt = fpExuConfigs.filter(intFastFilter) 292 val fpBlockSlowWakeUpInt = fpExuConfigs.filter(intSlowFilter) 293 294 val frontend = Module(new Frontend) 295 val ctrlBlock = Module(new CtrlBlock) 296 val integerBlock = Module(new IntegerBlock( 297 fastWakeUpIn = fpBlockFastWakeUpInt, 298 slowWakeUpIn = fpBlockSlowWakeUpInt ++ loadExuConfigs, 299 fastFpOut = intBlockFastWakeUpFp, 300 slowFpOut = intBlockSlowWakeUpFp, 301 fastIntOut = intBlockFastWakeUpInt, 302 slowIntOut = intBlockSlowWakeUpInt 303 )) 304 val floatBlock = Module(new FloatBlock( 305 fastWakeUpIn = intBlockFastWakeUpFp, 306 slowWakeUpIn = intBlockSlowWakeUpFp ++ loadExuConfigs, 307 fastFpOut = fpBlockFastWakeUpFp, 308 slowFpOut = fpBlockSlowWakeUpFp, 309 fastIntOut = fpBlockFastWakeUpInt, 310 slowIntOut = fpBlockSlowWakeUpInt 311 )) 312 val memBlock = Module(new MemBlock( 313 fastWakeUpIn = intBlockFastWakeUpInt ++ intBlockFastWakeUpFp ++ fpBlockFastWakeUpInt ++ fpBlockFastWakeUpFp, 314 slowWakeUpIn = intBlockSlowWakeUpInt ++ intBlockSlowWakeUpFp ++ fpBlockSlowWakeUpInt ++ fpBlockSlowWakeUpFp, 315 fastFpOut = Seq(), 316 slowFpOut = loadExuConfigs, 317 fastIntOut = Seq(), 318 slowIntOut = loadExuConfigs 319 )) 320 321 val dcache = outer.dcache.module 322 val uncache = outer.uncache.module 323 val l1pluscache = outer.l1pluscache.module 324 val ptw = outer.ptw.module 325 val icache = Module(new ICache) 326 327 frontend.io.backend <> ctrlBlock.io.frontend 328 frontend.io.icacheResp <> icache.io.resp 329 frontend.io.icacheToTlb <> icache.io.tlb 330 icache.io.req <> frontend.io.icacheReq 331 icache.io.flush <> frontend.io.icacheFlush 332 integerBlock.io.fenceio.sfence <> frontend.io.sfence 333 334 icache.io.mem_acquire <> l1pluscache.io.req 335 l1pluscache.io.resp <> icache.io.mem_grant 336 l1pluscache.io.flush := icache.io.l1plusflush 337 icache.io.fencei := integerBlock.io.fenceio.fencei 338 339 ctrlBlock.io.fromIntBlock <> integerBlock.io.toCtrlBlock 340 ctrlBlock.io.fromFpBlock <> floatBlock.io.toCtrlBlock 341 ctrlBlock.io.fromLsBlock <> memBlock.io.toCtrlBlock 342 ctrlBlock.io.toIntBlock <> integerBlock.io.fromCtrlBlock 343 ctrlBlock.io.toFpBlock <> floatBlock.io.fromCtrlBlock 344 ctrlBlock.io.toLsBlock <> memBlock.io.fromCtrlBlock 345 346 integerBlock.io.wakeUpIn.fast <> floatBlock.io.wakeUpIntOut.fast 347 integerBlock.io.wakeUpIn.slow <> floatBlock.io.wakeUpIntOut.slow ++ memBlock.io.wakeUpIntOut.slow 348 349 floatBlock.io.wakeUpIn.fast <> integerBlock.io.wakeUpFpOut.fast 350 floatBlock.io.wakeUpIn.slow <> integerBlock.io.wakeUpFpOut.slow ++ memBlock.io.wakeUpFpOut.slow 351 352 memBlock.io.wakeUpIn.fast <> integerBlock.io.wakeUpIntOut.fast ++ 353 integerBlock.io.wakeUpFpOut.fast ++ 354 floatBlock.io.wakeUpIntOut.fast ++ 355 floatBlock.io.wakeUpFpOut.fast 356 357 memBlock.io.wakeUpIn.slow <> integerBlock.io.wakeUpIntOut.slow ++ 358 integerBlock.io.wakeUpFpOut.slow ++ 359 floatBlock.io.wakeUpIntOut.slow ++ 360 floatBlock.io.wakeUpFpOut.slow 361 362 integerBlock.io.csrio.fflags <> ctrlBlock.io.roqio.toCSR.fflags 363 integerBlock.io.csrio.dirty_fs <> ctrlBlock.io.roqio.toCSR.dirty_fs 364 integerBlock.io.csrio.exception <> ctrlBlock.io.roqio.exception 365 integerBlock.io.csrio.isInterrupt <> ctrlBlock.io.roqio.isInterrupt 366 integerBlock.io.csrio.trapTarget <> ctrlBlock.io.roqio.toCSR.trapTarget 367 integerBlock.io.csrio.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr 368 integerBlock.io.csrio.externalInterrupt <> io.externalInterrupt 369 integerBlock.io.csrio.tlb <> memBlock.io.tlbCsr 370 integerBlock.io.fenceio.sfence <> memBlock.io.sfence 371 integerBlock.io.fenceio.sbuffer <> memBlock.io.fenceToSbuffer 372 373 floatBlock.io.frm <> integerBlock.io.csrio.frm 374 375 memBlock.io.lsqio.commits <> ctrlBlock.io.roqio.commits 376 memBlock.io.lsqio.roqDeqPtr <> ctrlBlock.io.roqio.roqDeqPtr 377 memBlock.io.lsqio.oldestStore <> ctrlBlock.io.oldestStore 378 memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.lqIdx 379 memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.sqIdx 380 memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.ctrl.commitType) 381 382 ptw.io.tlb(0) <> memBlock.io.ptw 383 ptw.io.tlb(1) <> frontend.io.ptw 384 ptw.io.sfence <> integerBlock.io.fenceio.sfence 385 ptw.io.csr <> integerBlock.io.csrio.tlb 386 387 dcache.io.lsu.load <> memBlock.io.dcache.loadUnitToDcacheVec 388 dcache.io.lsu.lsroq <> memBlock.io.dcache.loadMiss 389 dcache.io.lsu.atomics <> memBlock.io.dcache.atomics 390 dcache.io.lsu.store <> memBlock.io.dcache.sbufferToDcache 391 uncache.io.lsroq <> memBlock.io.dcache.uncache 392 393 val debugIntReg, debugFpReg = WireInit(VecInit(Seq.fill(32)(0.U(XLEN.W)))) 394 ExcitingUtils.addSink(debugIntReg, "DEBUG_INT_ARCH_REG", ExcitingUtils.Debug) 395 ExcitingUtils.addSink(debugFpReg, "DEBUG_FP_ARCH_REG", ExcitingUtils.Debug) 396 val debugArchReg = WireInit(VecInit(debugIntReg ++ debugFpReg)) 397 if (!env.FPGAPlatform) { 398 ExcitingUtils.addSource(debugArchReg, "difftestRegs", ExcitingUtils.Debug) 399 } 400 401 402} 403