xref: /XiangShan/src/main/scala/device/AXI4Memory.scala (revision 3c02ee8f82edea481fa8336c7f54ffc17fafba91)
171784e68SYinan Xu/***************************************************************************************
271784e68SYinan Xu  * Copyright (c) 2020-2022 Institute of Computing Technology, Chinese Academy of Sciences
371784e68SYinan Xu  *
471784e68SYinan Xu  * XiangShan is licensed under Mulan PSL v2.
571784e68SYinan Xu  * You can use this software according to the terms and conditions of the Mulan PSL v2.
671784e68SYinan Xu  * You may obtain a copy of Mulan PSL v2 at:
771784e68SYinan Xu  *          http://license.coscl.org.cn/MulanPSL2
871784e68SYinan Xu  *
971784e68SYinan Xu  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1071784e68SYinan Xu  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1171784e68SYinan Xu  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1271784e68SYinan Xu  *
1371784e68SYinan Xu  * See the Mulan PSL v2 for more details.
1471784e68SYinan Xu  ***************************************************************************************/
1571784e68SYinan Xu
1671784e68SYinan Xupackage device
1771784e68SYinan Xu
1871784e68SYinan Xuimport chipsalliance.rocketchip.config.Parameters
1971784e68SYinan Xuimport chisel3._
2071784e68SYinan Xuimport chisel3.experimental.ExtModule
2171784e68SYinan Xuimport chisel3.util._
2271784e68SYinan Xuimport freechips.rocketchip.amba.axi4.{AXI4MasterNode, AXI4Parameters, AXI4SlaveNode}
2371784e68SYinan Xuimport freechips.rocketchip.diplomacy.{AddressSet, InModuleBody, LazyModule, LazyModuleImp}
2471784e68SYinan Xuimport utils._
25*3c02ee8fSwakafaimport utility._
2671784e68SYinan Xu
2771784e68SYinan Xuclass MemoryRWHelper extends ExtModule with HasExtModuleInline {
2871784e68SYinan Xu  val DataBits = 64
2971784e68SYinan Xu
3071784e68SYinan Xu  val clock = IO(Input(Clock()))
3171784e68SYinan Xu  val reset = IO(Input(Reset()))
3271784e68SYinan Xu  val ren   = IO(Input(Bool()))
3371784e68SYinan Xu  val rIdx  = IO(Input(UInt(DataBits.W)))
3471784e68SYinan Xu  val rdata = IO(Output(UInt(DataBits.W)))
3571784e68SYinan Xu  val wen   = IO(Input(Bool()))
3671784e68SYinan Xu  val wIdx  = IO(Input(UInt(DataBits.W)))
3771784e68SYinan Xu  val wdata = IO(Input(UInt(DataBits.W)))
3871784e68SYinan Xu  val wmask = IO(Input(UInt(DataBits.W)))
3971784e68SYinan Xu
4071784e68SYinan Xu  def read(enable: Bool, address: UInt): UInt = {
4171784e68SYinan Xu    ren := enable
4271784e68SYinan Xu    rIdx := address
4371784e68SYinan Xu    rdata
4471784e68SYinan Xu  }
4571784e68SYinan Xu  def write(enable: Bool, address: UInt, data: UInt, mask: UInt): Unit = {
4671784e68SYinan Xu    wen := enable
4771784e68SYinan Xu    wIdx := address
4871784e68SYinan Xu    wdata := data
4971784e68SYinan Xu    wmask := mask
5071784e68SYinan Xu  }
5171784e68SYinan Xu
5271784e68SYinan Xu  val verilogLines = Seq(
5371784e68SYinan Xu    "module MemoryRWHelper(",
5471784e68SYinan Xu    "  input         clock,",
5571784e68SYinan Xu    "  input         reset,",
5671784e68SYinan Xu    "  input         ren,",
5771784e68SYinan Xu    "  input  [63:0] rIdx,",
5871784e68SYinan Xu    "  output [63:0] rdata,",
5971784e68SYinan Xu    "  input  [63:0] wIdx,",
6071784e68SYinan Xu    "  input  [63:0] wdata,",
6171784e68SYinan Xu    "  input  [63:0] wmask,",
6271784e68SYinan Xu    "  input         wen",
6371784e68SYinan Xu    ");",
6471784e68SYinan Xu    "",
6571784e68SYinan Xu    "  assign rdata = (!reset && ren) ? ram_read_helper(1, rIdx) : 64'b0;",
6671784e68SYinan Xu    "",
6771784e68SYinan Xu    "  always @(posedge clock) begin",
6871784e68SYinan Xu    "    if (!reset && wen) begin",
6971784e68SYinan Xu    "      ram_write_helper(wIdx, wdata, wmask, 1);",
7071784e68SYinan Xu    "    end",
7171784e68SYinan Xu    "  end",
7271784e68SYinan Xu    "",
7371784e68SYinan Xu    "endmodule"
7471784e68SYinan Xu  )
7571784e68SYinan Xu  setInline(s"$desiredName.v", verilogLines.mkString("\n"))
7671784e68SYinan Xu}
7771784e68SYinan Xu
7871784e68SYinan Xuobject MemoryRWHelper {
7971784e68SYinan Xu  def apply(clock: Clock, reset: Reset): MemoryRWHelper = {
8071784e68SYinan Xu    val helper = Module(new MemoryRWHelper)
8171784e68SYinan Xu    helper.clock := clock
8271784e68SYinan Xu    helper.reset := reset
8371784e68SYinan Xu    helper
8471784e68SYinan Xu  }
8571784e68SYinan Xu}
8671784e68SYinan Xu
8771784e68SYinan Xuclass MemoryRequestHelper(requestType: Int)
8871784e68SYinan Xu  extends ExtModule(Map("REQUEST_TYPE" -> requestType))
8971784e68SYinan Xu  with HasExtModuleInline
9071784e68SYinan Xu{
9171784e68SYinan Xu  val clock     = IO(Input(Clock()))
9271784e68SYinan Xu  val reset     = IO(Input(Reset()))
9371784e68SYinan Xu  val io = IO(new Bundle {
9471784e68SYinan Xu    val req = Flipped(ValidIO(new Bundle {
9571784e68SYinan Xu      val addr = UInt(64.W)
9671784e68SYinan Xu      val id   = UInt(32.W)
9771784e68SYinan Xu    }))
9871784e68SYinan Xu    val response = Output(Bool())
9971784e68SYinan Xu  })
10071784e68SYinan Xu
10171784e68SYinan Xu  val verilogLines = Seq(
10271784e68SYinan Xu    "import \"DPI-C\" function bit memory_request (",
10371784e68SYinan Xu    "  input longint address,",
10471784e68SYinan Xu    "  input int id,",
10571784e68SYinan Xu    "  input bit isWrite",
10671784e68SYinan Xu    ");",
10771784e68SYinan Xu    "",
10871784e68SYinan Xu    "module MemoryRequestHelper #(",
10971784e68SYinan Xu    "  parameter REQUEST_TYPE",
11071784e68SYinan Xu    ")(",
11171784e68SYinan Xu    "  input             clock,",
11271784e68SYinan Xu    "  input             reset,",
11371784e68SYinan Xu    "  input             io_req_valid,",
11471784e68SYinan Xu    "  input      [63:0] io_req_bits_addr,",
11571784e68SYinan Xu    "  input      [31:0] io_req_bits_id,",
11671784e68SYinan Xu    "  output reg        io_response",
11771784e68SYinan Xu    ");",
11871784e68SYinan Xu    "",
11971784e68SYinan Xu    "always @(posedge clock or posedge reset) begin",
12071784e68SYinan Xu    "  if (reset) begin",
12171784e68SYinan Xu    "    io_response <= 1'b0;",
12271784e68SYinan Xu    "  end",
12371784e68SYinan Xu    "  else if (io_req_valid) begin",
12471784e68SYinan Xu    "    io_response <= memory_request(io_req_bits_addr, io_req_bits_id, REQUEST_TYPE);",
12571784e68SYinan Xu    "  end" +
12671784e68SYinan Xu    "  else begin",
12771784e68SYinan Xu    "    io_response <= 1'b0;",
12871784e68SYinan Xu    "  end",
12971784e68SYinan Xu    "end",
13071784e68SYinan Xu    "",
13171784e68SYinan Xu    "endmodule"
13271784e68SYinan Xu  )
13371784e68SYinan Xu  setInline(s"$desiredName.v", verilogLines.mkString("\n"))
13471784e68SYinan Xu}
13571784e68SYinan Xu
13671784e68SYinan Xuclass MemoryResponseHelper(requestType: Int)
13771784e68SYinan Xu  extends ExtModule(Map("REQUEST_TYPE" -> requestType))
13871784e68SYinan Xu  with HasExtModuleInline
13971784e68SYinan Xu{
14071784e68SYinan Xu  val clock    = IO(Input(Clock()))
14171784e68SYinan Xu  val reset    = IO(Input(Reset()))
14271784e68SYinan Xu  val enable   = IO(Input(Bool()))
14371784e68SYinan Xu  val response = IO(Output(UInt(64.W)))
14471784e68SYinan Xu
14571784e68SYinan Xu  val verilogLines = Seq(
14671784e68SYinan Xu    "import \"DPI-C\" function longint memory_response (",
14771784e68SYinan Xu    "  input bit isWrite",
14871784e68SYinan Xu    ");",
14971784e68SYinan Xu    "",
15071784e68SYinan Xu    "module MemoryResponseHelper #(",
15171784e68SYinan Xu    "  parameter REQUEST_TYPE",
15271784e68SYinan Xu    ")(",
15371784e68SYinan Xu    "  input             clock,",
15471784e68SYinan Xu    "  input             reset,",
15571784e68SYinan Xu    "  input             enable,",
15671784e68SYinan Xu    "  output reg [63:0] response",
15771784e68SYinan Xu    ");",
15871784e68SYinan Xu    "",
15971784e68SYinan Xu    "always @(posedge clock or posedge reset) begin",
16071784e68SYinan Xu    "  if (reset) begin",
16171784e68SYinan Xu    "    response <= 64'b0;",
16271784e68SYinan Xu    "  end",
16371784e68SYinan Xu    "  else if (!reset && enable) begin",
16471784e68SYinan Xu    "    response <= memory_response(REQUEST_TYPE);",
16571784e68SYinan Xu    "  end",
16671784e68SYinan Xu    " else begin",
16771784e68SYinan Xu    "    response <= 64'b0;",
16871784e68SYinan Xu    "  end",
16971784e68SYinan Xu    "end",
17071784e68SYinan Xu    "",
17171784e68SYinan Xu    "endmodule"
17271784e68SYinan Xu  )
17371784e68SYinan Xu  setInline(s"$desiredName.v", verilogLines.mkString("\n"))
17471784e68SYinan Xu}
17571784e68SYinan Xu
17671784e68SYinan Xutrait MemoryHelper { this: Module =>
17771784e68SYinan Xu  private def requestType(isWrite: Boolean): Int = if (isWrite) 1 else 0
17871784e68SYinan Xu  private def request(valid: Bool, addr: UInt, id: UInt, isWrite: Boolean): Bool = {
17971784e68SYinan Xu    val helper = Module(new MemoryRequestHelper(requestType(isWrite)))
18071784e68SYinan Xu    helper.clock := clock
18171784e68SYinan Xu    helper.reset := reset
18271784e68SYinan Xu    helper.io.req.valid := valid
18371784e68SYinan Xu    helper.io.req.bits.addr := addr
18471784e68SYinan Xu    helper.io.req.bits.id := id
18571784e68SYinan Xu    helper.io.response
18671784e68SYinan Xu  }
18771784e68SYinan Xu  protected def readRequest(valid: Bool, addr: UInt, id: UInt): Bool =
18871784e68SYinan Xu    request(valid, addr, id, false)
18971784e68SYinan Xu  protected def writeRequest(valid: Bool, addr: UInt, id: UInt): Bool =
19071784e68SYinan Xu    request(valid, addr, id, true)
19171784e68SYinan Xu  private def response(enable: Bool, isWrite: Boolean): (Bool, UInt) = {
19271784e68SYinan Xu    val helper = Module(new MemoryResponseHelper(requestType(isWrite)))
19371784e68SYinan Xu    helper.clock := clock
19471784e68SYinan Xu    helper.reset := reset
19571784e68SYinan Xu    helper.enable := enable
19671784e68SYinan Xu    (helper.response(32), helper.response(31, 0))
19771784e68SYinan Xu  }
19871784e68SYinan Xu  protected def readResponse(enable: Bool): (Bool, UInt) =
19971784e68SYinan Xu    response(enable, false)
20071784e68SYinan Xu  protected def writeResponse(enable: Bool): (Bool, UInt) =
20171784e68SYinan Xu    response(enable, true)
20271784e68SYinan Xu}
20371784e68SYinan Xu
20471784e68SYinan Xuclass AXI4MemoryImp[T <: Data](outer: AXI4Memory) extends AXI4SlaveModuleImp(outer) with MemoryHelper {
20571784e68SYinan Xu  val ramWidth = 8
20671784e68SYinan Xu  val ramSplit = outer.beatBytes / ramWidth
20771784e68SYinan Xu  val ramBaseAddr = outer.address.head.base
20871784e68SYinan Xu  val ramOffsetBits = log2Ceil(outer.memByte)
20971784e68SYinan Xu  def ramIndex(addr: UInt) = ((addr - ramBaseAddr.U)(ramOffsetBits - 1, 0) >> log2Ceil(ramWidth)).asUInt
21071784e68SYinan Xu  val ramHelper = Seq.fill(ramSplit)(MemoryRWHelper(clock, reset))
21171784e68SYinan Xu
21271784e68SYinan Xu  val numOutstanding = 1 << in.ar.bits.id.getWidth
21371784e68SYinan Xu  val addressMem = Mem(numOutstanding, UInt((in.ar.bits.addr.getWidth - log2Ceil(ramWidth)).W))
21471784e68SYinan Xu  val arlenMem = Mem(numOutstanding, UInt(in.ar.bits.len.getWidth.W))
21571784e68SYinan Xu
21671784e68SYinan Xu  // accept a read request and send it to the external model
21771784e68SYinan Xu  val pending_read_req_valid = RegInit(false.B)
21871784e68SYinan Xu  val pending_read_req_bits  = RegEnable(in.ar.bits, in.ar.fire)
21971784e68SYinan Xu  val pending_read_req_ready = Wire(Bool())
22071784e68SYinan Xu  val pending_read_need_req = pending_read_req_valid && !pending_read_req_ready
22171784e68SYinan Xu  val read_req_valid = pending_read_need_req || in.ar.valid
22271784e68SYinan Xu  val read_req_bits  = Mux(pending_read_need_req, pending_read_req_bits, in.ar.bits)
22371784e68SYinan Xu  pending_read_req_ready := readRequest(read_req_valid, read_req_bits.addr, read_req_bits.id)
22471784e68SYinan Xu
22571784e68SYinan Xu  when (in.ar.fire) {
22671784e68SYinan Xu    pending_read_req_valid := true.B
22771784e68SYinan Xu    addressMem.write(read_req_bits.id, ramIndex(read_req_bits.addr))
22871784e68SYinan Xu    arlenMem.write(read_req_bits.id, read_req_bits.len)
22971784e68SYinan Xu  }.elsewhen (pending_read_req_ready) {
23071784e68SYinan Xu    pending_read_req_valid := false.B
23171784e68SYinan Xu  }
23271784e68SYinan Xu  in.ar.ready := !pending_read_req_valid || pending_read_req_ready
23371784e68SYinan Xu
23471784e68SYinan Xu  // accept a write request (including address and data) and send it to the external model
23571784e68SYinan Xu  val pending_write_req_valid = RegInit(VecInit.fill(2)(false.B))
23671784e68SYinan Xu  val pending_write_req_bits  = RegEnable(in.aw.bits, in.aw.fire)
23771784e68SYinan Xu  val pending_write_req_data  = RegEnable(in.w.bits, in.w.fire)
23871784e68SYinan Xu  XSError(in.aw.fire && in.aw.bits.len === 0.U, "data must have more than one beat now")
23971784e68SYinan Xu  val pending_write_req_ready = Wire(Bool())
24071784e68SYinan Xu  val pending_write_need_req = pending_write_req_valid.last && !pending_write_req_ready
24171784e68SYinan Xu  val write_req_valid = pending_write_req_valid.head && (pending_write_need_req || in.w.valid && in.w.bits.last)
24271784e68SYinan Xu  pending_write_req_ready := writeRequest(write_req_valid, pending_write_req_bits.addr, pending_write_req_bits.id)
24371784e68SYinan Xu
24471784e68SYinan Xu  when (in.aw.fire) {
24571784e68SYinan Xu    pending_write_req_valid.head := true.B
24671784e68SYinan Xu  }.elsewhen (pending_write_req_ready) {
24771784e68SYinan Xu    pending_write_req_valid.head := false.B
24871784e68SYinan Xu  }
24971784e68SYinan Xu  val write_req_last = in.w.fire && in.w.bits.last
25071784e68SYinan Xu  when (write_req_last) {
25171784e68SYinan Xu    pending_write_req_valid.last := true.B
25271784e68SYinan Xu  }.elsewhen (pending_write_req_ready) {
25371784e68SYinan Xu    pending_write_req_valid.last := false.B
25471784e68SYinan Xu  }
25571784e68SYinan Xu  in.aw.ready := !pending_write_req_valid.head || pending_write_req_ready
25671784e68SYinan Xu  in.w.ready := in.aw.ready || !pending_write_req_valid.last
25771784e68SYinan Xu
25871784e68SYinan Xu  // ram is written when write data fire
25971784e68SYinan Xu  val wdata_cnt = Counter(outer.burstLen)
26071784e68SYinan Xu  val write_req_addr = Mux(in.aw.fire, in.aw.bits.addr, pending_write_req_bits.addr)
26171784e68SYinan Xu  val write_req_index = ramIndex(write_req_addr) + Cat(wdata_cnt.value, 0.U(log2Ceil(ramSplit).W))
26271784e68SYinan Xu  for ((ram, i) <- ramHelper.zipWithIndex) {
26371784e68SYinan Xu    val enable = in.w.fire
26471784e68SYinan Xu    val address = write_req_index + i.U
26571784e68SYinan Xu    val data = in.w.bits.data(ramWidth * 8 * i + 63, ramWidth * 8 * i)
26671784e68SYinan Xu    val mask = MaskExpand(in.w.bits.strb(i * 8 + 7, i * 8))
26771784e68SYinan Xu    ram.write(enable, address, data, mask)
26871784e68SYinan Xu  }
26971784e68SYinan Xu  when (write_req_last) {
27071784e68SYinan Xu    wdata_cnt.reset()
27171784e68SYinan Xu  }.elsewhen (in.w.fire) {
27271784e68SYinan Xu    wdata_cnt.inc()
27371784e68SYinan Xu  }
27471784e68SYinan Xu
27571784e68SYinan Xu  // read data response
27671784e68SYinan Xu  val pending_read_resp_valid = RegInit(false.B)
27771784e68SYinan Xu  val pending_read_resp_id = Reg(UInt(in.r.bits.id.getWidth.W))
27871784e68SYinan Xu  val has_read_resp = Wire(Bool())
27971784e68SYinan Xu  val read_resp_last = in.r.fire && in.r.bits.last
28071784e68SYinan Xu  val (read_resp_valid, read_resp_id) = readResponse(!has_read_resp || read_resp_last)
28171784e68SYinan Xu  has_read_resp := (read_resp_valid && !read_resp_last) || pending_read_resp_valid
28271784e68SYinan Xu  val rdata_cnt = Counter(outer.burstLen)
28371784e68SYinan Xu  val read_resp_addr = addressMem(in.r.bits.id) + Cat(rdata_cnt.value, 0.U(log2Ceil(ramSplit).W))
28471784e68SYinan Xu  val read_resp_len = arlenMem(in.r.bits.id)
28571784e68SYinan Xu  in.r.valid := read_resp_valid || pending_read_resp_valid
28671784e68SYinan Xu  in.r.bits.id := Mux(pending_read_resp_valid, pending_read_resp_id, read_resp_id)
28771784e68SYinan Xu  val rdata = ramHelper.zipWithIndex.map{ case (ram, i) => ram.read(in.r.valid, read_resp_addr + i.U) }
28871784e68SYinan Xu  in.r.bits.data := VecInit(rdata).asUInt
28971784e68SYinan Xu  in.r.bits.resp := AXI4Parameters.RESP_OKAY
29071784e68SYinan Xu  in.r.bits.last := (rdata_cnt.value === read_resp_len)
29171784e68SYinan Xu
29271784e68SYinan Xu  when (!pending_read_resp_valid && read_resp_valid && !read_resp_last) {
29371784e68SYinan Xu    pending_read_resp_valid := true.B
29471784e68SYinan Xu    pending_read_resp_id := read_resp_id
29571784e68SYinan Xu  }.elsewhen (pending_read_resp_valid && !read_resp_valid && read_resp_last) {
29671784e68SYinan Xu    pending_read_resp_valid := false.B
29771784e68SYinan Xu  }
29871784e68SYinan Xu  when (read_resp_last) {
29971784e68SYinan Xu    rdata_cnt.reset()
30071784e68SYinan Xu  }.elsewhen (in.r.fire) {
30171784e68SYinan Xu    rdata_cnt.inc()
30271784e68SYinan Xu  }
30371784e68SYinan Xu
30471784e68SYinan Xu  // write response
30571784e68SYinan Xu  val pending_write_resp_valid = RegInit(false.B)
30671784e68SYinan Xu  val pending_write_resp_id = Reg(UInt(in.b.bits.id.getWidth.W))
30771784e68SYinan Xu  val has_write_resp = Wire(Bool())
30871784e68SYinan Xu  val (write_resp_valid, write_resp_id) = writeResponse(!has_write_resp || in.b.fire)
30904ac809eSYinan Xu  has_write_resp := write_resp_valid || pending_write_resp_valid
31071784e68SYinan Xu  in.b.valid := write_resp_valid || pending_write_resp_valid
31171784e68SYinan Xu  in.b.bits.id := Mux(pending_write_resp_valid, pending_write_resp_id, write_resp_id)
31271784e68SYinan Xu  in.b.bits.resp := AXI4Parameters.RESP_OKAY
31371784e68SYinan Xu
31471784e68SYinan Xu  when (!pending_write_resp_valid && write_resp_valid && !in.b.ready) {
31571784e68SYinan Xu    pending_write_resp_valid := true.B
31604ac809eSYinan Xu    pending_write_resp_id := write_resp_id
31771784e68SYinan Xu  }.elsewhen (pending_write_resp_valid && !write_resp_valid && in.b.ready) {
31871784e68SYinan Xu    pending_write_resp_valid := false.B
31971784e68SYinan Xu  }
32071784e68SYinan Xu}
32171784e68SYinan Xu
32271784e68SYinan Xuclass AXI4Memory
32371784e68SYinan Xu(
32471784e68SYinan Xu  val address: Seq[AddressSet],
32571784e68SYinan Xu  val memByte: Long,
32671784e68SYinan Xu  val useBlackBox: Boolean = false,
32771784e68SYinan Xu  val executable: Boolean = true,
32871784e68SYinan Xu  val beatBytes: Int,
32971784e68SYinan Xu  val burstLen: Int,
33071784e68SYinan Xu)(implicit p: Parameters)
33171784e68SYinan Xu  extends AXI4SlaveModule(address, executable, beatBytes, burstLen)
33271784e68SYinan Xu{
33371784e68SYinan Xu  override lazy val module = new AXI4MemoryImp(this)
33471784e68SYinan Xu}
33571784e68SYinan Xu
33671784e68SYinan Xuclass AXI4MemoryWrapper (
33771784e68SYinan Xu  slave: AXI4SlaveNode,
33871784e68SYinan Xu  memByte: Long,
33971784e68SYinan Xu  useBlackBox: Boolean = false
34071784e68SYinan Xu)(implicit p: Parameters) extends AXI4MemorySlave(slave, memByte, useBlackBox) {
34171784e68SYinan Xu  val ram = LazyModule(new AXI4Memory(
34271784e68SYinan Xu    slaveParam.address,
34371784e68SYinan Xu    memByte,
34471784e68SYinan Xu    useBlackBox,
34571784e68SYinan Xu    slaveParam.executable,
34671784e68SYinan Xu    portParam.beatBytes,
34771784e68SYinan Xu    burstLen
34871784e68SYinan Xu  ))
34971784e68SYinan Xu  ram.node := master
35071784e68SYinan Xu}
35171784e68SYinan Xu
35271784e68SYinan Xuabstract class AXI4MemorySlave (
35371784e68SYinan Xu  slave: AXI4SlaveNode,
35471784e68SYinan Xu  memByte: Long,
35571784e68SYinan Xu  useBlackBox: Boolean = false
35671784e68SYinan Xu)(implicit p: Parameters) extends LazyModule {
35771784e68SYinan Xu  val master = AXI4MasterNode(List(slave.in.head._2.master))
35871784e68SYinan Xu
35971784e68SYinan Xu  val portParam = slave.portParams.head
36071784e68SYinan Xu  val slaveParam = portParam.slaves.head
36171784e68SYinan Xu  val burstLen = portParam.maxTransfer / portParam.beatBytes
36271784e68SYinan Xu
36371784e68SYinan Xu  val io_axi4 = InModuleBody{ master.makeIOs() }
36471784e68SYinan Xu
36571784e68SYinan Xu  lazy val module = new LazyModuleImp(this) { }
36671784e68SYinan Xu}
36771784e68SYinan Xu
36871784e68SYinan Xuobject AXI4MemorySlave {
36971784e68SYinan Xu  def apply(
37071784e68SYinan Xu    slave: AXI4SlaveNode,
37171784e68SYinan Xu    memByte: Long,
37271784e68SYinan Xu    useBlackBox: Boolean = false,
37371784e68SYinan Xu    dynamicLatency: Boolean = false
37471784e68SYinan Xu  )(implicit p: Parameters): AXI4MemorySlave = {
37571784e68SYinan Xu    val memory = if (dynamicLatency) {
37671784e68SYinan Xu      LazyModule(new AXI4MemoryWrapper(slave, memByte, useBlackBox))
37771784e68SYinan Xu    } else {
37871784e68SYinan Xu      LazyModule(new AXI4RAMWrapper(slave, memByte, useBlackBox))
37971784e68SYinan Xu    }
38071784e68SYinan Xu    memory
38171784e68SYinan Xu  }
38271784e68SYinan Xu}
383