1package device 2 3import chisel3._ 4import chisel3.util._ 5import chisel3.util.experimental.loadMemoryFromFile 6 7import bus.axi4._ 8import utils._ 9 10class RAMHelper(memByte: Int) extends BlackBox { 11 val io = IO(new Bundle { 12 val clk = Input(Clock()) 13 val rIdx = Input(UInt(64.W)) 14 val rdata = Output(UInt(64.W)) 15 val wIdx = Input(UInt(64.W)) 16 val wdata = Input(UInt(64.W)) 17 val wmask = Input(UInt(64.W)) 18 val wen = Input(Bool()) 19 }) 20} 21 22class AXI4RAM[T <: AXI4Lite](_type: T = new AXI4, memByte: Int, beatBytes: Int = 8, 23 useBlackBox: Boolean = false) extends AXI4SlaveModule(_type) { 24 25 val offsetBits = log2Up(memByte) 26 val offsetMask = (1 << offsetBits) - 1 27 def index(addr: UInt) = (addr & offsetMask.U) >> log2Ceil(beatBytes) 28 def inRange(idx: UInt) = idx < (memByte / 8).U 29 30 val wIdx = index(waddr) + writeBeatCnt 31 val rIdx = index(raddr) + readBeatCnt 32 val wen = in.w.fire() && inRange(wIdx) 33 34 val rdata = if (useBlackBox) { 35 val mem = Module(new RAMHelper(memByte)) 36 mem.io.clk := clock 37 mem.io.rIdx := rIdx 38 mem.io.wIdx := wIdx 39 mem.io.wdata := in.w.bits.data 40 mem.io.wmask := Cat(in.w.bits.strb.asBools.map(Mux(_, 0xff.U, 0.U)).reverse) 41 mem.io.wen := wen 42 mem.io.rdata 43 } else { 44 val mem = Mem(memByte / beatBytes, Vec(beatBytes, UInt(8.W))) 45 46 val wdata = VecInit.tabulate(beatBytes) { i => in.w.bits.data(8*(i+1)-1, 8*i) } 47 when (wen) { mem.write(wIdx, wdata, in.w.bits.strb.asBools) } 48 49 Cat(mem.read(rIdx).reverse) 50 } 51 52 in.r.bits.data := RegEnable(rdata, ren) 53} 54