68 lines
2.2 KiB
Scala
68 lines
2.2 KiB
Scala
|
// 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)
|
||
|
}
|
||
|
}
|