xref: /XiangShan/src/main/scala/utils/VerilogAXI4LiteRecord.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 utils
18*720dd621STang Haojin
19*720dd621STang Haojinimport chisel3._
20*720dd621STang Haojinimport chisel3.util._
21*720dd621STang Haojinimport chisel3.experimental.dataview._
22*720dd621STang Haojinimport scala.collection.immutable._
23*720dd621STang Haojin
24*720dd621STang Haojinclass VerilogAXI4LiteRecord(val addrWidth: Int, val dataWidth: Int, val idWidth: Int = 0) extends Record {
25*720dd621STang Haojin  private val axi4LiteBundle = new AXI4LiteBundle(addrWidth, dataWidth, idWidth)
26*720dd621STang Haojin  private def traverseAndMap(data: (String, Data)): SeqMap[String, Data] = {
27*720dd621STang Haojin    data match {
28*720dd621STang Haojin      case (name: String, node: Bundle) => SeqMap.from(
29*720dd621STang Haojin        node.elements.map(x => traverseAndMap(x)).flatten.map {
30*720dd621STang Haojin          case (nodeName, node) => (s"${name.replace("bits", "")}${nodeName}", node)
31*720dd621STang Haojin        }
32*720dd621STang Haojin      )
33*720dd621STang Haojin      case (name: String, node: Data) => SeqMap(name -> node)
34*720dd621STang Haojin    }
35*720dd621STang Haojin  }
36*720dd621STang Haojin  private val outputPattern = "^(aw|w|ar).*".r
37*720dd621STang Haojin  private val elems = traverseAndMap("", axi4LiteBundle) map { case (name, node) => name match {
38*720dd621STang Haojin    case outputPattern(_) => (name, Output(node))
39*720dd621STang Haojin    case _: String        => (name, Input (node))
40*720dd621STang Haojin  }} map { case (name, node) => name match {
41*720dd621STang Haojin    case s"${_}ready" => (name, Flipped(node))
42*720dd621STang Haojin    case _: String    => (name, node)
43*720dd621STang Haojin  }}
44*720dd621STang Haojin  def elements: SeqMap[String, Data] = elems
45*720dd621STang Haojin}
46*720dd621STang Haojin
47*720dd621STang Haojinobject VerilogAXI4LiteRecord {
48*720dd621STang Haojin  private val elementsMap: Seq[(VerilogAXI4LiteRecord, AXI4LiteBundle) => (Data, Data)] = {
49*720dd621STang Haojin    val names = (new VerilogAXI4LiteRecord(1, 1, 0)).elements.map(_._1)
50*720dd621STang Haojin    val pattern = "^(aw|w|b|ar|r)(.*)".r
51*720dd621STang Haojin    names.map { name => { (verilog: VerilogAXI4LiteRecord, chisel: AXI4LiteBundle) => {
52*720dd621STang Haojin      val (channel: Record, signal: String) = name match {
53*720dd621STang Haojin        case pattern(prefix, signal) =>
54*720dd621STang Haojin          (chisel.elements(prefix).asInstanceOf[Record], signal)
55*720dd621STang Haojin        case _: String => require(false, "unexpected prefix"); null
56*720dd621STang Haojin      }
57*720dd621STang Haojin      verilog.elements(name) -> channel.elements.applyOrElse(signal,
58*720dd621STang Haojin        channel.elements("bits").asInstanceOf[Record].elements)
59*720dd621STang Haojin    }}}.toSeq
60*720dd621STang Haojin  }
61*720dd621STang Haojin  implicit val axi4View: DataView[VerilogAXI4LiteRecord, AXI4LiteBundle] = DataView[VerilogAXI4LiteRecord, AXI4LiteBundle](
62*720dd621STang Haojin    vab => new AXI4LiteBundle(vab.addrWidth, vab.dataWidth, vab.idWidth), elementsMap: _*
63*720dd621STang Haojin  )
64*720dd621STang Haojin  implicit val axi4View2: DataView[AXI4LiteBundle, VerilogAXI4LiteRecord] =
65*720dd621STang Haojin    axi4View.invert(ab => new VerilogAXI4LiteRecord(ab.addrWidth, ab.dataWidth, ab.idWidth))
66*720dd621STang Haojin}
67