Width Conversion - 2.1 English - PG059

AXI Interconnect LogiCORE IP Product Guide (PG059)

Document ID
PG059
Release Date
2025-12-19
Version
2.1 English

Each of the SI and MI on the AXI Interconnect core can be individually configured to have a data width of 32, 64, 128, 256, 512, or 1024 bits. When the data width of an interface is configured differently than the data width of the internal Crossbar, a width conversion module is automatically instantiated along the pathway.

The width conversion functions differ depending on whether the datapath width gets wider (upsizing) or narrower (downsizing) when moving in the direction from the SI toward the MI. The width conversion functions are the same in either the SI hemisphere (translating from an SI to the Crossbar) or the MI hemisphere (translating from the Crossbar to a MI).

Selecting a sufficiently high-data width for the AXI Crossbar can avoid loss of data bandwidth. For example, you could elect to set the AXI Crossbar to match the width of a speed-critical slave, such as a memory controller, even though all the masters that access that slave have narrower data widths.

With that setting, the AXI Interconnect core can perform data packing (Write transactions) or serialization (Read transactions) concurrently along multiple SI slot pathways in the SI hemisphere while the wide slave device and crossbar periodically maintain a data throughput rate higher than any one master device can sustain.

In contrast, selecting a lower data width for the AXI Crossbar can reduce logic resource utilization for less speed-critical designs. When seeking to minimize resource utilization, set the data width of the AXI Crossbar so that it minimizes the total number of width converters.

The following table lists the transformations performed by the Data Width Converter for various parametric configurations and incident SI transactions. Table 2 provides details of the resulting output (MI-side) transactions for each of the transformations. Use the Transformation Formula name in Table 1 as an index into Table 2.

The following tables use these following designators when describing properties, signals, and derived equations.

  1. si.DW = SI_DATA_WIDTH
  2. mi.DW = MI_DATA_WIDTH
  3. si.LEN = S_AXI_AWLEN or C_S_AXI_ARLEN, as applicable
  4. si.ADDR = S_AXI_AWADDR or C_S_AXI_ARADDR, as applicable
  5. si.Bytes = si.DW / 8
  6. mi.Bytes = mi.DW / 8
  7. mi.ByteMask = mi.Bytes – 1
  8. si.SIZE = S_AXI_AWSIZE or S_AXI_ARSIZE, as applicable
  9. si.SizeMask = (2**si.SIZE) – 1
  10. mi.SizeMask = (2**mi.SIZE) – 1
  11. mi.AlignedStart = si.ADDR & ~mi.ByteMask
  12. mi.AlignedEnd = ((si.ADDR & ~si.SizeMask) + (si.LEN * 2**si.SIZE)) & ~mi.ByteMask
  13. mi.upsize_LEN = (mi.AlignedEnd - mi.AlignedStart) / mi.Bytes
  14. si.conv_ratio = ceil((2**si.SIZE) / mi.Bytes)
  15. si.downsize_LEN = (si.LEN+1) * si.conv_ratio - 1
  16. mi.AlignedAdjustment = (si.ADDR & si.SizeMask & ~mi.ByteMask) / mi.Bytes
  17. si.burst_bytes = 2**si.SIZE * (si.LEN+1)
  18. si.burst_mask = si.burst_bytes - 1
  19. si.wrap_address = si.ADDR & ~si.burst_mask
  20. si.wrap1_LEN = (si.burst_bytes - (si.ADDR & si.burst_mask)) / mi.Bytes - 1
  21. si.wrap2_LEN = (si.ADDR & si.burst_mask) / mi.Bytes - 1
  22. Downsize_ratio = ceil((2**si.SIZE) / (MI_DATA_WIDTH / 8))
  23. MI beats = SI beats * Downsize_ratio (less MI beats skipped due to unaligned ADDR)
  24. max_beats = 256 if (PROTOCOL == AXI4), 16 if (PROTOCOL == AXI3)
Table 1. AXI Data Width Converter Functional Truth Table
DATA_WIDTH s_axi_a*burst PROTOCOL Input Conditions Resulting Output Transformation Formula
SI > MI (downsizer) b01 (INCR) 0 (AXI4) downsize_ratio = 1 Transaction unchanged Pass-through Downsize
1 (AXI3) downsize_ratio = 1 Transaction unchanged Pass-through Downsize
0 (AXI4) MI beats <= 256, downsize_ratio > 1 1 burst INCR Downsize
0 (AXI4) MI beats > 256, downsize_ratio > 1 Split into max 256-beat bursts Split INCR Downsize
1 (AXI3) MI beats <= 16, downsize_ratio > 1 1 burst INCR Downsize
1 (AXI3) MI beats > 16, downsize_ratio > 1 Split into max 16-beat bursts Split INCR Downsize
b10 (WRAP) 0 (AXI4) or 1 (AXI3) downsize_ratio = 1 Transaction unchanged (remains WRAP)

Pass-through Downsize

0 (AXI4) or 1 (AXI3) MI beats <= 16, downsize_ratio > 1

1 burst

(remains WRAP)

