1package system 2 3import chipsalliance.rocketchip.config.Parameters 4import device.{AXI4Timer, TLTimer} 5import chisel3._ 6import chisel3.util._ 7import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp} 8import freechips.rocketchip.tilelink.{TLBuffer, TLFuzzer, TLIdentityNode, TLXbar} 9import utils.DebugIdentityNode 10import xiangshan.{HasXSParameter, XSCore} 11import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters} 12import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, AddressSet} 13import freechips.rocketchip.tilelink.{TLBundleParameters, TLCacheCork, TLBuffer, TLClientNode, TLIdentityNode, TLXbar, TLWidthWidget, TLFilter, TLToAXI4} 14import freechips.rocketchip.devices.tilelink.{TLError, DevNullParams} 15import freechips.rocketchip.amba.axi4.{AXI4ToTL, AXI4IdentityNode, AXI4UserYanker, AXI4Fragmenter, AXI4IdIndexer, AXI4Deinterleaver} 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 = 8 65 ) 66 ))) 67 68 // L2 to L3 network 69 // ------------------------------------------------- 70 private val l3_xbar = TLXbar() 71 72 private val l3_banks = (0 until L3NBanks) map (i => 73 LazyModule(new InclusiveCache( 74 CacheParameters( 75 level = 3, 76 ways = L3NWays, 77 sets = L3NSets, 78 blockBytes = L3BlockSize, 79 beatBytes = L2BusWidth / 8, 80 cacheName = s"L3_$i" 81 ), 82 InclusiveCacheMicroParameters( 83 writeBytes = 8 84 ) 85 ))) 86 87 // L3 to memory network 88 // ------------------------------------------------- 89 private val memory_xbar = TLXbar() 90 private val mmioXbar = TLXbar() 91 92 // only mem, dma and extDev are visible externally 93 val mem = Seq.fill(L3NBanks)(AXI4IdentityNode()) 94 val dma = AXI4IdentityNode() 95 val extDev = AXI4IdentityNode() 96 97 // connections 98 // ------------------------------------------------- 99 for (i <- 0 until NumCores) { 100 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).dcache.clientNode 101 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).l1pluscache.clientNode 102 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).ptw.node 103 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).uncache.clientNode 104 l2cache(i).node := TLBuffer() := DebugIdentityNode() := l2_xbar(i) 105 l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node 106 } 107 108 // DMA should not go to MMIO 109 val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL) 110 // AXI4ToTL needs a TLError device to route error requests, 111 // add one here to make it happy. 112 val tlErrorParams = DevNullParams( 113 address = Seq(mmioRange), 114 maxAtomic = 8, 115 maxTransfer = 64) 116 val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8)) 117 private val tlError_xbar = TLXbar() 118 tlError_xbar := 119 AXI4ToTL() := 120 AXI4UserYanker(Some(1)) := 121 AXI4Fragmenter() := 122 AXI4IdIndexer(1) := 123 dma 124 tlError.node := tlError_xbar 125 126 l3_xbar := 127 TLBuffer() := 128 DebugIdentityNode() := 129 tlError_xbar 130 131 def bankFilter(bank: Int) = AddressSet( 132 base = bank * L3BlockSize, 133 mask = ~BigInt((L3NBanks -1) * L3BlockSize)) 134 135 for(i <- 0 until L3NBanks) { 136 val filter = TLFilter(TLFilter.mSelectIntersect(bankFilter(i))) 137 l3_banks(i).node := TLBuffer() := DebugIdentityNode() := filter := l3_xbar 138 } 139 140 for(i <- 0 until L3NBanks) { 141 mem(i) := 142 AXI4UserYanker() := 143 TLToAXI4() := 144 TLWidthWidget(L3BusWidth / 8) := 145 TLCacheCork() := 146 l3_banks(i).node 147 } 148 149 private val clint = LazyModule(new TLTimer( 150 Seq(AddressSet(0x38000000L, 0x0000ffffL)), 151 sim = !env.FPGAPlatform 152 )) 153 154 clint.node := mmioXbar 155 extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar 156 157 lazy val module = new LazyModuleImp(this){ 158 val io = IO(new Bundle{ 159 val meip = Input(Bool()) 160 val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None 161 }) 162 for (i <- 0 until NumCores) { 163 xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip 164 xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip 165 xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip)) 166 } 167 // do not let dma AXI signals optimized out 168 chisel3.dontTouch(dma.out.head._1) 169 chisel3.dontTouch(extDev.out.head._1) 170 } 171 172} 173