1package top 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import system._ 7import chisel3.stage.ChiselGeneratorAnnotation 8import chipsalliance.rocketchip.config 9import device.{TLTimer, AXI4Plic} 10import freechips.rocketchip.diplomacy._ 11import freechips.rocketchip.tilelink._ 12import freechips.rocketchip.amba.axi4._ 13import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError} 14import sifive.blocks.inclusivecache._ 15import xiangshan.cache.prefetch.L2Prefetcher 16 17 18abstract class BaseXSSoc()(implicit p: config.Parameters) extends LazyModule with HasSoCParameter { 19 val bankedNode = BankBinder(L3NBanks, L3BlockSize) 20 val peripheralXbar = TLXbar() 21 val l3_xbar = TLXbar() 22} 23 24// We adapt the following three traits from rocket-chip. 25// Source: rocket-chip/src/main/scala/subsystem/Ports.scala 26trait HaveSlaveAXI4Port { 27 this: BaseXSSoc => 28 29 val idBits = 16 30 31 val l3FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters( 32 Seq(AXI4MasterParameters( 33 name = "dma", 34 id = IdRange(0, 1 << idBits) 35 )) 36 ))) 37 private val errorDevice = LazyModule(new TLError( 38 params = DevNullParams( 39 address = Seq(AddressSet(0x0, 0x7fffffffL)), 40 maxAtomic = 8, 41 maxTransfer = 64), 42 beatBytes = L2BusWidth / 8 43 )) 44 private val error_xbar = TLXbar() 45 46 error_xbar := 47 AXI4ToTL() := 48 AXI4UserYanker(Some(1)) := 49 AXI4Fragmenter() := 50 AXI4IdIndexer(1) := 51 l3FrontendAXI4Node 52 errorDevice.node := error_xbar 53 l3_xbar := 54 TLBuffer() := 55 error_xbar 56 57 val dma = InModuleBody { 58 l3FrontendAXI4Node.makeIOs() 59 } 60} 61 62trait HaveAXI4MemPort { 63 this: BaseXSSoc => 64 // 40-bit physical address 65 val memRange = AddressSet(0x00000000L, 0xffffffffffL).subtract(AddressSet(0x0L, 0x7fffffffL)) 66 val memAXI4SlaveNode = AXI4SlaveNode(Seq.tabulate(L3NBanks) { i => 67 AXI4SlavePortParameters( 68 slaves = Seq( 69 AXI4SlaveParameters( 70 address = memRange, 71 regionType = RegionType.UNCACHED, 72 executable = true, 73 supportsRead = TransferSizes(1, L3BlockSize), 74 supportsWrite = TransferSizes(1, L3BlockSize), 75 interleavedId = Some(0) 76 ) 77 ), 78 beatBytes = L3BusWidth / 8 79 ) 80 }) 81 82 memAXI4SlaveNode :=* 83 AXI4UserYanker() :=* 84 AXI4IdIndexer(12) :=* 85 TLToAXI4() :=* 86 TLWidthWidget(L3BusWidth / 8) :=* 87 TLCacheCork() :=* 88 bankedNode 89 90 val memory = InModuleBody { 91 memAXI4SlaveNode.makeIOs() 92 } 93} 94 95 96trait HaveAXI4PeripheralPort { this: BaseXSSoc => 97 // on-chip devices: 0x3800_000 - 0x3fff_ffff 98 val onChipPeripheralRange = AddressSet(0x38000000L, 0x07ffffffL) 99 val peripheralRange = AddressSet(0x0, 0x7fffffff).subtract(onChipPeripheralRange) 100 val peripheralNode = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 101 Seq(AXI4SlaveParameters( 102 address = peripheralRange, 103 regionType = RegionType.UNCACHED, 104 supportsRead = TransferSizes(1, 8), 105 supportsWrite = TransferSizes(1, 8), 106 interleavedId = Some(0) 107 )), 108 beatBytes = 8 109 ))) 110 111 peripheralNode := 112 AXI4UserYanker() := 113 AXI4IdIndexer(14) :=* 114 TLToAXI4() := 115 peripheralXbar 116 117 val peripheral = InModuleBody { 118 peripheralNode.makeIOs() 119 } 120 121} 122 123 124class XSTop()(implicit p: config.Parameters) extends BaseXSSoc() 125 with HaveAXI4MemPort 126 with HaveAXI4PeripheralPort 127 with HaveSlaveAXI4Port 128 { 129 130 println(s"FPGASoC cores: $NumCores banks: $L3NBanks block size: $L3BlockSize bus size: $L3BusWidth") 131 132 val core = Seq.fill(NumCores)(LazyModule(new XSCore())) 133 val l2prefetcher = Seq.fill(NumCores)(LazyModule(new L2Prefetcher())) 134 val l2cache = Seq.fill(NumCores)(LazyModule(new InclusiveCache( 135 CacheParameters( 136 level = 2, 137 ways = L2NWays, 138 sets = L2NSets, 139 blockBytes = L2BlockSize, 140 beatBytes = L1BusWidth / 8, // beatBytes = l1BusDataWidth / 8 141 cacheName = s"L2" 142 ), 143 InclusiveCacheMicroParameters( 144 writeBytes = 32 145 ) 146 ))) 147 val l2xbar = Seq.fill(NumCores)(TLXbar()) 148 149 for (i <- 0 until NumCores) { 150 peripheralXbar := TLBuffer() := core(i).frontend.instrUncache.clientNode 151 peripheralXbar := TLBuffer() := core(i).memBlock.uncache.clientNode 152 l2xbar(i) := TLBuffer() := core(i).memBlock.dcache.clientNode 153 l2xbar(i) := TLBuffer() := core(i).l1pluscache.clientNode 154 l2xbar(i) := TLBuffer() := core(i).ptw.node 155 l2xbar(i) := TLBuffer() := l2prefetcher(i).clientNode 156 l2cache(i).node := TLBuffer() := l2xbar(i) 157 l3_xbar := TLBuffer() := l2cache(i).node 158 } 159 160 private val clint = LazyModule(new TLTimer( 161 Seq(AddressSet(0x38000000L, 0x0000ffffL)), 162 sim = !env.FPGAPlatform 163 )) 164 clint.node := peripheralXbar 165 166 val plic = LazyModule(new AXI4Plic( 167 Seq(AddressSet(0x3c000000L, 0x03ffffffL)), 168 sim = !env.FPGAPlatform 169 )) 170 plic.node := AXI4IdentityNode() := AXI4UserYanker() := TLToAXI4() := peripheralXbar 171 172 val l3cache = LazyModule(new InclusiveCache( 173 CacheParameters( 174 level = 3, 175 ways = L3NWays, 176 sets = L3NSets, 177 blockBytes = L3BlockSize, 178 beatBytes = L2BusWidth / 8, 179 cacheName = "L3" 180 ), 181 InclusiveCacheMicroParameters( 182 writeBytes = 32 183 ) 184 )).node 185 186 bankedNode :*= l3cache :*= TLBuffer() :*= l3_xbar 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 195 plic.module.io.extra.get.intrVec <> RegNext(RegNext(io.extIntrs)) 196 197 for (i <- 0 until NumCores) { 198 core(i).module.io.hartId := i.U 199 core(i).module.io.externalInterrupt.mtip := clint.module.io.mtip(i) 200 core(i).module.io.externalInterrupt.msip := clint.module.io.msip(i) 201 core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i) 202 l2prefetcher(i).module.io.enable := RegNext(core(i).module.io.l2_pf_enable) 203 l2prefetcher(i).module.io.in <> l2cache(i).module.io 204 } 205 206 dontTouch(io.extIntrs) 207 } 208} 209 210object TopMain extends App { 211 override def main(args: Array[String]): Unit = { 212 Parameters.set( 213 args.contains("--dual-core") match { 214 case false => Parameters() 215 case true => Parameters.dualCoreParameters 216 } 217 ) 218 val otherArgs = args.filterNot(_ == "--dual-core") 219 implicit val p = config.Parameters.empty 220 XiangShanStage.execute(otherArgs, Seq( 221 ChiselGeneratorAnnotation(() => { 222 val soc = LazyModule(new XSTop()) 223 soc.module 224 }) 225 )) 226 } 227} 228