xref: /XiangShan/src/main/scala/device/imsic_axi_top.scala (revision 9143e23274f936384a22f97745fbf54c36c7d141)
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