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