1720dd621STang Haojin/*************************************************************************************** 2720dd621STang Haojin* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3720dd621STang Haojin* Copyright (c) 2024 Institute of Computing Technology, Chinese Academy of Sciences 4720dd621STang Haojin* 5720dd621STang Haojin* XiangShan is licensed under Mulan PSL v2. 6720dd621STang Haojin* You can use this software according to the terms and conditions of the Mulan PSL v2. 7720dd621STang Haojin* You may obtain a copy of Mulan PSL v2 at: 8720dd621STang Haojin* http://license.coscl.org.cn/MulanPSL2 9720dd621STang Haojin* 10720dd621STang Haojin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11720dd621STang Haojin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12720dd621STang Haojin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13720dd621STang Haojin* 14720dd621STang Haojin* See the Mulan PSL v2 for more details. 15720dd621STang Haojin***************************************************************************************/ 16720dd621STang Haojin 17720dd621STang Haojinpackage device 18720dd621STang Haojin 19720dd621STang Haojinimport chisel3._ 20720dd621STang Haojinimport chisel3.util._ 21720dd621STang Haojinimport chisel3.experimental.dataview._ 22720dd621STang Haojinimport org.chipsalliance.cde.config.Parameters 23720dd621STang Haojinimport freechips.rocketchip.diplomacy._ 24720dd621STang Haojinimport freechips.rocketchip.amba.axi4._ 25720dd621STang Haojinimport freechips.rocketchip.tilelink._ 26720dd621STang Haojinimport utils.{AXI4LiteBundle, VerilogAXI4LiteRecord} 27720dd621STang Haojin 28720dd621STang Haojinclass imsic_axi_top( 29720dd621STang Haojin AXI_ID_WIDTH: Int = 5, 30720dd621STang Haojin AXI_ADDR_WIDTH: Int = 32, 31720dd621STang Haojin NR_INTP_FILES: Int = 7, 32720dd621STang Haojin NR_HARTS: Int = 1, 33720dd621STang Haojin NR_SRC: Int = 256, 34720dd621STang Haojin SETIP_KEEP_CYCLES: Int = 8 35720dd621STang Haojin) extends BlackBox(Map( 36720dd621STang Haojin "AXI_ID_WIDTH" -> AXI_ID_WIDTH, 37720dd621STang Haojin "AXI_ADDR_WIDTH" -> AXI_ADDR_WIDTH, 38720dd621STang Haojin "NR_INTP_FILES" -> NR_INTP_FILES, 39720dd621STang Haojin "NR_HARTS" -> NR_HARTS, 40720dd621STang Haojin "NR_SRC" -> NR_SRC, 41720dd621STang Haojin "SETIP_KEEP_CYCLES" -> SETIP_KEEP_CYCLES 42720dd621STang Haojin)) with HasBlackBoxResource { 43720dd621STang Haojin private val NR_SRC_WIDTH = log2Ceil(NR_SRC) 44720dd621STang Haojin private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS) 45720dd621STang Haojin private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES) 46720dd621STang Haojin private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH 47720dd621STang Haojin val io = IO(new Bundle { 48720dd621STang Haojin // crg 49720dd621STang Haojin val axi_clk = Input(Clock()) 50720dd621STang Haojin val axi_rstn = Input(AsyncReset()) 51720dd621STang Haojin val fifo_rstn = Input(AsyncReset()) 52720dd621STang Haojin // bus to access the m interrupt file 53720dd621STang Haojin val m_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)) 54720dd621STang Haojin // bus to access the s interrupt file 55720dd621STang Haojin val s_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)) 56720dd621STang Haojin // imsic_csr_top 57720dd621STang Haojin val o_msi_info = Output(UInt(MSI_INFO_WIDTH.W)) 58720dd621STang Haojin val o_msi_info_vld = Output(Bool()) 59720dd621STang Haojin }) 60f835884fSHaojin Tang addResource("/aia/src/rtl/imsic/imsic_axi_top.sv") 61f835884fSHaojin Tang addResource("/aia/src/rtl/imsic/imsic_axi2reg.sv") 62f835884fSHaojin Tang addResource("/aia/src/rtl/imsic/imsic_regmap.sv") 63f835884fSHaojin Tang addResource("/aia/src/rtl/imsic/common/generic_fifo_dc_gray.sv") 64f835884fSHaojin Tang addResource("/aia/src/rtl/imsic/common/generic_dpram.sv") 65720dd621STang Haojin} 66720dd621STang Haojin 67720dd621STang Haojinclass imsic_bus_top( 68720dd621STang Haojin useTL: Boolean = false, 69*9143e232SJiuyue Ma baseAddress: (BigInt, BigInt), /* (M-mode, S/VS-mode) */ 70*9143e232SJiuyue Ma maxHarts: Int = 512, 71720dd621STang Haojin AXI_ID_WIDTH: Int = 5, 72720dd621STang Haojin AXI_ADDR_WIDTH: Int = 32, 73720dd621STang Haojin NR_INTP_FILES: Int = 7, 74720dd621STang Haojin NR_HARTS: Int = 1, 75720dd621STang Haojin NR_SRC: Int = 256, 76720dd621STang Haojin SETIP_KEEP_CYCLES: Int = 8 77720dd621STang Haojin)(implicit p: Parameters) extends LazyModule { 78720dd621STang Haojin private val NR_SRC_WIDTH = log2Ceil(NR_SRC) 79720dd621STang Haojin private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS) 80720dd621STang Haojin private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES) 81720dd621STang Haojin private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH 82720dd621STang Haojin 83*9143e232SJiuyue Ma private val m_base = baseAddress._1; 84*9143e232SJiuyue Ma private val m_size = maxHarts * 0x1000; 85*9143e232SJiuyue Ma private val s_base = baseAddress._2; 86*9143e232SJiuyue Ma private val s_size = maxHarts * 0x8000; 87*9143e232SJiuyue Ma 88*9143e232SJiuyue Ma println(f"IMSIC: address-mapping for ${maxHarts} HARTs") 89*9143e232SJiuyue Ma println(f"IMSIC: M-mode: [0x${m_base}%08X, 0x${m_base + m_size - 1}%08X]") 90*9143e232SJiuyue Ma println(f"IMSIC: S/VS-mode: [0x${s_base}%08X, 0x${s_base + s_size - 1}%08X]") 91*9143e232SJiuyue Ma 92*9143e232SJiuyue Ma private val axi4nodes = Seq( 93*9143e232SJiuyue Ma AXI4SlaveNode(Seq(AXI4SlavePortParameters( 94720dd621STang Haojin Seq(AXI4SlaveParameters( 95*9143e232SJiuyue Ma Seq(AddressSet(m_base, m_size - 1)), 96720dd621STang Haojin regionType = RegionType.UNCACHED, 97720dd621STang Haojin supportsWrite = TransferSizes(1, 4), 98720dd621STang Haojin supportsRead = TransferSizes(1, 4), 99720dd621STang Haojin interleavedId = Some(0) 100720dd621STang Haojin )), 101720dd621STang Haojin beatBytes = 4 102*9143e232SJiuyue Ma ))), 103*9143e232SJiuyue Ma AXI4SlaveNode(Seq(AXI4SlavePortParameters( 104*9143e232SJiuyue Ma Seq(AXI4SlaveParameters( 105*9143e232SJiuyue Ma Seq(AddressSet(s_base, s_size - 1)), 106*9143e232SJiuyue Ma regionType = RegionType.UNCACHED, 107*9143e232SJiuyue Ma supportsWrite = TransferSizes(1, 4), 108*9143e232SJiuyue Ma supportsRead = TransferSizes(1, 4), 109*9143e232SJiuyue Ma interleavedId = Some(0) 110*9143e232SJiuyue Ma )), 111*9143e232SJiuyue Ma beatBytes = 4 112*9143e232SJiuyue Ma )))) 113*9143e232SJiuyue Ma 114*9143e232SJiuyue Ma val tl = Option.when(useTL) { 115*9143e232SJiuyue Ma val tlnodes = Seq.fill(2)(TLClientNode(Seq(TLMasterPortParameters.v1( 116*9143e232SJiuyue Ma clients = Seq(TLMasterParameters.v1( 117*9143e232SJiuyue Ma "tl", 118*9143e232SJiuyue Ma sourceId = IdRange(0, 1) 119*9143e232SJiuyue Ma )) 120720dd621STang Haojin )))) 121720dd621STang Haojin axi4nodes zip tlnodes foreach { case (axi4node, tlnode) => 122720dd621STang Haojin axi4node := 123720dd621STang Haojin AXI4IdIndexer(AXI_ID_WIDTH) := 124720dd621STang Haojin AXI4Buffer() := 125720dd621STang Haojin AXI4Buffer() := 126720dd621STang Haojin AXI4UserYanker(Some(1)) := 127720dd621STang Haojin TLToAXI4() := 128720dd621STang Haojin TLWidthWidget(4) := 129720dd621STang Haojin TLFIFOFixer() := 130720dd621STang Haojin tlnode 131720dd621STang Haojin } 132720dd621STang Haojin 133*9143e232SJiuyue Ma tlnodes 134720dd621STang Haojin } 135720dd621STang Haojin 136720dd621STang Haojin val tl_m = tl.map(x => InModuleBody(x(0).makeIOs())) 137720dd621STang Haojin val tl_s = tl.map(x => InModuleBody(x(1).makeIOs())) 138720dd621STang Haojin 139*9143e232SJiuyue Ma val axiMasterNode = Option.when(!useTL) { 140*9143e232SJiuyue Ma val node = AXI4MasterNode(Seq(AXI4MasterPortParameters( 141*9143e232SJiuyue Ma Seq(AXI4MasterParameters( 142*9143e232SJiuyue Ma name = "s_axi_", 143*9143e232SJiuyue Ma id = IdRange(0, 1 << AXI_ID_WIDTH) 144*9143e232SJiuyue Ma )) 145*9143e232SJiuyue Ma ))) 146*9143e232SJiuyue Ma val xbar = AXI4Xbar(TLArbiter.lowestIndexFirst) 147*9143e232SJiuyue Ma axi4nodes.foreach { _ := xbar } 148*9143e232SJiuyue Ma xbar := node 149*9143e232SJiuyue Ma node 150*9143e232SJiuyue Ma } 151*9143e232SJiuyue Ma 152720dd621STang Haojin class imsic_bus_top_imp(wrapper: imsic_bus_top) extends LazyModuleImp(wrapper) { 153720dd621STang Haojin // imsic csr top io 154720dd621STang Haojin val o_msi_info = IO(Output(UInt(MSI_INFO_WIDTH.W))) 155720dd621STang Haojin val o_msi_info_vld = IO(Output(Bool())) 156720dd621STang Haojin 157720dd621STang Haojin // axi4lite io 158*9143e232SJiuyue Ma val axi4lite = Option.when(!useTL)(IO(Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)))) 159720dd621STang Haojin 160720dd621STang Haojin // imsic axi top 161720dd621STang Haojin val u_imsic_axi_top = Module(new imsic_axi_top) 162720dd621STang Haojin 163720dd621STang Haojin // connection: crg 164720dd621STang Haojin u_imsic_axi_top.io.axi_clk := clock 165720dd621STang Haojin u_imsic_axi_top.io.axi_rstn := (~reset.asBool).asAsyncReset 166720dd621STang Haojin u_imsic_axi_top.io.fifo_rstn := (~reset.asBool).asAsyncReset // TODO: axi_rstn & sw_rstn 167720dd621STang Haojin 168720dd621STang Haojin // connection: imsic csr top 169720dd621STang Haojin o_msi_info := u_imsic_axi_top.io.o_msi_info 170720dd621STang Haojin o_msi_info_vld := u_imsic_axi_top.io.o_msi_info_vld 171720dd621STang Haojin 172720dd621STang Haojin // connection: axi4lite 173*9143e232SJiuyue Ma axi4lite.foreach { 174*9143e232SJiuyue Ma _.viewAs[AXI4LiteBundle].connectToAXI4(wrapper.axiMasterNode.get.out.head._1) 175*9143e232SJiuyue Ma } 176720dd621STang Haojin 177720dd621STang Haojin // connection: axi4 178*9143e232SJiuyue Ma wrapper.axi4nodes.map(_.in.head._1) zip 179*9143e232SJiuyue Ma Seq(u_imsic_axi_top.io.m_s, u_imsic_axi_top.io.s_s) foreach { 180720dd621STang Haojin case (axi4, axi4lite) => axi4lite.viewAs[AXI4LiteBundle].connectFromAXI4(axi4) 181720dd621STang Haojin } 182720dd621STang Haojin } 183720dd621STang Haojin 184720dd621STang Haojin lazy val module = new imsic_bus_top_imp(this) 185720dd621STang Haojin} 186