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