1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package device 18 19import chisel3._ 20import chisel3.util._ 21import difftest.common.DifftestMem 22import freechips.rocketchip.amba.axi4.AXI4SlaveNode 23import freechips.rocketchip.diplomacy.{AddressSet, LazyModule} 24import org.chipsalliance.cde.config.Parameters 25 26class AXI4RAM 27( 28 address: Seq[AddressSet], 29 memByte: Long, 30 useBlackBox: Boolean = false, 31 executable: Boolean = true, 32 beatBytes: Int = 8, 33 burstLen: Int = 16, 34)(implicit p: Parameters) 35 extends AXI4SlaveModule(address, executable, beatBytes, burstLen) 36{ 37 override lazy val module = new AXI4SlaveModuleImp(this){ 38 39 val offsetBits = log2Up(memByte) 40 41 require(address.length >= 1) 42 val baseAddress = address(0).base 43 44 def index(addr: UInt) = ((addr - baseAddress.U)(offsetBits - 1, 0) >> log2Ceil(beatBytes)).asUInt 45 46 def inRange(idx: UInt) = idx < (memByte / beatBytes).U 47 48 val wIdx = index(waddr) + writeBeatCnt 49 val rIdx = index(raddr) + readBeatCnt 50 val wen = in.w.fire && inRange(wIdx) 51 require(beatBytes >= 8) 52 53 val rdata = if (useBlackBox) { 54 val mem = DifftestMem(memByte, beatBytes) 55 when (wen) { 56 mem.write( 57 addr = wIdx, 58 data = in.w.bits.data.asTypeOf(Vec(beatBytes, UInt(8.W))), 59 mask = in.w.bits.strb.asBools 60 ) 61 } 62 val raddr = Mux(in.r.fire && !rLast, rIdx + 1.U, rIdx) 63 mem.readAndHold(raddr, in.ar.fire || in.r.fire).asUInt 64 } else { 65 val mem = Mem(memByte / beatBytes, Vec(beatBytes, UInt(8.W))) 66 67 val wdata = VecInit.tabulate(beatBytes) { i => in.w.bits.data(8 * (i + 1) - 1, 8 * i) } 68 when(wen) { 69 mem.write(wIdx, wdata, in.w.bits.strb.asBools) 70 } 71 72 Cat(mem.read(rIdx).reverse) 73 } 74 in.r.bits.data := rdata 75 } 76} 77 78class AXI4RAMWrapper ( 79 slave: AXI4SlaveNode, 80 memByte: Long, 81 useBlackBox: Boolean = false 82 )(implicit p: Parameters) extends AXI4MemorySlave(slave, memByte, useBlackBox) { 83 val ram = LazyModule(new AXI4RAM( 84 slaveParam.address, memByte, useBlackBox, 85 slaveParam.executable, portParam.beatBytes, burstLen 86 )) 87 ram.node := master 88} 89