Vyges Infrastructure IP | vyges/tlul-apb-adapter@0.1.0
A generic, parameterized TileLink Uncached Lightweight (TL-UL) slave to AMBA APB master protocol adapter. Enables any APB peripheral to be connected to a TL-UL bus fabric (Ibex, OpenTitan) without modification to either side.
TL-UL Crossbar APB Peripheral
┌──────────────┐ ┌──────────────┐
│ device port ├─── tlul_apb_adapter ───┤ APB slave │
└──────────────┘ └──────────────┘
(Ibex / OpenTitan) (GPIO, UART, FFT, ...)
The adapter translates the TL-UL A/D channel handshake to the APB setup/access phase sequence, handles PREADY wait-state extension, propagates APB4 PSLVERR to TL-UL d_error, and echoes a_source in d_source for correct crossbar routing.
Key properties:
- Zero buffering — single-outstanding constraint enforced by design
- Minimum 3-cycle latency (zero-wait APB slave)
- ~50–80 standard cells (SKY130); 40 LUTs (FPGA)
- APB3 and APB4 support via
APB4_ENparameter - OpenTitan/Ibex TL-UL struct compatible; ships a standalone
tlul_pkg.svfor use withoutopentitan-tlul
rtl/
tlul_apb_adapter.sv Main adapter module
standalone/
tlul_pkg.sv Minimal TL-UL type definitions — standalone use only
(see "tlul_pkg and opentitan-tlul" below)
tb/
tb_tlul_apb_adapter.sv SystemVerilog testbench (TC01–TC08)
cocotb/
test_tlul_apb_adapter.py cocotb test suite (TC01–TC09)
Makefile
docs/
tlul_apb_adapter_design_specification.md Interface definition, timing, verification plan
tlul_apb_adapter_architecture.md Internal architecture, design decisions
fft_integration_guide.md Step-by-step FFT APB integration example
examples/
fft_tlul_wrapper.sv Flat-signal wrapper: adapter + Vyges FFT Accelerator
(standalone / non-OpenTitan crossbar)
fft_ctrl_tlul_struct.sv Struct-interface wrapper using tl_h2d_t / tl_d2h_t
(SoC integration — requires opentitan-tlul)
constraints/
tlul_apb_adapter.sdc Timing constraints (OpenLane/Synopsys)
vyges-metadata.json Vyges IP catalog metadata
Use this pattern when your TL-UL host drives flat signals directly (no tlul_pkg structs).
tlul_apb_adapter #(
.AW (32),
.DW (32),
.SOURCE_WIDTH(8),
.APB4_EN (1) // 1=APB4 (PSTRB/PSLVERR), 0=APB3
) u_tlul_apb_periph (
.clk_i (clk),
.rst_ni (rst_n),
// TL-UL slave (connect to xbar device port)
.tl_a_valid_i (...), .tl_a_opcode_i (...),
.tl_a_param_i (...), .tl_a_size_i (...),
.tl_a_source_i (...), .tl_a_address_i(...),
.tl_a_mask_i (...), .tl_a_data_i (...),
.tl_a_ready_o (...),
.tl_d_valid_o (...), .tl_d_opcode_o (...),
.tl_d_param_o (...), .tl_d_size_o (...),
.tl_d_source_o (...), .tl_d_error_o (...),
.tl_d_data_o (...), .tl_d_ready_i (...),
// APB master (connect to peripheral)
.apb_psel_o (...), .apb_penable_o (...),
.apb_pwrite_o (...), .apb_paddr_o (...),
.apb_pwdata_o (...), .apb_pstrb_o (...),
.apb_pprot_o (...),
.apb_prdata_i (...), .apb_pready_i (...),
.apb_pslverr_i (...)
);See examples/fft_tlul_wrapper.sv for a complete flat-signal example.
When integrating with a TL-UL crossbar generated by soc-generator or OpenTitan (which uses
tlul_pkg::tl_h2d_t / tl_d2h_t struct ports), wrap the adapter in a thin flattening module.
tlul_apb_adapter uses flat signals — the crossbar uses struct types — a one-level wrapper
bridges the two.
// In your peripheral wrapper (e.g. fft_ctrl_tlul.sv):
module my_periph_tlul
import tlul_pkg::*;
(
input logic clk_i, rst_ni,
input tlul_pkg::tl_h2d_t tl_i, // from xbar slave port
output tlul_pkg::tl_d2h_t tl_o
);
// Flatten struct → flat signals
logic tl_a_valid; assign tl_a_valid = tl_i.a_valid;
// ... (see examples/fft_ctrl_tlul_struct.sv for full flatten)
tlul_apb_adapter #(.AW(32), .DW(32), .SOURCE_WIDTH(8), .APB4_EN(1))
u_adapter (
.clk_i(clk_i), .rst_ni(rst_ni),
.tl_a_valid_i(tl_a_valid), // ... flat signals
.apb_prdata_i(prdata), .apb_pready_i(pready), .apb_pslverr_i(1'b0)
);
// ... instantiate your APB peripheral
endmoduleSee examples/fft_ctrl_tlul_struct.sv for the complete
SoC integration pattern (used in vyges/edge-sensor-soc). Requires opentitan-tlul.
cocotb + Verilator (primary):
make sim
# or directly:
cd tb/cocotb && makeLint:
make lint| Parameter | Default | Description |
|---|---|---|
AW |
32 | Address width (bits, must be ≤ 32) |
DW |
32 | Data width (must be 32) |
SOURCE_WIDTH |
8 | TL-UL source/sink ID width |
APB4_EN |
1 | 1=APB4 (PSTRB/PPROT/PSLVERR), 0=APB3 |
| Scenario | Latency (cycles) |
|---|---|
| Zero-wait APB slave | 3 |
| N-wait-state APB slave | 3 + N |
| Max throughput | 1 transaction / 3 cycles |
tlul_apb_adapter uses flat port signals and does not depend on tlul_pkg internally.
The package is only needed in the wrapper layer when connecting to a struct-interface crossbar.
| Context | Which tlul_pkg.sv to use |
|---|---|
| Standalone use (no OpenTitan crossbar) | rtl/standalone/tlul_pkg.sv — minimal subset shipped in this repo |
| SoC with OpenTitan / soc-generator xbar | opentitan-tlul dependency — do not also include rtl/standalone/tlul_pkg.sv |
The standalone copy is a structural subset: it is missing d_sink, TL_DIW,
TL_H2D_DEFAULT, and TL_D2H_DEFAULT relative to the full opentitan-tlul package.
Using it alongside opentitan-tlul will cause package redefinition errors. The ifndef
guard prevents double-compilation but the field mismatch will cause downstream failures.
When compiling with Verilator and opentitan-tlul is present: include only
rtl/tlul_apb_adapter.sv explicitly — do not pass rtl/ as a -y directory.
Two integration examples are provided for the Vyges FFT Accelerator:
| Example | Interface | Use case |
|---|---|---|
examples/fft_tlul_wrapper.sv |
Flat TL-UL signals | Standalone, non-OpenTitan crossbar |
examples/fft_ctrl_tlul_struct.sv |
tl_h2d_t / tl_d2h_t structs |
SoC integration with soc-generator or OpenTitan xbar |
See docs/fft_integration_guide.md for a step-by-step walkthrough.
The struct example is the pattern used in vyges/edge-sensor-soc (ChipFoundry Design Contest 2026).
- Bus fabrics: OpenTitan TL-UL crossbar, Ibex RISC-V SoC, soc-generator xbar, any TL-UL-compliant fabric
- Simulators: Verilator (primary), ModelSim/Xcelium
- Synthesis: Yosys, Synopsys Design Compiler, Vivado
- PDKs: SKY130 (OpenLane), GF180MCU (OpenLane), any standard cell process
- FPGA: Xilinx 7-series/UltraScale, Intel Cyclone/Arria, Lattice iCE40/ECP5
- Dependencies: none (standalone);
opentitan-tlul(optional, for struct-interface SoC integration)
Copyright 2026 Vyges Inc.
Licensed under the Apache License, Version 2.0.
- vyges/fast-fourier-transform-ip — FFT accelerator with APB/AXI interfaces
- Vyges IP Catalog — Curated open-source silicon IP