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, 699143e232SJiuyue Ma baseAddress: (BigInt, BigInt), /* (M-mode, S/VS-mode) */ 709143e232SJiuyue 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 839143e232SJiuyue Ma private val m_base = baseAddress._1; 849143e232SJiuyue Ma private val m_size = maxHarts * 0x1000; 859143e232SJiuyue Ma private val s_base = baseAddress._2; 869143e232SJiuyue Ma private val s_size = maxHarts * 0x8000; 879143e232SJiuyue Ma 889143e232SJiuyue Ma println(f"IMSIC: address-mapping for ${maxHarts} HARTs") 899143e232SJiuyue Ma println(f"IMSIC: M-mode: [0x${m_base}%08X, 0x${m_base + m_size - 1}%08X]") 909143e232SJiuyue Ma println(f"IMSIC: S/VS-mode: [0x${s_base}%08X, 0x${s_base + s_size - 1}%08X]") 919143e232SJiuyue Ma 929143e232SJiuyue Ma private val axi4nodes = Seq( 939143e232SJiuyue Ma AXI4SlaveNode(Seq(AXI4SlavePortParameters( 94720dd621STang Haojin Seq(AXI4SlaveParameters( 959143e232SJiuyue 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 1029143e232SJiuyue Ma ))), 1039143e232SJiuyue Ma AXI4SlaveNode(Seq(AXI4SlavePortParameters( 1049143e232SJiuyue Ma Seq(AXI4SlaveParameters( 1059143e232SJiuyue Ma Seq(AddressSet(s_base, s_size - 1)), 1069143e232SJiuyue Ma regionType = RegionType.UNCACHED, 1079143e232SJiuyue Ma supportsWrite = TransferSizes(1, 4), 1089143e232SJiuyue Ma supportsRead = TransferSizes(1, 4), 1099143e232SJiuyue Ma interleavedId = Some(0) 1109143e232SJiuyue Ma )), 1119143e232SJiuyue Ma beatBytes = 4 1129143e232SJiuyue Ma )))) 1139143e232SJiuyue Ma 1149143e232SJiuyue Ma val tl = Option.when(useTL) { 1159143e232SJiuyue Ma val tlnodes = Seq.fill(2)(TLClientNode(Seq(TLMasterPortParameters.v1( 1169143e232SJiuyue Ma clients = Seq(TLMasterParameters.v1( 1179143e232SJiuyue Ma "tl", 118*468d6533STang Haojin sourceId = IdRange(0, 16) 1199143e232SJiuyue 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 1339143e232SJiuyue 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 1399143e232SJiuyue Ma val axiMasterNode = Option.when(!useTL) { 1409143e232SJiuyue Ma val node = AXI4MasterNode(Seq(AXI4MasterPortParameters( 1419143e232SJiuyue Ma Seq(AXI4MasterParameters( 1429143e232SJiuyue Ma name = "s_axi_", 1439143e232SJiuyue Ma id = IdRange(0, 1 << AXI_ID_WIDTH) 1449143e232SJiuyue Ma )) 1459143e232SJiuyue Ma ))) 1469143e232SJiuyue Ma val xbar = AXI4Xbar(TLArbiter.lowestIndexFirst) 1479143e232SJiuyue Ma axi4nodes.foreach { _ := xbar } 1489143e232SJiuyue Ma xbar := node 1499143e232SJiuyue Ma node 1509143e232SJiuyue Ma } 1519143e232SJiuyue 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 1589143e232SJiuyue 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 1739143e232SJiuyue Ma axi4lite.foreach { 1749143e232SJiuyue Ma _.viewAs[AXI4LiteBundle].connectToAXI4(wrapper.axiMasterNode.get.out.head._1) 1759143e232SJiuyue Ma } 176720dd621STang Haojin 177720dd621STang Haojin // connection: axi4 1789143e232SJiuyue Ma wrapper.axi4nodes.map(_.in.head._1) zip 1799143e232SJiuyue 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