Deadlocks & Dependencies

How poor system design can cause the bus to hang forever (Deadlock), and the AXI rules to prevent it.

What is an AXI Deadlock?

A deadlock occurs when Component A is waiting for Component B to do something, while Component B is waiting for Component A. Neither can proceed, and the bus hangs.

The Golden Rule of AXI

VALID must NOT depend on READY.

A sender cannot wait for the receiver to be ready before asserting VALID. It must assert VALID whenever it has data. Wait for READY only to deassert/complete the handshake.

Classic Deadlock Scenarios

1. The "Read-Write" Dependency

Imagine a weird Master that refuses to accept a Write Response (B channel) until it has finished receiving Read Data (R channel).

  • State: Master sends a Write Command AND a Read Command to a Slave.
  • Slave: It processes the Write first and sends BVALID. It holds the Read data back until the Write is done (to ensure consistency).
  • Master: It sees BVALID but refuses to assert BREADY because it is waiting for RVALID (Read Data).
  • Slave: It waits for BREADY before sending RVALID.
  • Result: DEADLOCK.

2. Interconnect Deadlock (Cyclic)

Master 1 -> Slave 2. (Waiting for path).
Master 2 -> Slave 1. (Waiting for path).

If the interconnect uses a simple "Hold one path until done" arbiter without priority escalation or independent channels, this can lock up.

AXI Ordering Rules to Prevent Deadlock

AXI spec enforces strict dependency rules:

  • Read Transaction: ARVALID cannot wait for ARREADY. RVALID cannot wait for RREADY.
  • Write Transaction: AWVALID cannot wait for AWREADY. WVALID cannot wait for WREADY. BVALID cannot wait for BREADY.
  • Write Data: The Master is allowed to wait for Address Handshake (AWREADY) before sending Data (WVALID), but it is generally recommended to send early if possible.
  • Write Response: The Slave MUST wait for both Address (AW) and Data (W) before sending Response (B).

Debugging a Deadlock

When your simulation hangs time 999999ns, check the waveforms:

  1. Look for VALID=1 and READY=0 persisting for a long time.
  2. Trace back: Why is READY low?
  3. Is the component waiting for another channel? (e.g., waiting for Read Data before accepting Write Response).