WRAP Downsize
0 (AXI4) 16 < MI beats <= 256, ADDR is burst-aligned 1 burst; change to INCR WRAP-to-INCR Downsize
0 (AXI4) 16 < MI beats <= 256, ADDR is not burst-aligned (wrapping required) Split into 2 bursts; change to INCR WRAP-to-INCR Downsize
0 (AXI4) MI beats > 256 Split into max 256-beat bursts; change to INCR Split WRAP-to-INCR Downsize
1 (AXI3) MI beats > 16 Split into max 16-beat bursts; change to INCR Split WRAP-to-INCR Downsize
b00 (FIXED) 0 (AXI4) or 1 (AXI3) downsize_ratio = 1 Transaction not modified (remains FIXED) Pass-through Downsize
0 (AXI4) downsize_ratio > 1 Split into (s_axi_alen + 1) bursts; change to INCR FIXED-to-INCR Downsize
SI > MI (downsizer) (continued) b0b00 (FIXED) (continued) 1 (AXI3) 1 < downsize_ratio <= 16 Split into (s_axi_alen + 1) bursts; change to INCR FIXED-to-INCR Downsize
1 (AXI3) downsize_ratio > 16 Split into max 16-beat bursts; change to INCR Split FIXED-to-INCR Downsize
x 2 (AXI4-Lite) Write && ~s_axi_awaddr[2] && (s_axi_wstrb[7:4] != 0) && (s_axi_wstrb[3:0] != 0) Split into 2 transactions Lite Split Downsize
Write && ~s_axi_awaddr[2] && (s_axi_wstrb[7:4] == 0) Transaction not modified Lite Low-order Write Downsize
Write && (s_axi_awaddr[2] || ((s_axi_wstrb[7:4] != 0) && (s_axi_wstrb[3:0] == 0))) One transaction with m_axi_awaddr = s_axi_awaddr | 'b100; m_axi_wdata = s_axi_wdata[63:32] Lite Unaligned Downsize
Read && ~s_axi_araddr[2] Split into 2 transactions Lite Split Downsize
Read && s_axi_araddr[2] Transaction not modified; s_axi_rdata[63:32] = m_axi_rdata; s_axi_rdata[31:0] undetermined Lite Unaligned Downsize
SI < MI (upsizer) 0 (AXI4) or 1 (AXI3) ~S_AXI_A*CACHE[1] Transaction not modified Pass-through Upsize
b01 (INCR) x S_AXI_A*CACHE[1] 1 burst INCR Upsize
b10 (WRAP) 0 (AXI4) or 1 (AXI3) S_AXI_A*CACHE[1] 1 burst WRAP Upsize
b00 (FIXED) 0 (AXI4) or 1 (AXI3) x Transaction not modified Pass-through Upsize
x 2 (AXI4-Lite) x Transaction not modified Pass-through Upsize
Table 2. AXI Data Width Converter Transaction Transformation Formulae
Transformation Formula Conditions Output Transactions Output (MI) LEN Output (MI) ADDR Output (MI) BURST Output (MI) LOCK
Pass-through Downsize 1 x 1 No Change No Change s_axi_a*burst s_axi_a*lock
INCR Downsize 2 x 1 si.downsize_LEN - mi.AlignedAdjustment

No Change

INCR s_axi_a*lock
Split INCR Downsize 2 x ceil((si.downsize_LEN+1) / max_beats)

first = max_beats -mi.AlignedAdjustmi.AlignedAdjustment - 1;

last =si.downsize_LEN %max_beats;

others =max_beats - 1

first = si.ADDR;

transaction i =(si.ADDR & ~si.SizeMask ) + ((i-1) *max_beats*mi.Bytes)

INCR 0
WRAP Downsize 2 x 1 si.downsize_LEN No change WRAP s_axi_a*lock
WRAP-to-INCR Downsize 2

if ((si.ADDR & si.burst_mask ) == 0)

else

1 si.wrap1_LEN si.ADDR INCR s_axi_a*lock
2

first =si.wrap1_LEN ;

second =si.wrap2_LEN

first = si.ADDR;

second = si.wrap_address

INCR 0
Split WRAP-to-INCR Downsize 2 if ((si.ADDR & si.burst_mask ) == 0) ceil ((si.wrap1_LEN+1) / max_beats) all = max_beats

first = si.ADDR;

transaction i = (si.ADDR & ~si.SizeMask) + ((i-1) *max_beats*mi.Bytes)

INCR 0
else ceil ((si.wrap1_LEN+1) / max_beats) + ceil ((si.wrap2_LEN+1) / max_beats) all = max_beats first = si.ADDR; (others TBD, wrap as required) INCR 0
FIXED-to-INCR Downsize 2 x si.LEN+1 all = max(si.conv_ratio - mi.AlignedAdjustment - 1, 0) all = si.ADDR INCR 0
Split FIXED-to-INCR Downsize 2 x

(si.LEN+1) *int((si.conv_ratio -mi.AlignedAdjustment) / max_beats)

first = (si.conv_ratio - mi.AlignedAdjustment - 1) % max_beats;

others = max_beats - 1

first = si.ADDR; (others TBD, repeat si.ADDR or increment as needed) INCR 0
Lite Split Downsize x 2 N/A (0) first = si.ADDR; second = si.ADDR | 'b100 N/A (singles) N/A
Lite Low-order Write Downsize x 1 N/A (0) si.ADDR N/A (singles) N/A
Lite Unaligned Downsize x 1 N/A (0) si.ADDR | 'b100 N/A (singles) N/A
Pass-through Upsize 1 x 1 No change No change s_axi_a*burst s_axi_a*lock
INCR Upsize 2 x 1 mi.upsize_LEN No change INCR s_axi_a*lock
WRAP Upsize 2 Write 1 ceil((si.LEN+1) * (2**si.SIZE) /mi.Bytes) - 1 si.wrap_address + (ceil((si.ADDR & si.burst_mask ) / mi.Bytes) * mi.Bytes) % si.burst_bytes If (mi.LEN>0) then WRAP, else INCR s_axi_a*lock
Read 1 ceil((si.LEN+1) * (2**si.SIZE )/mi.Bytes ) - 1 si.wrap_address + (int((si.ADDR & si.burst_mask) / mi.Bytes ) * mi.Bytes ) (If mi.LEN>0) then WRAP, else INCR s_axi_a*lock
  1. Output (MI) SIZE = si.SIZE
  2. Output (MI) SIZE = log2(mi.Bytes)