Skip to content

axi_to_obi: Tie off the demux channels each converter never uses - #7

Open
DanielKellerM wants to merge 3 commits into
pulp-platform:fix-strbfrom
DanielKellerM:fix/rw-split-comb-loop
Open

DanielKellerM wants to merge 3 commits into
pulp-platform:fix-strbfrom
DanielKellerM:fix/rw-split-comb-loop

Conversation

@DanielKellerM

Copy link
Copy Markdown

Stacked on #6 (fix-strb), since that is the revision gwaihir uses.

The read/write demux in axi_to_obi only sends AR to the read converter and AW/W to the write converter, but the unused channels were still connected. Their ready/valid paths coupled the two converters, so a manager whose R ready depends on its W ready (iDMA does this) closes a combinational loop through the converter. SpyGlass reports it as CombLoop on the gwaihir mem tiles (iDMA -> axi_to_obi). The loop can never be sensitized, but it is a real gate cycle.

This ties off the dead channels (read converter AW/W/B, write converter AR) and, when UseAtop is off, the write converter R. No change in area or latency.

Checked with a lockstep Questa 2026.1 testbench, old vs new module driven by axi_rand_master, with every output compared each cycle: 0 mismatches for UseAtop=0/1 at AXI 32/64 bit, 3000 ATOPs in the UseAtop=1 runs. The Verilator lint warnings are the same as before. Together with the matching iDMA fix, gwaihir's mem_tile_small/mem_tile_large have 0 CombLoop.

The new assertion fires if an ATOP reaches a converter without UseAtop. Before, such an ATOP was done as a plain write and returned a junk R. Now its R is dropped.

The read/write demux only routes AR to the read converter and AW/W to the
write converter, but the unused channels were still wired, so ready and
valid paths of one converter fed the other. Combined with a manager whose
R ready depends on its W ready (e.g. iDMA), this forms a structural
combinational loop. Tie off the dead channels, and the write converter R
when ATOPs are disabled.

Legal traffic is unaffected. An ATOP sent to a converter without UseAtop
was never executed as an atomic; it now also trips an assertion.
Copilot AI balanced review requested due to automatic review settings October 6, 2026 10:11

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.

