1package system 2 3import chipsalliance.rocketchip.config.Parameters 4import device.{AXI4Plic, AXI4Timer, TLTimer} 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.{DataDontCareNode, DebugIdentityNode} 10import utils.XSInfo 11import xiangshan.{DifftestBundle, HasXSLog, HasXSParameter, XSBundle, XSCore} 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} 17import freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode 18import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkParameters, IntSinkPortParameters, IntSinkPortSimple} 19import freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, BusErrors, L1BusErrors} 20 21case class SoCParameters 22( 23 NumCores: Integer = 1, 24 EnableILA: Boolean = false, 25 HasL2Cache: Boolean = false, 26 HasPrefetch: Boolean = false 27) 28 29trait HasSoCParameter extends HasXSParameter{ 30 val soc = top.Parameters.get.socParameters 31 val NumCores = soc.NumCores 32 val EnableILA = soc.EnableILA 33 val HasL2cache = soc.HasL2Cache 34 val HasPrefetch = soc.HasPrefetch 35} 36 37class ILABundle extends Bundle {} 38 39 40class L1CacheErrorInfo extends XSBundle{ 41 val paddr = Valid(UInt(PAddrBits.W)) 42 // for now, we only detect ecc 43 val ecc_error = Valid(Bool()) 44} 45 46class XSL1BusErrors extends BusErrors { 47 val icache = new L1CacheErrorInfo 48 val dcache = new L1CacheErrorInfo 49 override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] = List( 50 Some(icache.paddr, "IBUS", "Icache bus error"), 51 Some(icache.ecc_error, "I_ECC", "Icache ecc error"), 52 Some(dcache.paddr, "DBUS", "Dcache bus error"), 53 Some(dcache.ecc_error, "D_ECC", "Dcache ecc error") 54 ) 55} 56 57class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter { 58 // CPU Cores 59 private val xs_core = Seq.fill(NumCores)(LazyModule(new XSCore())) 60 61 // L1 to L2 network 62 // ------------------------------------------------- 63 private val l2_xbar = Seq.fill(NumCores)(TLXbar()) 64 65 private val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache( 66 CacheParameters( 67 level = 2, 68 ways = L2NWays, 69 sets = L2NSets, 70 blockBytes = L2BlockSize, 71 beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8 72 cacheName = s"L2" 73 ), 74 InclusiveCacheMicroParameters( 75 writeBytes = 32 76 ) 77 ))) 78 79 private val l2prefetcher = Seq.fill(NumCores)(LazyModule(new L2Prefetcher())) 80 81 // L2 to L3 network 82 // ------------------------------------------------- 83 private val l3_xbar = TLXbar() 84 85 private val l3_node = LazyModule(new InclusiveCache( 86 CacheParameters( 87 level = 3, 88 ways = L3NWays, 89 sets = L3NSets, 90 blockBytes = L3BlockSize, 91 beatBytes = L2BusWidth / 8, 92 cacheName = "L3" 93 ), 94 InclusiveCacheMicroParameters( 95 writeBytes = 32 96 ) 97 )).node 98 99 // L3 to memory network 100 // ------------------------------------------------- 101 private val memory_xbar = TLXbar() 102 private val mmioXbar = TLXbar() 103 104 // only mem, dma and extDev are visible externally 105 val mem = Seq.fill(L3NBanks)(AXI4IdentityNode()) 106 val dma = AXI4IdentityNode() 107 val extDev = AXI4IdentityNode() 108 109 // connections 110 // ------------------------------------------------- 111 for (i <- 0 until NumCores) { 112 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.dcache.clientNode 113 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).l1pluscache.clientNode 114 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := xs_core(i).ptw.node 115 l2_xbar(i) := TLBuffer() := DebugIdentityNode() := l2prefetcher(i).clientNode 116 117 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).memBlock.uncache.clientNode 118 mmioXbar := TLBuffer() := DebugIdentityNode() := xs_core(i).frontend.instrUncache.clientNode 119 l2cache(i).node := DataDontCareNode(a = true, b = true) := TLBuffer() := DebugIdentityNode() := l2_xbar(i) 120 l3_xbar := TLBuffer() := DebugIdentityNode() := l2cache(i).node 121 } 122 123 // DMA should not go to MMIO 124 val mmioRange = AddressSet(base = 0x0000000000L, mask = 0x007fffffffL) 125 // AXI4ToTL needs a TLError device to route error requests, 126 // add one here to make it happy. 127 val tlErrorParams = DevNullParams( 128 address = Seq(mmioRange), 129 maxAtomic = 8, 130 maxTransfer = 64) 131 val tlError = LazyModule(new TLError(params = tlErrorParams, beatBytes = L2BusWidth / 8)) 132 private val tlError_xbar = TLXbar() 133 tlError_xbar := 134 AXI4ToTL() := 135 AXI4UserYanker(Some(1)) := 136 AXI4Fragmenter() := 137 AXI4IdIndexer(1) := 138 dma 139 tlError.node := tlError_xbar 140 141 l3_xbar := 142 TLBuffer() := 143 DebugIdentityNode() := 144 tlError_xbar 145 146 val bankedNode = 147 BankBinder(L3NBanks, L3BlockSize) :*= l3_node :*= TLBuffer() :*= DebugIdentityNode() :*= l3_xbar 148 149 for(i <- 0 until L3NBanks) { 150 mem(i) := 151 AXI4UserYanker() := 152 TLToAXI4() := 153 TLWidthWidget(L3BusWidth / 8) := 154 TLCacheCork() := 155 bankedNode 156 } 157 158 private val clint = LazyModule(new TLTimer( 159 Seq(AddressSet(0x38000000L, 0x0000ffffL)), 160 sim = !env.FPGAPlatform 161 )) 162 163 clint.node := mmioXbar 164 extDev := AXI4UserYanker() := TLToAXI4() := mmioXbar 165 166 val fakeTreeNode = new GenericLogicalTreeNode 167 168 val beu = LazyModule( 169 new BusErrorUnit(new XSL1BusErrors(), BusErrorUnitParams(0x38010000), fakeTreeNode)) 170 beu.node := mmioXbar 171 172 class BeuSinkNode()(implicit p: Parameters) extends LazyModule { 173 val intSinkNode = IntSinkNode(IntSinkPortSimple()) 174 lazy val module = new LazyModuleImp(this){ 175 val interrupt = IO(Output(Bool())) 176 interrupt := intSinkNode.in.head._1.head 177 } 178 } 179 val beuSink = LazyModule(new BeuSinkNode()) 180 beuSink.intSinkNode := beu.intNode 181 182 val plic = LazyModule(new AXI4Plic( 183 Seq(AddressSet(0x3c000000L, 0x03ffffffL)), 184 sim = !env.FPGAPlatform 185 )) 186 plic.node := AXI4UserYanker() := TLToAXI4() := mmioXbar 187 188 lazy val module = new LazyModuleImp(this){ 189 val io = IO(new Bundle{ 190 val extIntrs = Input(UInt(NrExtIntr.W)) 191 // val meip = Input(Vec(NumCores, Bool())) 192 val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None 193 }) 194 val difftestIO0 = IO(new DifftestBundle()) 195 val difftestIO1 = IO(new DifftestBundle()) 196 val difftestIO = Seq(difftestIO0, difftestIO1) 197 198 val trapIO0 = IO(new xiangshan.TrapIO()) 199 val trapIO1 = IO(new xiangshan.TrapIO()) 200 val trapIO = Seq(trapIO0, trapIO1) 201 202 beu.module.io.errors.icache <> DontCare 203 beu.module.io.errors.dcache <> DontCare 204 plic.module.io.extra.get.intrVec <> RegNext(beuSink.module.interrupt) 205 206 for (i <- 0 until NumCores) { 207 xs_core(i).module.io.hartId := i.U 208 xs_core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i) 209 xs_core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i) 210 // xs_core(i).module.io.externalInterrupt.meip := RegNext(RegNext(io.meip(i))) 211 xs_core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i) 212 l2prefetcher(i).module.io.enable := RegNext(xs_core(i).module.io.l2_pf_enable) 213 l2prefetcher(i).module.io.in <> l2cache(i).module.io 214 } 215 216 difftestIO0 <> xs_core(0).module.difftestIO 217 difftestIO1 <> DontCare 218 trapIO0 <> xs_core(0).module.trapIO 219 trapIO1 <> DontCare 220 221 if (env.DualCore) { 222 difftestIO1 <> xs_core(1).module.difftestIO 223 trapIO1 <> xs_core(1).module.trapIO 224 } 225 // do not let dma AXI signals optimized out 226 dontTouch(dma.out.head._1) 227 dontTouch(extDev.out.head._1) 228 dontTouch(io.extIntrs) 229 } 230 231} 232