'What does it mean that `the Q must be ready faster than the response` for the AXI4 User Yanker assertion?
I'm attempting to perform a DMA that involves an AXI master fetching from an AXI slave. For simplicity, I elected to hook this system up through the TL front bus and system bus instead of directly to each other since other masters might need to access the AXI slave. I'm using Rocket Chip's default MMIO port. I've invoked it with the following MasterPortParams.
class WithMMIOPort extends Config((site, here, up) => {
case ExtBus => Some(MasterPortParams(
base = x"4000_0000",
size = x"2000_0000",
beatBytes = site(MemoryBusKey).beatBytes,
idBits = 4))
})
Here's the MMIO port for reference.
trait CanHaveMasterAXI4MMIOPort { this: BaseSubsystem =>
private val mmioPortParamsOpt = p(ExtBus)
private val portName = "mmio_port_axi4"
private val device = new SimpleBus(portName.kebab, Nil)
val mmioAXI4Node = AXI4SlaveNode(
mmioPortParamsOpt.map(params =>
AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = AddressSet.misaligned(params.base, params.size),
resources = device.ranges,
executable = params.executable,
supportsWrite = TransferSizes(1, params.maxXferBytes),
supportsRead = TransferSizes(1, params.maxXferBytes))),
beatBytes = params.beatBytes)).toSeq)
mmioPortParamsOpt.map { params =>
sbus.coupleTo(s"port_named_$portName") {
(mmioAXI4Node
:= AXI4Buffer()
:= AXI4UserYanker()
:= AXI4Deinterleaver(sbus.blockBytes)
:= AXI4IdIndexer(params.idBits)
:= TLToAXI4()
:= TLWidthWidget(sbus.beatBytes)
:= _)
}
}
And here's the master node that's trying to issue a write.
(dmaHstNode
:= TLBuffer(BufferParams.default)
// := TLFIFOFixer(TLFIFOFixer.all)
:= TLWidthWidget(8)
:= AXI4ToTL()
:= AXI4UserYanker(capMaxFlight=Some(16))
:= AXI4Fragmenter()
:= AXI4IdIndexer(idBits=3)
:= AXI4Buffer()
:= dmaTop.hstMaster)
// }
It begins issuing the write, but then I encounter an assertion failure
assert (!out.b.valid || b_valid) // Q must be ready faster than the response
I'm trying to understand what this assertion is suggesting. It comes from the UserYanker. Here it is in context
val bid = out.b.bits.id
val b_valid = Vec(wqueues.map(_.deq.valid))(bid)
val b_bits = Vec(wqueues.map(_.deq.bits))(bid)
assert (!out.b.valid || b_valid) // Q must be ready faster than the response
in.b :<> out.b
in.b.bits.echo :<= b_bits
My best guess is b.valid is going high before the UserYanker has space in its queue? Does this mean I need larger queues? If that's the case, what parameter would increase the UserYanker's queue size? Would it be maxFlight? Is this some sort of protocol translation issue from Tilelink to axi4? I'm not familiar with the specifics of either, but maybe the conversion to Tilelink should be skipped in this case?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|