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