fix BRAM slave so that it can correctly take all TileLink requests
This commit is contained in:
parent
e716661637
commit
aba13cee7f
@ -9,62 +9,74 @@ class BRAMSlave(depth: Int)(implicit val p: Parameters) extends Module
|
|||||||
with HasTileLinkParameters {
|
with HasTileLinkParameters {
|
||||||
val io = new ClientUncachedTileLinkIO().flip
|
val io = new ClientUncachedTileLinkIO().flip
|
||||||
|
|
||||||
val bram = SeqMem(depth, Bits(width = tlDataBits))
|
val bram = SeqMem(depth, Vec(tlDataBytes, UInt(width = 8)))
|
||||||
|
|
||||||
val (s0_get :: s0_getblk :: s0_put :: s0_putblk :: Nil) = Seq(
|
val s_idle :: s_getblk :: s_putblk :: s_resp :: Nil = Enum(Bits(), 4)
|
||||||
|
val state = Reg(init = s_idle)
|
||||||
|
|
||||||
|
val acq = io.acquire.bits
|
||||||
|
val r_acq = Reg(new AcquireMetadata)
|
||||||
|
|
||||||
|
val (is_get :: is_getblk :: is_put :: is_putblk :: Nil) = Seq(
|
||||||
Acquire.getType, Acquire.getBlockType, Acquire.putType, Acquire.putBlockType
|
Acquire.getType, Acquire.getBlockType, Acquire.putType, Acquire.putBlockType
|
||||||
).map(io.acquire.bits.isBuiltInType _)
|
).map(acq.isBuiltInType _)
|
||||||
|
|
||||||
val fire_acq = io.acquire.fire()
|
val beats = Reg(UInt(width = tlBeatAddrBits))
|
||||||
val fire_gnt = io.grant.fire()
|
|
||||||
|
|
||||||
val multibeat = Reg(init = Bool(false))
|
when (io.acquire.fire()) {
|
||||||
when (fire_acq) {
|
r_acq := acq
|
||||||
multibeat := s0_getblk
|
when (is_get || is_put || acq.isPrefetch()) {
|
||||||
|
state := s_resp
|
||||||
|
}
|
||||||
|
when (is_getblk) {
|
||||||
|
beats := UInt(tlDataBeats - 1)
|
||||||
|
state := s_getblk
|
||||||
|
}
|
||||||
|
/** Need to collect the rest of the beats.
|
||||||
|
* Beat 0 has already been accepted. */
|
||||||
|
when (is_putblk) {
|
||||||
|
beats := UInt(tlDataBeats - 2)
|
||||||
|
state := s_putblk
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when (state === s_getblk && io.grant.ready) {
|
||||||
|
r_acq.addr_beat := r_acq.addr_beat + UInt(1)
|
||||||
|
beats := beats - UInt(1)
|
||||||
|
when (beats === UInt(0)) { state := s_idle }
|
||||||
|
}
|
||||||
|
|
||||||
val last = Wire(Bool())
|
when (state === s_putblk && io.acquire.valid) {
|
||||||
val s0_valid = io.acquire.valid || (multibeat && !last)
|
beats := beats - UInt(1)
|
||||||
val s1_valid = Reg(next = s0_valid, init = Bool(false))
|
when (beats === UInt(0)) { state := s_resp }
|
||||||
val s1_acq = RegEnable(io.acquire.bits, fire_acq)
|
}
|
||||||
|
|
||||||
val s0_addr = Cat(io.acquire.bits.addr_block, io.acquire.bits.addr_beat)
|
when (state === s_resp && io.grant.ready) { state := s_idle }
|
||||||
val s1_beat = s1_acq.addr_beat + Mux(io.grant.ready, UInt(1), UInt(0))
|
|
||||||
val s1_addr = Cat(s1_acq.addr_block, s1_beat)
|
|
||||||
val raddr = Mux(multibeat, s1_addr, s0_addr)
|
|
||||||
|
|
||||||
last := (s1_acq.addr_beat === UInt(tlDataBeats-1))
|
val acq_addr = Cat(acq.addr_block, acq.addr_beat)
|
||||||
val ren = (io.acquire.valid && (s0_get || s0_getblk)) || (multibeat && !last)
|
val r_acq_addr = Cat(r_acq.addr_block, r_acq.addr_beat)
|
||||||
val wen = (io.acquire.valid && (s0_put || s0_putblk))
|
|
||||||
|
|
||||||
|
val ren = (io.acquire.fire() && (is_get || is_getblk)) ||
|
||||||
|
(state === s_getblk && io.grant.ready)
|
||||||
|
val raddr = Mux(state === s_idle, acq_addr,
|
||||||
|
Mux(io.grant.ready, r_acq_addr + UInt(1), r_acq_addr))
|
||||||
val rdata = bram.read(raddr, ren)
|
val rdata = bram.read(raddr, ren)
|
||||||
val wdata = io.acquire.bits.data
|
|
||||||
val wmask = io.acquire.bits.wmask()
|
|
||||||
assert(!wen || (wmask === Fill(tlDataBytes, Bool(true))),
|
|
||||||
"bram: subblock writes not supported")
|
|
||||||
when (wen) {
|
|
||||||
bram.write(s0_addr, wdata)
|
|
||||||
}
|
|
||||||
|
|
||||||
when (multibeat && fire_gnt) {
|
val wen = (io.acquire.fire() && (is_put || is_putblk))
|
||||||
s1_acq.addr_beat := s1_beat
|
val wdata = Vec.tabulate(tlDataBytes) { i => acq.data((i+1)*8-1, i*8) }
|
||||||
when (last) {
|
val wmask = Vec.tabulate(tlWriteMaskBits) { i => acq.wmask()(i) }
|
||||||
multibeat := Bool(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
io.grant.valid := s1_valid
|
when (wen) { bram.write(acq_addr, wdata, wmask) }
|
||||||
|
|
||||||
|
io.grant.valid := (state === s_resp) || (state === s_getblk)
|
||||||
io.grant.bits := Grant(
|
io.grant.bits := Grant(
|
||||||
is_builtin_type = Bool(true),
|
is_builtin_type = Bool(true),
|
||||||
g_type = s1_acq.getBuiltInGrantType(),
|
g_type = r_acq.getBuiltInGrantType(),
|
||||||
client_xact_id = s1_acq.client_xact_id,
|
client_xact_id = r_acq.client_xact_id,
|
||||||
manager_xact_id = UInt(0),
|
manager_xact_id = UInt(0),
|
||||||
addr_beat = s1_acq.addr_beat,
|
addr_beat = r_acq.addr_beat,
|
||||||
data = rdata)
|
data = rdata.toBits)
|
||||||
|
io.acquire.ready := (state === s_idle) || (state === s_putblk)
|
||||||
val stall = multibeat || (io.grant.valid && !io.grant.ready)
|
|
||||||
io.acquire.ready := !stall
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HastiRAM(depth: Int)(implicit p: Parameters) extends HastiModule()(p) {
|
class HastiRAM(depth: Int)(implicit p: Parameters) extends HastiModule()(p) {
|
||||||
|
Loading…
Reference in New Issue
Block a user