1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16package xiangshan 17 18import chisel3._ 19import chisel3.util._ 20import xiangshan.backend._ 21import xiangshan.backend.fu.HasExceptionNO 22import xiangshan.backend.dispatch.DispatchParameters 23import xiangshan.frontend._ 24import xiangshan.mem._ 25import xiangshan.cache.{DCacheParameters, ICacheParameters, L1plusCacheWrapper, L1plusCacheParameters, PTWWrapper, PTWRepeater, PTWFilter} 26import xiangshan.cache.prefetch._ 27import chipsalliance.rocketchip.config 28import chipsalliance.rocketchip.config.Parameters 29import freechips.rocketchip.diplomacy.{Description, LazyModule, LazyModuleImp, ResourceAnchors, ResourceBindings, SimpleDevice} 30import freechips.rocketchip.tile.HasFPUParameters 31import system.{HasSoCParameter, L1CacheErrorInfo} 32import utils._ 33 34object hartIdCore extends (() => Int) { 35 var x = 0 36 37 def apply(): Int = { 38 x = x + 1 39 x - 1 40 } 41} 42 43abstract class XSModule(implicit val p: Parameters) extends MultiIOModule 44 with HasXSParameter 45 with HasExceptionNO 46 with HasFPUParameters { 47 def io: Record 48} 49 50//remove this trait after impl module logic 51trait NeedImpl { 52 this: RawModule => 53 override protected def IO[T <: Data](iodef: T): T = { 54 println(s"[Warn]: (${this.name}) please reomve 'NeedImpl' after implement this module") 55 val io = chisel3.experimental.IO(iodef) 56 io <> DontCare 57 io 58 } 59} 60 61abstract class XSBundle(implicit val p: Parameters) extends Bundle 62 with HasXSParameter 63 64case class EnviromentParameters 65( 66 FPGAPlatform: Boolean = true, 67 EnableDebug: Boolean = false, 68 EnablePerfDebug: Boolean = true, 69 DualCore: Boolean = false 70) 71 72abstract class XSCoreBase()(implicit p: config.Parameters) extends LazyModule 73 with HasXSParameter 74{ 75 // outer facing nodes 76 val frontend = LazyModule(new Frontend()) 77 val l1pluscache = LazyModule(new L1plusCacheWrapper()) 78 val ptw = LazyModule(new PTWWrapper()) 79 val memBlock = LazyModule(new MemBlock( 80 fastWakeUpIn = intExuConfigs.filter(_.hasCertainLatency), 81 slowWakeUpIn = intExuConfigs.filter(_.hasUncertainlatency) ++ fpExuConfigs, 82 fastWakeUpOut = Seq(), 83 slowWakeUpOut = loadExuConfigs, 84 numIntWakeUpFp = intExuConfigs.count(_.writeFpRf) 85 )) 86 87} 88 89class XSCore()(implicit p: config.Parameters) extends XSCoreBase 90 with HasXSDts 91{ 92 lazy val module = new XSCoreImp(this) 93} 94 95class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer) 96 with HasXSParameter 97 with HasSoCParameter 98 with HasExeBlockHelper { 99 val io = IO(new Bundle { 100 val hartId = Input(UInt(64.W)) 101 val externalInterrupt = new ExternalInterruptIO 102 val l2_pf_enable = Output(Bool()) 103 val l1plus_error, icache_error, dcache_error = Output(new L1CacheErrorInfo) 104 }) 105 106 println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}") 107 AddressSpace.checkMemmap() 108 AddressSpace.printMemmap() 109 110 // to fast wake up fp, mem rs 111 val intBlockFastWakeUp = intExuConfigs.filter(_.hasCertainLatency) 112 val intBlockSlowWakeUp = intExuConfigs.filter(_.hasUncertainlatency) 113 114 val ctrlBlock = Module(new CtrlBlock) 115 val integerBlock = Module(new IntegerBlock( 116 fastWakeUpIn = Seq(), 117 slowWakeUpIn = fpExuConfigs.filter(_.writeIntRf) ++ loadExuConfigs, 118 memFastWakeUpIn = loadExuConfigs, 119 fastWakeUpOut = intBlockFastWakeUp, 120 slowWakeUpOut = intBlockSlowWakeUp 121 )) 122 val floatBlock = Module(new FloatBlock( 123 intSlowWakeUpIn = intExuConfigs.filter(_.writeFpRf), 124 memSlowWakeUpIn = loadExuConfigs, 125 fastWakeUpOut = Seq(), 126 slowWakeUpOut = fpExuConfigs 127 )) 128 129 val frontend = outer.frontend.module 130 val memBlock = outer.memBlock.module 131 val l1pluscache = outer.l1pluscache.module 132 val ptw = outer.ptw.module 133 134 io.l1plus_error <> l1pluscache.io.error 135 io.icache_error <> frontend.io.error 136 io.dcache_error <> memBlock.io.error 137 138 frontend.io.backend <> ctrlBlock.io.frontend 139 frontend.io.sfence <> integerBlock.io.fenceio.sfence 140 frontend.io.tlbCsr <> integerBlock.io.csrio.tlb 141 frontend.io.csrCtrl <> integerBlock.io.csrio.customCtrl 142 143 frontend.io.icacheMemAcq <> l1pluscache.io.req 144 l1pluscache.io.resp <> frontend.io.icacheMemGrant 145 l1pluscache.io.flush := frontend.io.l1plusFlush 146 frontend.io.fencei := integerBlock.io.fenceio.fencei 147 148 ctrlBlock.io.fromIntBlock <> integerBlock.io.toCtrlBlock 149 ctrlBlock.io.fromFpBlock <> floatBlock.io.toCtrlBlock 150 ctrlBlock.io.fromLsBlock <> memBlock.io.toCtrlBlock 151 ctrlBlock.io.toIntBlock <> integerBlock.io.fromCtrlBlock 152 ctrlBlock.io.toFpBlock <> floatBlock.io.fromCtrlBlock 153 ctrlBlock.io.toLsBlock <> memBlock.io.fromCtrlBlock 154 ctrlBlock.io.csrCtrl <> integerBlock.io.csrio.customCtrl 155 156 val memBlockWakeUpInt = memBlock.io.wakeUpOutInt.slow.map(WireInit(_)) 157 val memBlockWakeUpFp = memBlock.io.wakeUpOutFp.slow.map(WireInit(_)) 158 memBlock.io.wakeUpOutInt.slow.foreach(_.ready := true.B) 159 memBlock.io.wakeUpOutFp.slow.foreach(_.ready := true.B) 160 161 fpExuConfigs.zip(floatBlock.io.wakeUpOut.slow).filterNot(_._1.writeIntRf).map(_._2.ready := true.B) 162 val fpBlockWakeUpInt = fpExuConfigs 163 .zip(floatBlock.io.wakeUpOut.slow) 164 .filter(_._1.writeIntRf) 165 .map(_._2) 166 167 intExuConfigs.zip(integerBlock.io.wakeUpOut.slow).filterNot(_._1.writeFpRf).map(_._2.ready := true.B) 168 val intBlockWakeUpFp = intExuConfigs.filter(_.hasUncertainlatency) 169 .zip(integerBlock.io.wakeUpOut.slow) 170 .filter(_._1.writeFpRf) 171 .map(_._2) 172 173 integerBlock.io.wakeUpIn.slow <> fpBlockWakeUpInt ++ memBlockWakeUpInt 174 integerBlock.io.toMemBlock <> memBlock.io.fromIntBlock 175 integerBlock.io.memFastWakeUp <> memBlock.io.ldFastWakeUpInt 176 177 floatBlock.io.intWakeUpFp <> intBlockWakeUpFp 178 floatBlock.io.memWakeUpFp <> memBlockWakeUpFp 179 floatBlock.io.toMemBlock <> memBlock.io.fromFpBlock 180 181 val wakeUpMem = Seq( 182 integerBlock.io.wakeUpOut, 183 floatBlock.io.wakeUpOut, 184 ) 185 memBlock.io.wakeUpIn.fastUops <> wakeUpMem.flatMap(_.fastUops) 186 memBlock.io.wakeUpIn.fast <> wakeUpMem.flatMap(_.fast) 187 // Note: 'WireInit' is used to block 'ready's from memBlock, 188 // we don't need 'ready's from memBlock 189 memBlock.io.wakeUpIn.slow <> wakeUpMem.flatMap(_.slow.map(x => WireInit(x))) 190 memBlock.io.intWakeUpFp <> floatBlock.io.intWakeUpOut 191 memBlock.io.intWbOut := integerBlock.io.intWbOut 192 memBlock.io.fpWbOut := floatBlock.io.fpWbOut 193 194 integerBlock.io.csrio.hartId <> io.hartId 195 integerBlock.io.csrio.perf <> DontCare 196 integerBlock.io.csrio.perf.retiredInstr <> ctrlBlock.io.roqio.toCSR.perfinfo.retiredInstr 197 integerBlock.io.csrio.perf.bpuInfo <> ctrlBlock.io.perfInfo.bpuInfo 198 integerBlock.io.csrio.perf.ctrlInfo <> ctrlBlock.io.perfInfo.ctrlInfo 199 integerBlock.io.csrio.perf.memInfo <> memBlock.io.memInfo 200 integerBlock.io.csrio.perf.frontendInfo <> frontend.io.frontendInfo 201 202 integerBlock.io.csrio.fpu.fflags <> ctrlBlock.io.roqio.toCSR.fflags 203 integerBlock.io.csrio.fpu.isIllegal := false.B 204 integerBlock.io.csrio.fpu.dirty_fs <> ctrlBlock.io.roqio.toCSR.dirty_fs 205 integerBlock.io.csrio.fpu.frm <> floatBlock.io.frm 206 integerBlock.io.csrio.exception <> ctrlBlock.io.roqio.exception 207 integerBlock.io.csrio.isXRet <> ctrlBlock.io.roqio.toCSR.isXRet 208 integerBlock.io.csrio.trapTarget <> ctrlBlock.io.roqio.toCSR.trapTarget 209 integerBlock.io.csrio.interrupt <> ctrlBlock.io.roqio.toCSR.intrBitSet 210 integerBlock.io.csrio.memExceptionVAddr <> memBlock.io.lsqio.exceptionAddr.vaddr 211 integerBlock.io.csrio.externalInterrupt <> io.externalInterrupt 212 213 integerBlock.io.fenceio.sfence <> memBlock.io.sfence 214 integerBlock.io.fenceio.sbuffer <> memBlock.io.fenceToSbuffer 215 216 memBlock.io.csrCtrl <> integerBlock.io.csrio.customCtrl 217 memBlock.io.tlbCsr <> integerBlock.io.csrio.tlb 218 memBlock.io.lsqio.roq <> ctrlBlock.io.roqio.lsq 219 memBlock.io.lsqio.exceptionAddr.lsIdx.lqIdx := ctrlBlock.io.roqio.exception.bits.uop.lqIdx 220 memBlock.io.lsqio.exceptionAddr.lsIdx.sqIdx := ctrlBlock.io.roqio.exception.bits.uop.sqIdx 221 memBlock.io.lsqio.exceptionAddr.isStore := CommitType.lsInstIsStore(ctrlBlock.io.roqio.exception.bits.uop.ctrl.commitType) 222 223 val itlbRepeater = Module(new PTWRepeater()) 224 val dtlbRepeater = Module(new PTWFilter(LoadPipelineWidth + StorePipelineWidth, PtwMissQueueSize)) 225 itlbRepeater.io.tlb <> frontend.io.ptw 226 dtlbRepeater.io.tlb <> memBlock.io.ptw 227 itlbRepeater.io.sfence <> integerBlock.io.fenceio.sfence 228 dtlbRepeater.io.sfence <> integerBlock.io.fenceio.sfence 229 ptw.io.tlb(0) <> itlbRepeater.io.ptw 230 ptw.io.tlb(1) <> dtlbRepeater.io.ptw 231 ptw.io.sfence <> integerBlock.io.fenceio.sfence 232 ptw.io.csr <> integerBlock.io.csrio.tlb 233 234 // if l2 prefetcher use stream prefetch, it should be placed in XSCore 235 assert(l2PrefetcherParameters._type == "bop") 236 io.l2_pf_enable := integerBlock.io.csrio.customCtrl.l2_pf_enable 237 238 val l1plus_reset_gen = Module(new ResetGen(1, !debugOpts.FPGAPlatform)) 239 l1pluscache.reset := l1plus_reset_gen.io.out 240 241 val ptw_reset_gen = Module(new ResetGen(2, !debugOpts.FPGAPlatform)) 242 ptw.reset := ptw_reset_gen.io.out 243 itlbRepeater.reset := ptw_reset_gen.io.out 244 dtlbRepeater.reset := ptw_reset_gen.io.out 245 246 val memBlock_reset_gen = Module(new ResetGen(3, !debugOpts.FPGAPlatform)) 247 memBlock.reset := memBlock_reset_gen.io.out 248 249 val intBlock_reset_gen = Module(new ResetGen(4, !debugOpts.FPGAPlatform)) 250 integerBlock.reset := intBlock_reset_gen.io.out 251 252 val fpBlock_reset_gen = Module(new ResetGen(5, !debugOpts.FPGAPlatform)) 253 floatBlock.reset := fpBlock_reset_gen.io.out 254 255 val ctrlBlock_reset_gen = Module(new ResetGen(6, !debugOpts.FPGAPlatform)) 256 ctrlBlock.reset := ctrlBlock_reset_gen.io.out 257 258 val frontend_reset_gen = Module(new ResetGen(7, !debugOpts.FPGAPlatform)) 259 frontend.reset := frontend_reset_gen.io.out 260} 261