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() := xs_core(i).l2Prefetcher.clientNode 106 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := l2prefetcher(i).clientNode 107 l2prefetcher(i).module.io.in <> l2cache(i).module.io 108 109 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.uncache.clientNode 110 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).frontend.instrUncache.clientNode 111 l2cache(i).node := DataDontCareNode(a = true, b = true) := TLBuffer() := DebugIdentityNode() := l2_xbar(i) 112 l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node 113 } 114 115 // DMA should not go to MMIO 116 val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL) 117 // AXI4ToTL needs a TLError device to route error requests, 118 // add one here to make it happy. 119 val tlErrorParams = DevNullParams( 120 address = Seq(mmioRange), 121 maxAtomic = 8, 122 maxTransfer = 64) 123 val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8)) 124 private val tlError_xbar = TLXbar() 125 tlError_xbar := 126 AXI4ToTL() := 127 AXI4UserYanker(Some(1)) := 128 AXI4Fragmenter() := 129 AXI4IdIndexer(1) := 130 dma 131 tlError.node := tlError_xbar 132 133 l3_xbar := 134 TLBuffer() := 135 DebugIdentityNode() := 136 tlError_xbar 137 138 val bankedNode = 139 BankBinder(L3NBanks, L3BlockSize) :*= l3_node :*= TLBuffer() :*= DebugIdentityNode() :*= l3_xbar 140 141 for(i <- 0 until L3NBanks) { 142 mem(i) := 143 AXI4UserYanker() := 144 TLToAXI4() := 145 TLWidthWidget(L3BusWidth / 8) := 146 TLCacheCork() := 147 bankedNode 148 } 149 150 private val clint = LazyModule(new TLTimer( 151 Seq(AddressSet(0x38000000L, 0x0000ffffL)), 152 sim = !env.FPGAPlatform 153 )) 154 155 clint.node := mmioXbar 156 extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar 157 158 val plic = LazyModule(new AXI4Plic( 159 Seq(AddressSet(0x3c000000L, 0x03ffffffL)), 160 sim = !env.FPGAPlatform 161 )) 162 val plicIdentity = AXI4IdentityNode() 163 plic.node := plicIdentity := AXI4UserYanker() := TLToAXI4() := mmioXbar 164 165 lazy val module = new LazyModuleImp(this){ 166 val io = IO(new Bundle{ 167 val extIntrs = Input(UInt(NrExtIntr.W)) 168 // val meip = Input(Vec(NumCores, Bool())) 169 val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None 170 }) 171 val difftestIO0 = IO(new DifftestBundle()) 172 val difftestIO1 = IO(new DifftestBundle()) 173 val difftestIO = Seq(difftestIO0, difftestIO1) 174 175 val trapIO0 = IO(new xiangshan.TrapIO()) 176 val trapIO1 = IO(new xiangshan.TrapIO()) 177 val trapIO = Seq(trapIO0, trapIO1) 178 179 plic.module.io.extra.get.intrVec <> RegNext(RegNext(io.extIntrs)) 180 181 for (i <- 0 until NumCores) { 182 xs_core(i).module.io.hartId := i.U 183 xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i) 184 xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i) 185 // xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip(i))) 186 xs_core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i) 187 l2prefetcher(i).module.io.enable := xs_core(i).module.io.l2_pf_enable 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