Width Conversion - 2.1 English

AXI Interconnect LogiCORE IP Product Guide (PG059)

Document ID
PG059
Release Date
2022-05-17
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.

Table: AXI Data Width Converter Functional Truth Table lists the transformations performed by the Data Width Converter for various parametric configurations and incident SI transactions. Table: AXI Data Width Converter Transaction Transformation Formulae provides details of the resulting output (MI-side) transactions for each of the transformations. Use the Transformation Formula name in Table: AXI Data Width Converter Functional Truth Table as an index into Table: AXI Data Width Converter Transaction Transformation Formulae.

Table: AXI Data Width Converter Functional Truth Table and Table: AXI Data Width Converter Transaction Transformation Formulae 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 3-1:      AXI Data Width Converter

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

Functional Truth Table

 

 

Table 3-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.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

Notes:

1.Output (MI) SIZE = si.SIZE

2.Output (MI) SIZE = log2(mi.Bytes)