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 useBlackBox: Boolean = false, 25 executable: Boolean = true, 26 beatBytes: Int = 8, 27 burstLen: Int = 16 28)(implicit p: Parameters) 29 extends AXI4SlaveModule(address, executable, beatBytes, burstLen) 30{ 31 32 override lazy val module = new AXI4SlaveModuleImp(this){ 33 34 val offsetMask = address.mask.toInt 35 val memByte = offsetMask + 1 36 val offsetBits = log2Up(memByte) 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