1/*************************************************************************************** 2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3* Copyright (c) 2024 Institute of Computing Technology, Chinese Academy of Sciences 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package device 18 19import chisel3._ 20import chisel3.util._ 21import chisel3.experimental.dataview._ 22import org.chipsalliance.cde.config.Parameters 23import freechips.rocketchip.diplomacy._ 24import freechips.rocketchip.amba.axi4._ 25import freechips.rocketchip.tilelink._ 26import utils.{AXI4LiteBundle, VerilogAXI4LiteRecord} 27 28class imsic_axi_top( 29 AXI_ID_WIDTH: Int = 5, 30 AXI_ADDR_WIDTH: Int = 32, 31 NR_INTP_FILES: Int = 7, 32 NR_HARTS: Int = 1, 33 NR_SRC: Int = 256, 34 SETIP_KEEP_CYCLES: Int = 8 35) extends BlackBox(Map( 36 "AXI_ID_WIDTH" -> AXI_ID_WIDTH, 37 "AXI_ADDR_WIDTH" -> AXI_ADDR_WIDTH, 38 "NR_INTP_FILES" -> NR_INTP_FILES, 39 "NR_HARTS" -> NR_HARTS, 40 "NR_SRC" -> NR_SRC, 41 "SETIP_KEEP_CYCLES" -> SETIP_KEEP_CYCLES 42)) with HasBlackBoxResource { 43 private val NR_SRC_WIDTH = log2Ceil(NR_SRC) 44 private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS) 45 private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES) 46 private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH 47 val io = IO(new Bundle { 48 // crg 49 val axi_clk = Input(Clock()) 50 val axi_rstn = Input(AsyncReset()) 51 val fifo_rstn = Input(AsyncReset()) 52 // bus to access the m interrupt file 53 val m_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)) 54 // bus to access the s interrupt file 55 val s_s = Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)) 56 // imsic_csr_top 57 val o_msi_info = Output(UInt(MSI_INFO_WIDTH.W)) 58 val o_msi_info_vld = Output(Bool()) 59 }) 60 addResource("/aia/src/rtl/imsic/imsic_axi_top.v") 61 addResource("/aia/src/rtl/imsic/imsic_axi2reg.v") 62 addResource("/aia/src/rtl/imsic/imsic_regmap.v") 63 addResource("/aia/src/rtl/imsic/common/generic_fifo_dc_gray.v") 64 addResource("/aia/src/rtl/imsic/common/generic_dpram.v") 65} 66 67class imsic_bus_top( 68 useTL: Boolean = false, 69 AXI_ID_WIDTH: Int = 5, 70 AXI_ADDR_WIDTH: Int = 32, 71 NR_INTP_FILES: Int = 7, 72 NR_HARTS: Int = 1, 73 NR_SRC: Int = 256, 74 SETIP_KEEP_CYCLES: Int = 8 75)(implicit p: Parameters) extends LazyModule { 76 private val NR_SRC_WIDTH = log2Ceil(NR_SRC) 77 private val NR_HARTS_WIDTH = if (NR_HARTS == 1) 1 else log2Ceil(NR_HARTS) 78 private val INTP_FILE_WIDTH = log2Ceil(NR_INTP_FILES) 79 private val MSI_INFO_WIDTH = NR_HARTS_WIDTH + INTP_FILE_WIDTH + NR_SRC_WIDTH 80 81 private val tuple_axi4_tl = Option.when(useTL) { 82 val tlnodes = Seq.fill(2)(TLClientNode(Seq(TLMasterPortParameters.v1( 83 clients = Seq(TLMasterParameters.v1( 84 "tl", 85 sourceId = IdRange(0, 1) 86 )) 87 )))) 88 val axi4nodes = Seq.fill(2)(AXI4SlaveNode(Seq(AXI4SlavePortParameters( 89 Seq(AXI4SlaveParameters( 90 Seq(AddressSet(0x0, (1L << AXI_ADDR_WIDTH) - 1)), 91 regionType = RegionType.UNCACHED, 92 supportsWrite = TransferSizes(1, 4), 93 supportsRead = TransferSizes(1, 4), 94 interleavedId = Some(0) 95 )), 96 beatBytes = 4 97 )))) 98 axi4nodes zip tlnodes foreach { case (axi4node, tlnode) => 99 axi4node := 100 AXI4IdIndexer(AXI_ID_WIDTH) := 101 AXI4Buffer() := 102 AXI4Buffer() := 103 AXI4UserYanker(Some(1)) := 104 TLToAXI4() := 105 TLWidthWidget(4) := 106 TLFIFOFixer() := 107 tlnode 108 } 109 110 (axi4nodes, tlnodes) 111 } 112 113 val axi4 = tuple_axi4_tl.map(_._1) 114 private val tl = tuple_axi4_tl.map(_._2) 115 val tl_m = tl.map(x => InModuleBody(x(0).makeIOs())) 116 val tl_s = tl.map(x => InModuleBody(x(1).makeIOs())) 117 118 class imsic_bus_top_imp(wrapper: imsic_bus_top) extends LazyModuleImp(wrapper) { 119 // imsic csr top io 120 val o_msi_info = IO(Output(UInt(MSI_INFO_WIDTH.W))) 121 val o_msi_info_vld = IO(Output(Bool())) 122 123 // axi4lite io 124 val m_s = Option.when(!useTL)(IO(Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)))) 125 val s_s = Option.when(!useTL)(IO(Flipped(new VerilogAXI4LiteRecord(AXI_ADDR_WIDTH, 32, AXI_ID_WIDTH)))) 126 127 // imsic axi top 128 val u_imsic_axi_top = Module(new imsic_axi_top) 129 130 // connection: crg 131 u_imsic_axi_top.io.axi_clk := clock 132 u_imsic_axi_top.io.axi_rstn := (~reset.asBool).asAsyncReset 133 u_imsic_axi_top.io.fifo_rstn := (~reset.asBool).asAsyncReset // TODO: axi_rstn & sw_rstn 134 135 // connection: imsic csr top 136 o_msi_info := u_imsic_axi_top.io.o_msi_info 137 o_msi_info_vld := u_imsic_axi_top.io.o_msi_info_vld 138 139 // connection: axi4lite 140 m_s.foreach(_ <> u_imsic_axi_top.io.m_s) 141 s_s.foreach(_ <> u_imsic_axi_top.io.s_s) 142 143 // connection: axi4 144 wrapper.axi4.foreach { axi4 => 145 axi4.map(_.in.head._1) zip Seq(u_imsic_axi_top.io.m_s, u_imsic_axi_top.io.s_s) foreach { 146 case (axi4, axi4lite) => axi4lite.viewAs[AXI4LiteBundle].connectFromAXI4(axi4) 147 } 148 } 149 } 150 151 lazy val module = new imsic_bus_top_imp(this) 152} 153