1package device 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType} 7import xiangshan.HasXSParameter 8 9class RAMHelper(memByte: BigInt) extends BlackBox with HasXSParameter { 10 val io = IO(new Bundle { 11 val clk = Input(Clock()) 12 val rIdx = Input(UInt(DataBits.W)) 13 val rdata = Output(UInt(DataBits.W)) 14 val wIdx = Input(UInt(DataBits.W)) 15 val wdata = Input(UInt(DataBits.W)) 16 val wmask = Input(UInt(DataBits.W)) 17 val wen = Input(Bool()) 18 }) 19} 20 21class AXI4RAM 22( 23 address: AddressSet, 24 memByte: Long, 25 useBlackBox: Boolean = false, 26 executable: Boolean = true, 27 beatBytes: Int = 8, 28 burstLen: Int = 16 29)(implicit p: Parameters) 30 extends AXI4SlaveModule(address, executable, beatBytes, burstLen) 31{ 32 33 override lazy val module = new AXI4SlaveModuleImp(this){ 34 35 val offsetBits = log2Up(memByte) 36 val offsetMask = (1 << offsetBits) - 1 37 38 39 def index(addr: UInt) = ((addr & offsetMask.U) >> log2Ceil(beatBytes)).asUInt() 40 41 def inRange(idx: UInt) = idx < (memByte / 8).U 42 43 val wIdx = index(waddr) + writeBeatCnt 44 val rIdx = index(raddr) + readBeatCnt 45 val wen = in.w.fire() && inRange(wIdx) 46 47 val rdata = if (useBlackBox) { 48 val mem = Module(new RAMHelper(memByte)) 49 mem.io.clk := clock 50 mem.io.rIdx := rIdx 51 mem.io.wIdx := wIdx 52 mem.io.wdata := in.w.bits.data 53 mem.io.wmask := fullMask 54 mem.io.wen := wen 55 mem.io.rdata 56 } else { 57 val mem = Mem(memByte / beatBytes, Vec(beatBytes, UInt(8.W))) 58 59 val wdata = VecInit.tabulate(beatBytes) { i => in.w.bits.data(8 * (i + 1) - 1, 8 * i) } 60 when(wen) { 61 mem.write(wIdx, wdata, in.w.bits.strb.asBools()) 62 } 63 64 Cat(mem.read(rIdx).reverse) 65 } 66 in.r.bits.data := RegEnable(rdata, ren) 67 } 68} 69