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