Skip to content

frontend: Eliminate external_pending launch deadlock (non-external next_id via rd_swacc)#147

Open
DanielKellerM wants to merge 1 commit into
develfrom
dk/idma070
Open

frontend: Eliminate external_pending launch deadlock (non-external next_id via rd_swacc)#147
DanielKellerM wants to merge 1 commit into
develfrom
dk/idma070

Conversation

@DanielKellerM

Copy link
Copy Markdown
Collaborator

Problem

Reading next_id launches a DMA. Since #73 the register frontend models next_id/status/done_id as PeakRDL external registers. peakrdl-regblock emits an external_pending latch driving cpuif_req_stall_rd/wr — a whole register-block stall while any external access is outstanding.

#134 then gated the external rd_ack on the decoded req strobe. But external_pending masks cpuif_req, so req is high for only one cycle; once external_pending latches, req drops to 0. If the arbiter grant (arb_ready) is not high in that first cycle, rd_ack = req & arb_ready can never fire again → external_pending is stuck high → the whole reg block is frozen. When the config port shares interconnect ordering with other traffic (e.g. a mem-tile DMA whose config slave shares a demux/NoC path with CPU stores), this frozen block back-pressures and deadlocks unrelated memory traffic.

The pre-0.7.0 (reggen) frontend never had this: next_id was hwext + hwre (a hardware-external register with a .re read strobe) — no external_pending, no whole-block stall; the read stalled only locally via the wrapper's reg-bus ready.

Fix

Model the observation registers as non-external, reproducing the reggen behaviour in PeakRDL:

With no external register, peakrdl emits external_pending = 0 and hardwires cpuif_req_stall = '0 — no whole-block stall, no deadlock, and no assert_bad_ext_rd_ack. The frontend fires the launch off rd_swacc; no ack handshake, no hold latch.

Relation to other PRs

This branch incorporates:

and fixes #134's launch-read deadlock via the next_idrd_swacc change.

Suggested merge order: #131#135 → this. It can also be merged standalone (it contains all three); if #131/#135 land first, this rebases down to just the next_idrd_swacc change + the rd_swacc UDP declaration.

Test

Validated on a Gwaihir mem-tile DMA (l2_dma L2↔L2 passthrough), where the config port shares the mem-tile demux/NoC path with CVA6 SPM stores. On devel + #134 this hard-deadlocks the SoC; with this fix it runs to completion (SLINK SUCCESS), matching the 0.6.5 baseline, with zero assertions.

…ernal status/done_id

Removes the peakrdl external_pending whole-block stall that #134's rd_ack
gating deadlocks against. next_id becomes a normal internal register with a
rd_swacc read-strobe (declared as a UDP) driving the launch, matching the
old reggen hwext+hwre behaviour: no external register, no cpuif_req_stall,
one-cycle read. Combined with the native-APB frontend (#131) and internal
status/done_id (#135).
@DanielKellerM DanielKellerM requested a review from micprog as a code owner July 3, 2026 14:07
Copilot AI review requested due to automatic review settings July 3, 2026 14:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants