1// See LICENSE.SiFive for license details. 2 3package device 4 5import chisel3._ 6import chisel3.util._ 7import chisel3.util.experimental.loadMemoryFromFile 8 9import bus.axi4._ 10 11sealed abstract class RAM[T <: AXI4Lite](_type: T, 12 memByte: Int, beatBytes: Int = 4, dataFile: String = "") extends Module { 13 val io = IO(new Bundle{ 14 val in = Flipped(_type) 15 }) 16 17 val in = io.in 18 val mem = Mem(memByte / beatBytes, Vec(beatBytes, UInt(8.W))) 19 if (dataFile != "") loadMemoryFromFile(mem, dataFile) 20 21 val r_addr = in.ar.bits.addr >> log2Ceil(beatBytes) 22 val w_addr = in.aw.bits.addr >> log2Ceil(beatBytes) 23 24 val w_full = RegInit(false.B) 25 when (in. b.fire()) { w_full := false.B } 26 when (in.aw.fire()) { w_full := true.B } 27 28 val wdata = VecInit.tabulate(beatBytes) { i => in.w.bits.data(8*(i+1)-1, 8*i) } 29 when (in.aw.fire()) { 30 mem.write(w_addr, wdata, in.w.bits.strb.toBools) 31 } 32 33 in. b.valid := w_full 34 in.aw.ready := in. w.valid && (in.b.ready || !w_full) 35 in. w.ready := in.aw.valid && (in.b.ready || !w_full) 36 in.b.bits.resp := AXI4Parameters.RESP_OKAY 37 38 val r_full = RegInit(false.B) 39 when (in. r.fire()) { r_full := false.B } 40 when (in.ar.fire()) { r_full := true.B } 41 42 def holdUnless[T <: Data](x: T, enable: Bool): T = Mux(enable, x, RegEnable(x, enable)) 43 44 val ren = in.ar.fire() 45 val rdata = RegEnable(mem.read(r_addr), ren) 46 47 in. r.valid := r_full 48 in.ar.ready := in.r.ready || !r_full 49 in.r.bits.resp := AXI4Parameters.RESP_OKAY 50 in.r.bits.data := Cat(rdata.reverse) 51} 52 53class AXI4LiteRAM(memByte: Int, beatBytes: Int = 4, dataFile: String = "") 54 extends RAM(new AXI4Lite, memByte, beatBytes, dataFile) 55 56class AXI4RAM(memByte: Int, beatBytes: Int = 4, dataFile: String = "") 57 extends RAM(new AXI4, memByte, beatBytes, dataFile) { 58 59 in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 60 in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 61 in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 62 in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 63 in.r.bits.last := true.B 64} 65