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