1

I'm attempting to do these rather large DMA transfers over the frontbus to memory. The frontbus is ready and no other clients are contending for the front bus at the moment this occurs. My AXI client connected in its 15th 2kB transfer is unable to finish the transfer because the FifoFixer's stall signal goes high and never goes back down. I'm making an effort and hoping someone can help me to understand the following lines of code (as well as the other diplomatic widgets) to understand why stall goes high, the wready signal to the AXI client goes low, and the transaction never completes.

      val stalls = edgeIn.client.clients.filter(c => c.requestFifo && c.sourceId.size > 1).map { c =>
        val a_sel = c.sourceId.contains(in.a.bits.source)
        val id    = RegEnable(a_id, in.a.fire() && a_sel && !a_notFIFO)
        val track = flight.slice(c.sourceId.start, c.sourceId.end)

        a_sel && a_first && track.reduce(_ || _) && (a_noDomain || id =/= a_id)
      }

      val stall = stalls.foldLeft(Bool(false))(_||_)

The awaddr channel handshake occurs with the same aw channel id for each w channel transfer. enter image description here The Tilelink A channel handshake occurs for the first 64 bytes, and then the a_ready signal goes low forever even though the frontbus and the FifoFixer are receiving an a_ready high signal.

My diplomatic widget connection:

    ( dmaDDRNode 
        := TLBuffer(BufferParams.default)
        // := TLFIFOFixer(TLFIFOFixer.all) // included in fromPort
        := TLWidthWidget(8)
        := AXI4ToTL()
        := AXI4UserYanker(capMaxFlight=Some(16)) // Might want to cap max flight # but I don't know what that cap should be - ME
        := AXI4Fragmenter()
        := AXI4IdIndexer(idBits=3)
        // := AXI4Buffer()
        := dmaTop.ddrMaster)

fbus.fromPort(Some("DMA_DDR_MASTER"))() := dmaDDRNode 

I'm suspecting it could be the DMA engine using wready to determine the next wvalid? This could violate some decoupled assumption. It could have to do with capMaxFlight being 16, but all other transfers through the front bus complete.

metzkorn
  • 335
  • 2
  • 8

1 Answers1

1

The FifoFixer assures the d_source for the Put operation completes before starting the next A channel transfer. So, after sending the transfer in the screenshot (source 'hf), it waits for the d channel to provide an ack for 'hf. The d channel on the front bus seems to have stopped because one of the TL clients pulled d_ready down low forever. The AXI host associated with this TL client is holding its r_ready low after requesting a read, so the FifoFixer is holding stall high.

While the DAG property assures deadlock-free operation, Diplomacy cannot stop two source nodes from creating a "virtual" connection between each other. In my case, one of the AXI source nodes was requesting data that relied on another AXI source node completing its request. This ruined the DAG property and created deadlock.

metzkorn
  • 335
  • 2
  • 8