1*71784e68SYinan Xu/*************************************************************************************** 2*71784e68SYinan Xu * Copyright (c) 2020-2022 Institute of Computing Technology, Chinese Academy of Sciences 3*71784e68SYinan Xu * 4*71784e68SYinan Xu * XiangShan is licensed under Mulan PSL v2. 5*71784e68SYinan Xu * You can use this software according to the terms and conditions of the Mulan PSL v2. 6*71784e68SYinan Xu * You may obtain a copy of Mulan PSL v2 at: 7*71784e68SYinan Xu * http://license.coscl.org.cn/MulanPSL2 8*71784e68SYinan Xu * 9*71784e68SYinan Xu * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10*71784e68SYinan Xu * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11*71784e68SYinan Xu * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12*71784e68SYinan Xu * 13*71784e68SYinan Xu * See the Mulan PSL v2 for more details. 14*71784e68SYinan Xu ***************************************************************************************/ 15*71784e68SYinan Xu 16*71784e68SYinan Xupackage device 17*71784e68SYinan Xu 18*71784e68SYinan Xuimport chipsalliance.rocketchip.config.Parameters 19*71784e68SYinan Xuimport chisel3._ 20*71784e68SYinan Xuimport chisel3.experimental.ExtModule 21*71784e68SYinan Xuimport chisel3.util._ 22*71784e68SYinan Xuimport freechips.rocketchip.amba.axi4.{AXI4MasterNode, AXI4Parameters, AXI4SlaveNode} 23*71784e68SYinan Xuimport freechips.rocketchip.diplomacy.{AddressSet, InModuleBody, LazyModule, LazyModuleImp} 24*71784e68SYinan Xuimport utils._ 25*71784e68SYinan Xu 26*71784e68SYinan Xuclass MemoryRWHelper extends ExtModule with HasExtModuleInline { 27*71784e68SYinan Xu val DataBits = 64 28*71784e68SYinan Xu 29*71784e68SYinan Xu val clock = IO(Input(Clock())) 30*71784e68SYinan Xu val reset = IO(Input(Reset())) 31*71784e68SYinan Xu val ren = IO(Input(Bool())) 32*71784e68SYinan Xu val rIdx = IO(Input(UInt(DataBits.W))) 33*71784e68SYinan Xu val rdata = IO(Output(UInt(DataBits.W))) 34*71784e68SYinan Xu val wen = IO(Input(Bool())) 35*71784e68SYinan Xu val wIdx = IO(Input(UInt(DataBits.W))) 36*71784e68SYinan Xu val wdata = IO(Input(UInt(DataBits.W))) 37*71784e68SYinan Xu val wmask = IO(Input(UInt(DataBits.W))) 38*71784e68SYinan Xu 39*71784e68SYinan Xu def read(enable: Bool, address: UInt): UInt = { 40*71784e68SYinan Xu ren := enable 41*71784e68SYinan Xu rIdx := address 42*71784e68SYinan Xu rdata 43*71784e68SYinan Xu } 44*71784e68SYinan Xu def write(enable: Bool, address: UInt, data: UInt, mask: UInt): Unit = { 45*71784e68SYinan Xu wen := enable 46*71784e68SYinan Xu wIdx := address 47*71784e68SYinan Xu wdata := data 48*71784e68SYinan Xu wmask := mask 49*71784e68SYinan Xu } 50*71784e68SYinan Xu 51*71784e68SYinan Xu val verilogLines = Seq( 52*71784e68SYinan Xu "module MemoryRWHelper(", 53*71784e68SYinan Xu " input clock,", 54*71784e68SYinan Xu " input reset,", 55*71784e68SYinan Xu " input ren,", 56*71784e68SYinan Xu " input [63:0] rIdx,", 57*71784e68SYinan Xu " output [63:0] rdata,", 58*71784e68SYinan Xu " input [63:0] wIdx,", 59*71784e68SYinan Xu " input [63:0] wdata,", 60*71784e68SYinan Xu " input [63:0] wmask,", 61*71784e68SYinan Xu " input wen", 62*71784e68SYinan Xu ");", 63*71784e68SYinan Xu "", 64*71784e68SYinan Xu " assign rdata = (!reset && ren) ? ram_read_helper(1, rIdx) : 64'b0;", 65*71784e68SYinan Xu "", 66*71784e68SYinan Xu " always @(posedge clock) begin", 67*71784e68SYinan Xu " if (!reset && wen) begin", 68*71784e68SYinan Xu " ram_write_helper(wIdx, wdata, wmask, 1);", 69*71784e68SYinan Xu " end", 70*71784e68SYinan Xu " end", 71*71784e68SYinan Xu "", 72*71784e68SYinan Xu "endmodule" 73*71784e68SYinan Xu ) 74*71784e68SYinan Xu setInline(s"$desiredName.v", verilogLines.mkString("\n")) 75*71784e68SYinan Xu} 76*71784e68SYinan Xu 77*71784e68SYinan Xuobject MemoryRWHelper { 78*71784e68SYinan Xu def apply(clock: Clock, reset: Reset): MemoryRWHelper = { 79*71784e68SYinan Xu val helper = Module(new MemoryRWHelper) 80*71784e68SYinan Xu helper.clock := clock 81*71784e68SYinan Xu helper.reset := reset 82*71784e68SYinan Xu helper 83*71784e68SYinan Xu } 84*71784e68SYinan Xu} 85*71784e68SYinan Xu 86*71784e68SYinan Xuclass MemoryRequestHelper(requestType: Int) 87*71784e68SYinan Xu extends ExtModule(Map("REQUEST_TYPE" -> requestType)) 88*71784e68SYinan Xu with HasExtModuleInline 89*71784e68SYinan Xu{ 90*71784e68SYinan Xu val clock = IO(Input(Clock())) 91*71784e68SYinan Xu val reset = IO(Input(Reset())) 92*71784e68SYinan Xu val io = IO(new Bundle { 93*71784e68SYinan Xu val req = Flipped(ValidIO(new Bundle { 94*71784e68SYinan Xu val addr = UInt(64.W) 95*71784e68SYinan Xu val id = UInt(32.W) 96*71784e68SYinan Xu })) 97*71784e68SYinan Xu val response = Output(Bool()) 98*71784e68SYinan Xu }) 99*71784e68SYinan Xu 100*71784e68SYinan Xu val verilogLines = Seq( 101*71784e68SYinan Xu "import \"DPI-C\" function bit memory_request (", 102*71784e68SYinan Xu " input longint address,", 103*71784e68SYinan Xu " input int id,", 104*71784e68SYinan Xu " input bit isWrite", 105*71784e68SYinan Xu ");", 106*71784e68SYinan Xu "", 107*71784e68SYinan Xu "module MemoryRequestHelper #(", 108*71784e68SYinan Xu " parameter REQUEST_TYPE", 109*71784e68SYinan Xu ")(", 110*71784e68SYinan Xu " input clock,", 111*71784e68SYinan Xu " input reset,", 112*71784e68SYinan Xu " input io_req_valid,", 113*71784e68SYinan Xu " input [63:0] io_req_bits_addr,", 114*71784e68SYinan Xu " input [31:0] io_req_bits_id,", 115*71784e68SYinan Xu " output reg io_response", 116*71784e68SYinan Xu ");", 117*71784e68SYinan Xu "", 118*71784e68SYinan Xu "always @(posedge clock or posedge reset) begin", 119*71784e68SYinan Xu " if (reset) begin", 120*71784e68SYinan Xu " io_response <= 1'b0;", 121*71784e68SYinan Xu " end", 122*71784e68SYinan Xu " else if (io_req_valid) begin", 123*71784e68SYinan Xu " io_response <= memory_request(io_req_bits_addr, io_req_bits_id, REQUEST_TYPE);", 124*71784e68SYinan Xu " end" + 125*71784e68SYinan Xu " else begin", 126*71784e68SYinan Xu " io_response <= 1'b0;", 127*71784e68SYinan Xu " end", 128*71784e68SYinan Xu "end", 129*71784e68SYinan Xu "", 130*71784e68SYinan Xu "endmodule" 131*71784e68SYinan Xu ) 132*71784e68SYinan Xu setInline(s"$desiredName.v", verilogLines.mkString("\n")) 133*71784e68SYinan Xu} 134*71784e68SYinan Xu 135*71784e68SYinan Xuclass MemoryResponseHelper(requestType: Int) 136*71784e68SYinan Xu extends ExtModule(Map("REQUEST_TYPE" -> requestType)) 137*71784e68SYinan Xu with HasExtModuleInline 138*71784e68SYinan Xu{ 139*71784e68SYinan Xu val clock = IO(Input(Clock())) 140*71784e68SYinan Xu val reset = IO(Input(Reset())) 141*71784e68SYinan Xu val enable = IO(Input(Bool())) 142*71784e68SYinan Xu val response = IO(Output(UInt(64.W))) 143*71784e68SYinan Xu 144*71784e68SYinan Xu val verilogLines = Seq( 145*71784e68SYinan Xu "import \"DPI-C\" function longint memory_response (", 146*71784e68SYinan Xu " input bit isWrite", 147*71784e68SYinan Xu ");", 148*71784e68SYinan Xu "", 149*71784e68SYinan Xu "module MemoryResponseHelper #(", 150*71784e68SYinan Xu " parameter REQUEST_TYPE", 151*71784e68SYinan Xu ")(", 152*71784e68SYinan Xu " input clock,", 153*71784e68SYinan Xu " input reset,", 154*71784e68SYinan Xu " input enable,", 155*71784e68SYinan Xu " output reg [63:0] response", 156*71784e68SYinan Xu ");", 157*71784e68SYinan Xu "", 158*71784e68SYinan Xu "always @(posedge clock or posedge reset) begin", 159*71784e68SYinan Xu " if (reset) begin", 160*71784e68SYinan Xu " response <= 64'b0;", 161*71784e68SYinan Xu " end", 162*71784e68SYinan Xu " else if (!reset && enable) begin", 163*71784e68SYinan Xu " response <= memory_response(REQUEST_TYPE);", 164*71784e68SYinan Xu " end", 165*71784e68SYinan Xu " else begin", 166*71784e68SYinan Xu " response <= 64'b0;", 167*71784e68SYinan Xu " end", 168*71784e68SYinan Xu "end", 169*71784e68SYinan Xu "", 170*71784e68SYinan Xu "endmodule" 171*71784e68SYinan Xu ) 172*71784e68SYinan Xu setInline(s"$desiredName.v", verilogLines.mkString("\n")) 173*71784e68SYinan Xu} 174*71784e68SYinan Xu 175*71784e68SYinan Xutrait MemoryHelper { this: Module => 176*71784e68SYinan Xu private def requestType(isWrite: Boolean): Int = if (isWrite) 1 else 0 177*71784e68SYinan Xu private def request(valid: Bool, addr: UInt, id: UInt, isWrite: Boolean): Bool = { 178*71784e68SYinan Xu val helper = Module(new MemoryRequestHelper(requestType(isWrite))) 179*71784e68SYinan Xu helper.clock := clock 180*71784e68SYinan Xu helper.reset := reset 181*71784e68SYinan Xu helper.io.req.valid := valid 182*71784e68SYinan Xu helper.io.req.bits.addr := addr 183*71784e68SYinan Xu helper.io.req.bits.id := id 184*71784e68SYinan Xu helper.io.response 185*71784e68SYinan Xu } 186*71784e68SYinan Xu protected def readRequest(valid: Bool, addr: UInt, id: UInt): Bool = 187*71784e68SYinan Xu request(valid, addr, id, false) 188*71784e68SYinan Xu protected def writeRequest(valid: Bool, addr: UInt, id: UInt): Bool = 189*71784e68SYinan Xu request(valid, addr, id, true) 190*71784e68SYinan Xu private def response(enable: Bool, isWrite: Boolean): (Bool, UInt) = { 191*71784e68SYinan Xu val helper = Module(new MemoryResponseHelper(requestType(isWrite))) 192*71784e68SYinan Xu helper.clock := clock 193*71784e68SYinan Xu helper.reset := reset 194*71784e68SYinan Xu helper.enable := enable 195*71784e68SYinan Xu (helper.response(32), helper.response(31, 0)) 196*71784e68SYinan Xu } 197*71784e68SYinan Xu protected def readResponse(enable: Bool): (Bool, UInt) = 198*71784e68SYinan Xu response(enable, false) 199*71784e68SYinan Xu protected def writeResponse(enable: Bool): (Bool, UInt) = 200*71784e68SYinan Xu response(enable, true) 201*71784e68SYinan Xu} 202*71784e68SYinan Xu 203*71784e68SYinan Xuclass AXI4MemoryImp[T <: Data](outer: AXI4Memory) extends AXI4SlaveModuleImp(outer) with MemoryHelper { 204*71784e68SYinan Xu val ramWidth = 8 205*71784e68SYinan Xu val ramSplit = outer.beatBytes / ramWidth 206*71784e68SYinan Xu val ramBaseAddr = outer.address.head.base 207*71784e68SYinan Xu val ramOffsetBits = log2Ceil(outer.memByte) 208*71784e68SYinan Xu def ramIndex(addr: UInt) = ((addr - ramBaseAddr.U)(ramOffsetBits - 1, 0) >> log2Ceil(ramWidth)).asUInt 209*71784e68SYinan Xu val ramHelper = Seq.fill(ramSplit)(MemoryRWHelper(clock, reset)) 210*71784e68SYinan Xu 211*71784e68SYinan Xu val numOutstanding = 1 << in.ar.bits.id.getWidth 212*71784e68SYinan Xu val addressMem = Mem(numOutstanding, UInt((in.ar.bits.addr.getWidth - log2Ceil(ramWidth)).W)) 213*71784e68SYinan Xu val arlenMem = Mem(numOutstanding, UInt(in.ar.bits.len.getWidth.W)) 214*71784e68SYinan Xu 215*71784e68SYinan Xu // accept a read request and send it to the external model 216*71784e68SYinan Xu val pending_read_req_valid = RegInit(false.B) 217*71784e68SYinan Xu val pending_read_req_bits = RegEnable(in.ar.bits, in.ar.fire) 218*71784e68SYinan Xu val pending_read_req_ready = Wire(Bool()) 219*71784e68SYinan Xu val pending_read_need_req = pending_read_req_valid && !pending_read_req_ready 220*71784e68SYinan Xu val read_req_valid = pending_read_need_req || in.ar.valid 221*71784e68SYinan Xu val read_req_bits = Mux(pending_read_need_req, pending_read_req_bits, in.ar.bits) 222*71784e68SYinan Xu pending_read_req_ready := readRequest(read_req_valid, read_req_bits.addr, read_req_bits.id) 223*71784e68SYinan Xu 224*71784e68SYinan Xu when (in.ar.fire) { 225*71784e68SYinan Xu pending_read_req_valid := true.B 226*71784e68SYinan Xu addressMem.write(read_req_bits.id, ramIndex(read_req_bits.addr)) 227*71784e68SYinan Xu arlenMem.write(read_req_bits.id, read_req_bits.len) 228*71784e68SYinan Xu }.elsewhen (pending_read_req_ready) { 229*71784e68SYinan Xu pending_read_req_valid := false.B 230*71784e68SYinan Xu } 231*71784e68SYinan Xu in.ar.ready := !pending_read_req_valid || pending_read_req_ready 232*71784e68SYinan Xu 233*71784e68SYinan Xu // accept a write request (including address and data) and send it to the external model 234*71784e68SYinan Xu val pending_write_req_valid = RegInit(VecInit.fill(2)(false.B)) 235*71784e68SYinan Xu val pending_write_req_bits = RegEnable(in.aw.bits, in.aw.fire) 236*71784e68SYinan Xu val pending_write_req_data = RegEnable(in.w.bits, in.w.fire) 237*71784e68SYinan Xu XSError(in.aw.fire && in.aw.bits.len === 0.U, "data must have more than one beat now") 238*71784e68SYinan Xu val pending_write_req_ready = Wire(Bool()) 239*71784e68SYinan Xu val pending_write_need_req = pending_write_req_valid.last && !pending_write_req_ready 240*71784e68SYinan Xu val write_req_valid = pending_write_req_valid.head && (pending_write_need_req || in.w.valid && in.w.bits.last) 241*71784e68SYinan Xu pending_write_req_ready := writeRequest(write_req_valid, pending_write_req_bits.addr, pending_write_req_bits.id) 242*71784e68SYinan Xu 243*71784e68SYinan Xu when (in.aw.fire) { 244*71784e68SYinan Xu pending_write_req_valid.head := true.B 245*71784e68SYinan Xu }.elsewhen (pending_write_req_ready) { 246*71784e68SYinan Xu pending_write_req_valid.head := false.B 247*71784e68SYinan Xu } 248*71784e68SYinan Xu val write_req_last = in.w.fire && in.w.bits.last 249*71784e68SYinan Xu when (write_req_last) { 250*71784e68SYinan Xu pending_write_req_valid.last := true.B 251*71784e68SYinan Xu }.elsewhen (pending_write_req_ready) { 252*71784e68SYinan Xu pending_write_req_valid.last := false.B 253*71784e68SYinan Xu } 254*71784e68SYinan Xu in.aw.ready := !pending_write_req_valid.head || pending_write_req_ready 255*71784e68SYinan Xu in.w.ready := in.aw.ready || !pending_write_req_valid.last 256*71784e68SYinan Xu 257*71784e68SYinan Xu // ram is written when write data fire 258*71784e68SYinan Xu val wdata_cnt = Counter(outer.burstLen) 259*71784e68SYinan Xu val write_req_addr = Mux(in.aw.fire, in.aw.bits.addr, pending_write_req_bits.addr) 260*71784e68SYinan Xu val write_req_index = ramIndex(write_req_addr) + Cat(wdata_cnt.value, 0.U(log2Ceil(ramSplit).W)) 261*71784e68SYinan Xu for ((ram, i) <- ramHelper.zipWithIndex) { 262*71784e68SYinan Xu val enable = in.w.fire 263*71784e68SYinan Xu val address = write_req_index + i.U 264*71784e68SYinan Xu val data = in.w.bits.data(ramWidth * 8 * i + 63, ramWidth * 8 * i) 265*71784e68SYinan Xu val mask = MaskExpand(in.w.bits.strb(i * 8 + 7, i * 8)) 266*71784e68SYinan Xu ram.write(enable, address, data, mask) 267*71784e68SYinan Xu } 268*71784e68SYinan Xu when (write_req_last) { 269*71784e68SYinan Xu wdata_cnt.reset() 270*71784e68SYinan Xu }.elsewhen (in.w.fire) { 271*71784e68SYinan Xu wdata_cnt.inc() 272*71784e68SYinan Xu } 273*71784e68SYinan Xu 274*71784e68SYinan Xu // read data response 275*71784e68SYinan Xu val pending_read_resp_valid = RegInit(false.B) 276*71784e68SYinan Xu val pending_read_resp_id = Reg(UInt(in.r.bits.id.getWidth.W)) 277*71784e68SYinan Xu val has_read_resp = Wire(Bool()) 278*71784e68SYinan Xu val read_resp_last = in.r.fire && in.r.bits.last 279*71784e68SYinan Xu val (read_resp_valid, read_resp_id) = readResponse(!has_read_resp || read_resp_last) 280*71784e68SYinan Xu has_read_resp := (read_resp_valid && !read_resp_last) || pending_read_resp_valid 281*71784e68SYinan Xu val rdata_cnt = Counter(outer.burstLen) 282*71784e68SYinan Xu val read_resp_addr = addressMem(in.r.bits.id) + Cat(rdata_cnt.value, 0.U(log2Ceil(ramSplit).W)) 283*71784e68SYinan Xu val read_resp_len = arlenMem(in.r.bits.id) 284*71784e68SYinan Xu in.r.valid := read_resp_valid || pending_read_resp_valid 285*71784e68SYinan Xu in.r.bits.id := Mux(pending_read_resp_valid, pending_read_resp_id, read_resp_id) 286*71784e68SYinan Xu val rdata = ramHelper.zipWithIndex.map{ case (ram, i) => ram.read(in.r.valid, read_resp_addr + i.U) } 287*71784e68SYinan Xu in.r.bits.data := VecInit(rdata).asUInt 288*71784e68SYinan Xu in.r.bits.resp := AXI4Parameters.RESP_OKAY 289*71784e68SYinan Xu in.r.bits.last := (rdata_cnt.value === read_resp_len) 290*71784e68SYinan Xu 291*71784e68SYinan Xu when (!pending_read_resp_valid && read_resp_valid && !read_resp_last) { 292*71784e68SYinan Xu pending_read_resp_valid := true.B 293*71784e68SYinan Xu pending_read_resp_id := read_resp_id 294*71784e68SYinan Xu }.elsewhen (pending_read_resp_valid && !read_resp_valid && read_resp_last) { 295*71784e68SYinan Xu pending_read_resp_valid := false.B 296*71784e68SYinan Xu } 297*71784e68SYinan Xu when (read_resp_last) { 298*71784e68SYinan Xu rdata_cnt.reset() 299*71784e68SYinan Xu }.elsewhen (in.r.fire) { 300*71784e68SYinan Xu rdata_cnt.inc() 301*71784e68SYinan Xu } 302*71784e68SYinan Xu 303*71784e68SYinan Xu // write response 304*71784e68SYinan Xu val pending_write_resp_valid = RegInit(false.B) 305*71784e68SYinan Xu val pending_write_resp_id = Reg(UInt(in.b.bits.id.getWidth.W)) 306*71784e68SYinan Xu val has_write_resp = Wire(Bool()) 307*71784e68SYinan Xu val (write_resp_valid, write_resp_id) = writeResponse(!has_write_resp || in.b.fire) 308*71784e68SYinan Xu has_write_resp := (write_resp_valid && !read_resp_last) || pending_write_resp_valid 309*71784e68SYinan Xu in.b.valid := write_resp_valid || pending_write_resp_valid 310*71784e68SYinan Xu in.b.bits.id := Mux(pending_write_resp_valid, pending_write_resp_id, write_resp_id) 311*71784e68SYinan Xu in.b.bits.resp := AXI4Parameters.RESP_OKAY 312*71784e68SYinan Xu 313*71784e68SYinan Xu when (!pending_write_resp_valid && write_resp_valid && !in.b.ready) { 314*71784e68SYinan Xu pending_write_resp_valid := true.B 315*71784e68SYinan Xu pending_write_resp_id := pending_write_resp_id 316*71784e68SYinan Xu }.elsewhen (pending_write_resp_valid && !write_resp_valid && in.b.ready) { 317*71784e68SYinan Xu pending_write_resp_valid := false.B 318*71784e68SYinan Xu } 319*71784e68SYinan Xu} 320*71784e68SYinan Xu 321*71784e68SYinan Xuclass AXI4Memory 322*71784e68SYinan Xu( 323*71784e68SYinan Xu val address: Seq[AddressSet], 324*71784e68SYinan Xu val memByte: Long, 325*71784e68SYinan Xu val useBlackBox: Boolean = false, 326*71784e68SYinan Xu val executable: Boolean = true, 327*71784e68SYinan Xu val beatBytes: Int, 328*71784e68SYinan Xu val burstLen: Int, 329*71784e68SYinan Xu)(implicit p: Parameters) 330*71784e68SYinan Xu extends AXI4SlaveModule(address, executable, beatBytes, burstLen) 331*71784e68SYinan Xu{ 332*71784e68SYinan Xu override lazy val module = new AXI4MemoryImp(this) 333*71784e68SYinan Xu} 334*71784e68SYinan Xu 335*71784e68SYinan Xuclass AXI4MemoryWrapper ( 336*71784e68SYinan Xu slave: AXI4SlaveNode, 337*71784e68SYinan Xu memByte: Long, 338*71784e68SYinan Xu useBlackBox: Boolean = false 339*71784e68SYinan Xu)(implicit p: Parameters) extends AXI4MemorySlave(slave, memByte, useBlackBox) { 340*71784e68SYinan Xu val ram = LazyModule(new AXI4Memory( 341*71784e68SYinan Xu slaveParam.address, 342*71784e68SYinan Xu memByte, 343*71784e68SYinan Xu useBlackBox, 344*71784e68SYinan Xu slaveParam.executable, 345*71784e68SYinan Xu portParam.beatBytes, 346*71784e68SYinan Xu burstLen 347*71784e68SYinan Xu )) 348*71784e68SYinan Xu ram.node := master 349*71784e68SYinan Xu} 350*71784e68SYinan Xu 351*71784e68SYinan Xuabstract class AXI4MemorySlave ( 352*71784e68SYinan Xu slave: AXI4SlaveNode, 353*71784e68SYinan Xu memByte: Long, 354*71784e68SYinan Xu useBlackBox: Boolean = false 355*71784e68SYinan Xu)(implicit p: Parameters) extends LazyModule { 356*71784e68SYinan Xu val master = AXI4MasterNode(List(slave.in.head._2.master)) 357*71784e68SYinan Xu 358*71784e68SYinan Xu val portParam = slave.portParams.head 359*71784e68SYinan Xu val slaveParam = portParam.slaves.head 360*71784e68SYinan Xu val burstLen = portParam.maxTransfer / portParam.beatBytes 361*71784e68SYinan Xu 362*71784e68SYinan Xu val io_axi4 = InModuleBody{ master.makeIOs() } 363*71784e68SYinan Xu 364*71784e68SYinan Xu lazy val module = new LazyModuleImp(this) { } 365*71784e68SYinan Xu} 366*71784e68SYinan Xu 367*71784e68SYinan Xuobject AXI4MemorySlave { 368*71784e68SYinan Xu def apply( 369*71784e68SYinan Xu slave: AXI4SlaveNode, 370*71784e68SYinan Xu memByte: Long, 371*71784e68SYinan Xu useBlackBox: Boolean = false, 372*71784e68SYinan Xu dynamicLatency: Boolean = false 373*71784e68SYinan Xu )(implicit p: Parameters): AXI4MemorySlave = { 374*71784e68SYinan Xu val memory = if (dynamicLatency) { 375*71784e68SYinan Xu LazyModule(new AXI4MemoryWrapper(slave, memByte, useBlackBox)) 376*71784e68SYinan Xu } else { 377*71784e68SYinan Xu LazyModule(new AXI4RAMWrapper(slave, memByte, useBlackBox)) 378*71784e68SYinan Xu } 379*71784e68SYinan Xu memory 380*71784e68SYinan Xu } 381*71784e68SYinan Xu} 382