xref: /XiangShan/src/main/scala/device/AXI4RAM.scala (revision 0341d9bdd8dca6d3e05f5bd0b6f71bdab7f0decd)
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