DanielKellerM added a commit to pulp-platform/gwaihir that referenced this pull request Oct 6, 2026
iDMA devel deploy 378fa46 (#267 on #271), pinned by commit until 0.7.4 is
tagged. axi_obi points at pulp-platform/axi_obi#7 until it merges.
@DanielKellerM

Copy link
Copy Markdown
Author

@Lore0599 @colluca need review here, solves combinational loop in mem-tile

hopang-0221 pushed a commit to pulp-platform/gwaihir that referenced this pull request Oct 9, 2026
iDMA devel deploy 378fa46 (#267 on #271), pinned by commit until 0.7.4 is
tagged. axi_obi points at pulp-platform/axi_obi#7 until it merges.
@Lore0599
Lore0599 force-pushed the fix/rw-split-comb-loop branch from d912bcf to 030136e Compare October 10, 2026 08:26
Lore0599 added a commit to pulp-platform/gwaihir that referenced this pull request Oct 11, 2026
* [Bender][hw][sw][CI] MXCore Feature and Kernel Updates

MXCore now supports accumulator preload for C += AxB

MXCore now supports BF16 output quantization

MXCore now supports multi-context configuration

[hw] MXCore interrupt on job(s) done only

[sw] Extended mxcore.c with PRELOAD/MULTI_JOB modes, disabled by default

[sw] Added mxcore_multi.c (with PRELOAD/MULTI_JOB) for work-splitting a large GEMM across 16 clusters

[CI] Extend CI with new MXCore kernels

* [Bender] Bump MXCore with Quantizer Fixes

Result scales are now unsigned/biased like the input scales, in line with OCP spec

* deps: Bump iDMA to devel for the planar MX layout

iDMA devel drops the inline 33 B MX block for separate data and E8M0
scale planes. Move l2_dma_mx_roundtrip to the planes, with a 2D quant and
dequant that step the scale plane by the scale stride. Pinned by commit
until iDMA 0.7.4 is tagged.

* hw: Wire the mx4 iDMA timing cuts (103) and frontend parameters

TimingCuts 103 (mx_beat_push, dfe_ready_ahead, dfe_reg_flags, wdp_head_spill,
outst_cnt_reg) and BufferDepth 3 to the backend; DataWidth and ComputeOps to
the reg64 frontends.

* deps: Bump iDMA to devel 6d64058 and axi_obi to the comb-loop fix

iDMA devel deploy 378fa46 (#267 on #271), pinned by commit until 0.7.4 is
tagged. axi_obi points at pulp-platform/axi_obi#7 until it merges.

* deps: Bump iDMA to v0.7.4

* sw: Add an iDMA to MXCore MX end-to-end test

The cluster DMA gathers FP32 A and B ([N][K]) from L2 and quantizes them
into MXCore's operand planes, MXCore runs the GEMM in FP32 and MXFP8, and
the DMA dequantizes the MXFP8 result. verify.py checks the operand planes
and the FP32 result bit-exactly; the result scale and dequant checks are
reported but not gating until #119, since MXCore writes signed result scales.

* sw: Gate the mx_e2e result scale, MXFP8 result and dequant checks

MXCore now writes E8M0 result scales (pulp-platform/MXCore#1), so the c_scale, c_mx and c_deq checks are bit-exact and gating.

* sw: Port mx_e2e to the MXCore preload register map

MXCore d45847f (#126) inserts the preload pointer and tile size registers; without the port the job never completes.

* sw: Add an FP16 variant of the MX end-to-end test

mx_e2e_fp16 runs the same flow from FP16 sources with the FP16 MX quant
and dequant ops. verify.py now takes its goldens from iDMA's
test/idma_mx_golden.h (quant/dequant) and MXCore's PyGolden (layout, GEMM,
result quantization) instead of local math, also checks the iDMA dequant of
the planes MXCore wrote, and checks canaries around every L2 output.

* sw: Preload the mx_e2e canaries and fix the golden pointer types

Core byte stores to the L2 canaries before the run made MXCore's result
port hang (HCI RQ-3 on the result mux) in both variants, so the canaries
are now part of the preloaded image. The ctypes goldens passed 64-bit
pointers as int, which truncated them and crashed verify.py.

* [hw] Minor mem tile rtl changes for timing improvement

* Fix lint issue

* Bump AXI obi

---------

Co-authored-by: Jayanth Jonnalagadda <jjonnalagadd@iis.ee.ethz.ch>
Co-authored-by: Hong Pang <hopang@iis.ee.ethz.ch>
Co-authored-by: Lorenzo Leone <lleone@iis.ee.ethz.ch>

@Lore0599 Lore0599 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.

I'm not the official maintainer of this repo but let me add few comments below.
In general I think the fixes you've done solve the comb loop.
My concerns are the following:

  1. To my understanding, it makes sense to tie off the R channels (and W) in your specific situation (DMA comb loop). However, when we have ATOP, the R path on the write adapter is actually used. Therefore, don't we have the comb loop risk again?
  2. For the reason above, I think it might make sense to add a spill register to cut the comb loop. Since this has a HW cost, and I think it's not a necessary cost in case of no ATOP support, I added it only in the atomic path.

In general, I have the feeling that R->W dependency is not really AXI compliant, therefore the coupling done by the DMA is not the best, even though I don't have a solution to it at the moment (except adding huge buffers in the DMA).
Perhaps in the ATOP support is less likely that the manager couples R-W, however I still think it's better to avoid the comb loop here instead of relying on the endpoint behaviour.

@micprog @colluca @DanielKellerM I would like to have your opinion regarding the comment above.

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.

4 participants