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