1package system 2 3import chipsalliance.rocketchip.config.Parameters 4import device.{AXI4Timer, TLTimer, AXI4Plic} 5import chisel3._ 6import chisel3.util._ 7import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp} 8import freechips.rocketchip.tilelink.{BankBinder, TLBuffer, TLBundleParameters, TLCacheCork, TLClientNode, TLFilter, TLFuzzer, TLIdentityNode, TLToAXI4, TLWidthWidget, TLXbar} 9import utils.{DebugIdentityNode, DataDontCareNode} 10import utils.XSInfo 11import xiangshan.{HasXSParameter, XSCore, HasXSLog, DifftestBundle} 12import xiangshan.cache.prefetch._ 13import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} 14import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp} 15import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError} 16import freechips.rocketchip.amba.axi4.{AXI4Deinterleaver, AXI4Fragmenter, AXI4IdIndexer, AXI4IdentityNode, AXI4ToTL, AXI4UserYanker} 17 18case class SoCParameters 19( 20 NumCores: Integer = 1, 21 EnableILA: Boolean = false, 22 HasL2Cache: Boolean = false, 23 HasPrefetch: Boolean = false 24) 25 26trait HasSoCParameter extends HasXSParameter{ 27 val soc = top.Parameters.get.socParameters 28 val NumCores = soc.NumCores 29 val EnableILA = soc.EnableILA 30 val HasL2cache = soc.HasL2Cache 31 val HasPrefetch = soc.HasPrefetch 32} 33 34class ILABundle extends Bundle {} 35 36 37class DummyCore()(implicit p: Parameters) extends LazyModule { 38 val mem = TLFuzzer(nOperations = 10) 39 val mmio = TLFuzzer(nOperations = 10) 40 41 lazy val module = new LazyModuleImp(this){ 42 43 } 44} 45 46 47class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { 48 // CPU Cores 49 private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore())) 50 51 // L1 to L2 network 52 // ------------------------------------------------- 53 private val l2_xbar = Seq.fill(NumCores)(TLXbar()) 54 55 private val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache( 56 CacheParameters( 57 level = 2, 58 ways = L2NWays, 59 sets = L2NSets, 60 blockBytes = L2BlockSize, 61 beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8 62 cacheName = s"L2" 63 ), 64 InclusiveCacheMicroParameters( 65 writeBytes = 32 66 ) 67 ))) 68 69 private val l2prefetcher = Seq.fill(NumCores)(LazyModule(new L2Prefetcher())) 70 71 // L2 to L3 network 72 // ------------------------------------------------- 73 private val l3_xbar = TLXbar() 74 75 private val l3_node = LazyModule(new InclusiveCache( 76 CacheParameters( 77 level = 3, 78 ways = L3NWays, 79 sets = L3NSets, 80 blockBytes = L3BlockSize, 81 beatBytes = L2BusWidth / 8, 82 cacheName = "L3" 83 ), 84 InclusiveCacheMicroParameters( 85 writeBytes = 32 86 ) 87 )).node 88 89 // L3 to memory network 90 // ------------------------------------------------- 91 private val memory_xbar = TLXbar() 92 private val mmioXbar = TLXbar() 93 94 // only mem, dma and extDev are visible externally 95 val mem = Seq.fill(L3NBanks)(AXI4IdentityNode()) 96 val dma = AXI4IdentityNode() 97 val extDev = AXI4IdentityNode() 98 99 // connections 100 // ------------------------------------------------- 101 for (i <- 0 until NumCores) { 102 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.dcache.clientNode 103 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).l1pluscache.clientNode 104 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).ptw.node 105 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := l2prefetcher(i).clientNode 106 107 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.uncache.clientNode 108 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).frontend.instrUncache.clientNode 109 l2cache(i).node := DataDontCareNode(a = true, b = true) := TLBuffer() := DebugIdentityNode() := l2_xbar(i) 110 l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node 111 } 112 113 // DMA should not go to MMIO 114 val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL) 115 // AXI4ToTL needs a TLError device to route error requests, 116 // add one here to make it happy. 117 val tlErrorParams = DevNullParams( 118 address = Seq(mmioRange), 119 maxAtomic = 8, 120 maxTransfer = 64) 121 val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8)) 122 private val tlError_xbar = TLXbar() 123 tlError_xbar := 124 AXI4ToTL() := 125 AXI4UserYanker(Some(1)) := 126 AXI4Fragmenter() := 127 AXI4IdIndexer(1) := 128 dma 129 tlError.node := tlError_xbar 130 131 l3_xbar := 132 TLBuffer() := 133 DebugIdentityNode() := 134 tlError_xbar 135 136 val bankedNode = 137 BankBinder(L3NBanks, L3BlockSize) :*= l3_node :*= TLBuffer() :*= DebugIdentityNode() :*= l3_xbar 138 139 for(i <- 0 until L3NBanks) { 140 mem(i) := 141 AXI4UserYanker() := 142 TLToAXI4() := 143 TLWidthWidget(L3BusWidth / 8) := 144 TLCacheCork() := 145 bankedNode 146 } 147 148 private val clint = LazyModule(new TLTimer( 149 Seq(AddressSet(0x38000000L, 0x0000ffffL)), 150 sim = !env.FPGAPlatform 151 )) 152 153 clint.node := mmioXbar 154 extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar 155 156 val plic = LazyModule(new AXI4Plic( 157 Seq(AddressSet(0x3c000000L, 0x03ffffffL)), 158 sim = !env.FPGAPlatform 159 )) 160 val plicIdentity = AXI4IdentityNode() 161 plic.node := plicIdentity := AXI4UserYanker() := TLToAXI4() := mmioXbar 162 163 lazy val module = new LazyModuleImp(this){ 164 val io = IO(new Bundle{ 165 val extIntrs = Input(UInt(NrExtIntr.W)) 166 // val meip = Input(Vec(NumCores, Bool())) 167 val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None 168 }) 169 val difftestIO0 = IO(new DifftestBundle()) 170 val difftestIO1 = IO(new DifftestBundle()) 171 val difftestIO = Seq(difftestIO0, difftestIO1) 172 173 val trapIO0 = IO(new xiangshan.TrapIO()) 174 val trapIO1 = IO(new xiangshan.TrapIO()) 175 val trapIO = Seq(trapIO0, trapIO1) 176 177 plic.module.io.extra.get.intrVec <> RegNext(RegNext(io.extIntrs)) 178 179 for (i <- 0 until NumCores) { 180 xs_core(i).module.io.hartId := i.U 181 xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i) 182 xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i) 183 // xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip(i))) 184 xs_core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i) 185 l2prefetcher(i).module.io.enable := xs_core(i).module.io.l2_pf_enable 186 l2prefetcher(i).module.io.in <> l2cache(i).module.io 187 } 188 189 difftestIO0 <> xs_core(0).module.difftestIO 190 difftestIO1 <> DontCare 191 trapIO0 <> xs_core(0).module.trapIO 192 trapIO1 <> DontCare 193 194 if (env.DualCore) { 195 difftestIO1 <> xs_core(1).module.difftestIO 196 trapIO1 <> xs_core(1).module.trapIO 197 } 198 // do not let dma AXI signals optimized out 199 dontTouch(dma.out.head._1) 200 dontTouch(extDev.out.head._1) 201 dontTouch(io.extIntrs) 202 } 203 204} 205