Skip to content

feat: add native axi_to_apb converter - #431

Open
fischeti wants to merge 6 commits into
masterfrom
apb-converter
Open

feat: add native axi_to_apb converter#431
fischeti wants to merge 6 commits into
masterfrom
apb-converter

Conversation

@fischeti

@fischeti fischeti commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

This PR adds a native axi_to_apb converter, which supports both downsizing datawidth and truncating the address.

Current situation

It is already possible now to convert from AXI to APB but multiple modules are needed like 1) axi_to_axi_lite ─▶ axi_lite_to_apb or 2) axi_to_reg ─▶ reg_to_apb. Both add intermediate protocol signals and generally make the code more verbose. Further, 2) uses a non-standard protocol and pulls in register_interface as a dependency.

Also, 1) has the disadvantage that it pulls in a axi_to_axi_lite which has relatively heavy burst splitter and other components, which is overkill to convert to APB. Further, neither axi_to_axi_lite nor axi_lite_to_apb allow to natively downsize the datawidth, hence a axi_lite_dw_converter is also needed.

Exploration

I prototyped three ways to bridge AXI4+ATOP to APB4 and compared area (post-synth, gate equivalents):

Approach Area
axi_to_axi_liteaxi_lite_dw_converteraxi_lite_to_apb chain 11.6 kGE
axi_to_detailed_mem + inline APB master (this PR) 9.3 kGE ✅ chosen
Native AXI→APB FSM 8.3 kGE

The AXI4-Lite chain was the heaviest: it drags in burst splitting, and a Lite data-width converter.

A fully native FSM was the smallest (~10% below the chosen option), but it was vibecoded so not proven logic, and code complexity is higher.

The chosen axi_to_detailed_mem + inline APB master sits in between: it reuses axi_to_detailed_mem the AXI conversion. It is ~20% smaller than the Lite chain.

Verification

The adapter is verified with a tb_axi_to_apb testbench, that checks the APB interface for protocol compliancy, as well as an AXI scoreboard to check for correct data. I also added different types of slaves (ideal, random) to simulate backpressure.

@fischeti
fischeti force-pushed the apb-converter branch 3 times, most recently from 5f66dd6 to 9e222cd Compare July 3, 2026 07:48
@fischeti
fischeti marked this pull request as ready for review July 3, 2026 07:50
@fischeti
fischeti requested review from imchenwu, micprog and nikgiu July 3, 2026 07:50
@imchenwu
imchenwu changed the base branch from master to devel July 8, 2026 08:25

@nikgiu nikgiu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

While reviewing this I tried bumping OutFifoDepth to 2 in the testbench to see how the module behaves with more buffering, and the simulation blew up: Questa hits a zero-delay combinational loop (Autofindloop at 350 ns, X propagation, then vsimk SIGSEGV / exit 211). The loop it reports runs through mem_gnt/mem_rvalid in this module and back through the axi_to_detailed_mem response path (stream_join → stream_fork_dynamic).

Digging into it, I think the root cause is that bank_sel (and therefore apb_sel_idx) is purely combinational. It's the lzc output over mem_req, and it drives paddr/psel/pwdata/mem_gnt/… directly. So mem_gnt/mem_rvalid depend combinationally on mem_req, and once OutFifoDepth > 1 the front-end closes that path into a combinational cycle. With OutFifoDepth == 1 it happens to be safe only because a full depth-1 bank FIFO blocks the next beat's enqueue, so mem_req can't change mid-transfer.

I also think the same root cause can break the APB protocol even without hitting the loop: since the selection isn't frozen for the duration of a transfer, a lower-index bank asserting between SETUP and ACCESS shifts bank_sel/apb_sel_idx mid-transfer → SETUP is driven to one slave and ACCESS (penable) to another, and paddr/pwdata change while a transaction is in flight.

My suggestion would be to latch the selection at the SETUP→ACCESS transition and drive the bus from the latched values during ACCESS. That keeps the APB signals stable by construction and breaks the mem_req → bank_sel → mem_gnt combinational path, regardless of OutFifoDepth

Comment thread test/tb_axi_to_apb.sv Outdated
@fischeti

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review @nikgiu! I will dig into the issue when I find some time again. I will draft it again, until I have fixed the issue.

@fischeti
fischeti marked this pull request as draft July 13, 2026 07:34
imchenwu and others added 5 commits July 28, 2026 16:12
Document INCR/FIXED/WRAP burst behavior in the module headers of
axi_dw_converter, axi_dw_downsizer, and axi_dw_upsizer.

Closes #429.
… interfaces.

The original multi-dimensional interface module is not supported by many tools.
Downstream users can still trivially write their own intf wrapper.

Close #353.
…meter (#399)

* src: axi_fifo_delay_dyn: Fix incorrect power-of-two check for `Depth` parameter

The `axi_fifo_delay_dyn` module's parameter constraint checker incorrectly
identified valid `Depth` values as not being a power of two.

This commit corrects the logic to accurately verify that the `Depth`
parameter is a power of two.

* Update src/axi_fifo_delay_dyn.sv

---------

Co-authored-by: Chen Wu <chenwu@iis.ee.ethz.ch>
* Bump to common_cells v2

* fix(cc): fix cc_ module parameter names for common_cells v2

Update parameter names to match the actual cc_ module API in v2-test:
- cc_delta_counter: Width->WIDTH, StickyOverflow->STICKY_OVERFLOW
- cc_stream_register: data_t->T
- cc_fifo: FallThrough->FALL_THROUGH, Depth->DEPTH, data_t->dtype
- cc_counter: Width->WIDTH

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* hw: Align mux and demux to common_cells v2

* hw: Align params name to common cells v2-test

* hw: Remove test_i ports

* hw: clean up dead test_i ports and use cc_pkg::lzc_mode_e enum for the cc_lzc MODE parameter.

* fixed indentation

* bumped common-cells v2.0.0-beta and tech-cells-generic 0.2.14

* bumped common2 fixes for synopsis tools

* scripts: add target cc_no_deprecated

* deps: Bump `common_cells` to `v2.0.0-beta.2`

---------

Co-authored-by: Lorenzo Leone <lleone@iis.ee.ethz.ch>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Chen Wu <chenwu@iis.ee.ethz.ch>
Co-authored-by: Niccolò Giuliani <niccolo.giuliani44@gmail.com>
@fischeti
fischeti marked this pull request as ready for review July 31, 2026 11:52
@fischeti

Copy link
Copy Markdown
Contributor Author

You were right with your analysis @nikgiu! And I think your proposed fix is indeed the simplest option. I pushed some changes and also rebased to devel now.

@nikgiu

nikgiu commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Thank you @fischeti ! Looks legit to me

@nikgiu
nikgiu self-requested a review August 4, 2026 11:32
@nikgiu
nikgiu changed the base branch from devel to master September 9, 2026 06:10
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.

5 participants