From e856cbe3a6db1559f2209c014161e07da3547128 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 6 Oct 2016 14:39:43 -0700 Subject: [PATCH] axi4: SRAM for testing --- src/main/scala/uncore/axi4/SRAM.scala | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/scala/uncore/axi4/SRAM.scala diff --git a/src/main/scala/uncore/axi4/SRAM.scala b/src/main/scala/uncore/axi4/SRAM.scala new file mode 100644 index 00000000..c2014f94 --- /dev/null +++ b/src/main/scala/uncore/axi4/SRAM.scala @@ -0,0 +1,67 @@ +// See LICENSE for license details. + +package uncore.axi4 + +import Chisel._ +import diplomacy._ + +class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4) extends LazyModule +{ + val node = AXI4SlaveNode(AXI4SlavePortParameters( + Seq(AXI4SlaveParameters( + address = List(address), + regionType = RegionType.UNCACHED, + executable = executable, + supportsRead = TransferSizes(1, beatBytes), + supportsWrite = TransferSizes(1, beatBytes), + interleavedId = Some(0))), + beatBytes = beatBytes)) + + // We require the address range to include an entire beat (for the write mask) + require ((address.mask & (beatBytes-1)) == beatBytes-1) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = node.bundleIn + } + + def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = + if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) + val mask = bigBits(address.mask >> log2Ceil(beatBytes)) + + val in = io.in(0) + val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8))) + + val r_addr = Cat((mask zip (in.ar.bits.addr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse) + val w_addr = Cat((mask zip (in.aw.bits.addr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse) + + in.aw.ready := in. w.valid && in.b.ready + in. w.ready := in.aw.valid && in.b.ready + in. b.valid := in.w.valid && in.aw.valid + + in.b.bits.id := in.aw.bits.id + in.b.bits.resp := AXI4Parameters.RESP_OKAY + val wdata = Vec.tabulate(beatBytes) { i => in.w.bits.data(8*(i+1)-1, 8*i) } + when (in.b.fire()) { + mem.write(w_addr, wdata, in.w.bits.strb.toBools) + } + + val r_full = RegInit(Bool(false)) + val r_id = Reg(UInt()) + + when (in. r.fire()) { r_full := Bool(false) } + when (in.ar.fire()) { r_full := Bool(true) } + + in. r.valid := r_full + in.ar.ready := in.r.ready || !r_full + + when (in.ar.fire()) { + r_id := in.ar.bits.id + } + + in.r.bits.id := r_id + in.r.bits.resp := AXI4Parameters.RESP_OKAY + in.r.bits.data := Cat(mem.read(r_addr, in.ar.fire()).reverse) + in.r.bits.last := Bool(true) + } +}