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