This guide explains how to create a simple Aurora 64B/66B test design for the Kria 260 Robotics Kit in Vivado 2024.2. It is intended for engineers who are new to the project and need a clear, repeatable setup path without unnecessary background detail.
The design uses a single GTH transceiver lane, AXI4-Stream data, and internal or passive SFP+ loopback to verify link bring-up and data integrity.
What this guide covers· Creating a Vivado project for the Kria 260 Robotics Kit SOM and carrier connection.
· Configuring the Aurora 64B/66B IP for a single-lane GTH link.
· Adding simple AXI4-Stream transmitter and receiver-checker IP blocks.
· Connecting the block design, applying basic constraints, and validating the link with ILA signals.
Background: MGTs, GTH / GTR and AuroraMulti-Gigabit Transceivers (MGTs) are hardened FPGA blocks used to transmit and receive serial data at very high speeds. They provide the physical layer: serialization, deserialization, clock recovery, and high-speed differential I/O. However, they do not define how user data is framed, aligned, or checked. A link-layer protocol is still required.
GTX, GTH and GTR in simple termsWhen we are working with Zynq UltraScale+ MPSoCs we mainly have to work with GTR/GTH Transcievers.
GTRs are hardwired into Processing System (PS) side of Ultrascale+ MPSoC. They are optimized for standard industry protocols. For example, when USB 3.0 port or a display output is needed to be used on Kria board, GTR transceivers are always the choise, as they are also easier to be configured using Petalinux.
Meanwhile, GTH Transcievers are allocated in the Programmable Logic (PL) fabric. They are highly flexible, support massive data rates, and can be customized to run proprietary or specialized protocols like AMD Xilinx Aurora.
More detailed information about UltraScale FPGA Transceivers can be found in PG182 document, provided by AMD.
What is Aurora Protocol?
Whie MGTs provide physical interface to move bits over traces, they do not inherently understand meaning behind those bits. Thus, a link-layer protocol is needed to manage the connection, format the data, and handle errors.
Aurora is a lightweight, easy to setup, point-to-point serial communication protocol. It is designed specifically to pass data between chips, boards, or backplanes with the absolute minimum amount of logic overhead.
In comparison with complex protocols, like PCIe or Ethernet, Aurora acts as a simple high-speed pipeline. It takes a raw data in an AXI stream format, wraps it in a minimal frame, and blasts it across the transceiver lanes.
Aurora 8B/10B vs Aurora 64B/66B
The protocol comes in two variants: 8B/10B and 64B/66B. For modern robotics or vision appliocations, where there are not that big resource constraints, engineers will almost always use Aurora with 64b/66B encoding.
- 8B/10B: For every 8 bits of actual data, it sends 10 bits over the wire (a 2-bit mapping overhead). This means 20% of a given bandwidth is wasted on protocol overhead.
- 64B/66B: For every 64 bits of user data, the protocol adds, just a 2-bit synchronization header. This significantly reduces the transmission overhead to roughly 3%, giving an effective bandwidth efficiency of 97%.
Create a new Project
Open Vivado and in a desired location create a project with the name of your choise. For now you do not have to add any source files / constraints files as this can be done at a later stage.
In “Default Part” menu, go to “Boards” and search for “Kria 260 Robotics Starter Kit SOM”. Press “Connections” button highlighted in the screenshot.
And then set board connections as following:
Configuring Aurora IP
After setting up a new project, create/open block design and add Aurora IP to it. In Core options menu, set parameters as shown in the screenshot:
- GT Type: GTH
- Line Rate: 10.0 Gbps
- Column Used: Right
- Lanes: 1
- Starting GT Quad: Quad X0Y1
- Starting GT Lane: X0Y6
- GT Refclk Selection: CLK0
- GT Refclk Frequency: 156.25 MHz
- Dataflow Mode: Duplex
- Interface: Streaming
- Flow Control: None
- DRP Mode: Disabled
- Shared Logic: Include Shared Logic in Core
Streaming vs Framing Interface
Regarding Streaming vs Frame Interface: Framing interface treats data as structured packets, as it uses additional AXI control signals to mark the boundaries of these packets, while streaming interface treats data as an endless, continuous pipe of bytes. In this example, we will keep things simple and choose the streaming interface;
Flow control options
Aurora provides optional flow control mechanisms for cases where the receiver may need to slow down or send urgent control information.
Native Flow Control (NFC) allows the receiver to request a temporary pause when its internal buffers are close to full.
User Flow Control (UFC) provides a separate high-priority side channel for urgent control messages.
In this tutorial, flow control is set to None, because the design uses a simple and controlled loopback test where the receiver is not expected to create backpressure.
In the end, we do not use DRP mode in this example, which stands for Dynamic Reconfiguration Port. It allows a processor or user logic to read and write the internal configuration registers of the transceivers on-the-fly (dynamically) while the rest of the FPGA is still running. Provided example is fully based only on PL Fabric, thus we have disabled it as well.
In “shared logic” menu, simply choose option “Include shared logic in core”.
Two small custom Verilog IPs are used to generate and verify traffic. They make the design self-contained and allow the Aurora link to be tested without external software.
Aurora_stream_tx_gen
This block generates intermittent AXI4-Stream bursts. In the current configuration, it uses a 64-bit data bus and sends short packets of incrementing values.
· BURST_LEN = 4, so each burst contains four 64-bit beats.
· Each burst therefore sends 32 bytes of user data.
· After the final beat is accepted, the generator waits for 200 clock cycles before sending the next burst.
· The SEED parameter resets the counter when the Aurora link comes up.
Aurora_stream_rx_check
This block checks whether the received data matches the expected incrementing sequence. It is useful for quickly confirming that the Aurora link is passing data correctly.
· It compares incoming TDATA against an internal expected-value register.
· It increments err_cnt whenever the received value does not match the expected value.
· It increments the expected value on every valid transfer.
· It resets the expected sequence when the link comes up, while the error counter remains available as a diagnostic indicator.
Block Design Connections
Connect the Aurora input ports as follows:
- USER_DATA_S_AXIS_TX connects to the
interface_axisoutput ofaurora_stream_tx_gen. This provides the AXI4-Stream test traffic. - GT_DIFF_REFCLK1 is connected as an external port and provides the 156.25 MHz differential reference clock.
- Core_CONTROL.loopback[2:0] is connected to a constant. Use
010for near-end PMA loopback, or000for normal operation with a passive SFP+ loopback module. - GT_SERIAL_RX is connected as an external port for the SFP+ receive differential pair.
- reset_pb is tied to constant
0for this example. In a production design, it should be connected to a proper reset source. - pma_init can be tied off or connected to a controlled reset source. For easier hardware debugging, connect it to a debounced button or a processor-controlled register.
- init_clk is connected to
PS pl_clk0at 100 MHz and is used by the Aurora initialization logic.
Connect the Aurora output ports as follows:
- USER_DATA_M_AXIS_RX connects to the
interface_axisinput ofaurora_stream_rx_check. This carries the received AXI4-Stream traffic. - channel_up connects to the
run_levelinput of the TX generator and is also monitored with the ILA. It indicates that the Aurora channel is active. - lane_up is monitored with the ILA and shows whether the selected serial lane is active.
- gt_pll_lock is monitored with the ILA and should stay high when the GT PLL is locked.
- hard_err and soft_err are monitored with the ILA and should remain low during a clean test.
- mmcm_not_locked_out is monitored with the ILA and should remain low once the clocks are stable.
- GT_SERIAL_TX is connected as an external port for the SFP+ transmit differential pair.
- user_clk_out connects to the
clkinput ofaurora_stream_rx_checkand provides the clock for the receive checker.
Complete block design can be viewed below:
4 Constraints
Create an XDC constraints file and add the following assignments for the reference clock and SFP+ serial pins used in this example.
create_clock -name GT_REFCLK156 -period 6.400 [get_ports GT_DIFF_REFCLK1_0_clk_p]
set_property PACKAGE_PIN Y6 [get_ports GT_DIFF_REFCLK1_0_clk_p]
set_property PACKAGE_PIN Y5 [get_ports GT_DIFF_REFCLK1_0_clk_n]
set_property PACKAGE_PIN T2 [get_ports GT_SERIAL_RX_0_rxp]
set_property PACKAGE_PIN T1 [get_ports GT_SERIAL_RX_0_rxn]
set_property PACKAGE_PIN R4 [get_ports GT_SERIAL_TX_0_txp]
set_property PACKAGE_PIN R3 [get_ports GT_SERIAL_TX_0_txn]Important: verify these pins against the exact board, carrier-card revision and selected SFP+ port before reusing the constraints in another project.
Build and Test ProcedureBuild the bitstream
1. Validate the block design.
2. Generate the HDL wrapper if needed.
3. Run synthesis and implementation.
4. Generate the bitstream.
Program the board
Before programming only from Vivado, ensure that the PS-side clocks required by the design are active. In this example, the Aurora init clock is connected to the PS pl_clk0 clock. If the PS has not been initialized, the ILA and Aurora initialization may not behave as expected.
A practical bring-up method is to first program or boot a known working Vitis example that enables the required PS clocks, then program the PL bitstream from Vivado.
Test in internal loopback mode
5. Set loopback[2:0] to 010 for near-end PMA loopback.
6. Program the device and open the Hardware Manager.
7. Observe the ILA signals.
8. Confirm that channel_up and lane_up are high.
9. Confirm that hard_err, soft_err and mmcm_not_locked_out remain low.
10. Confirm that received data follows the same incrementing sequence as transmitted data.
11. Confirm that err_cnt remains 0.
The same design can also be tested without Aurora internal loopback by using a passive SFP+ loopback module.
12. Insert the passive loopback module into the selected SFP+ connector.
13. Set loopback[2:0] to 000 for normal operation.
14. Regenerate the bitstream if the loopback constant is changed in the block design.
15. Program the device and repeat the ILA checks described above.
Expected result
After programming the bitstream and opening the ILA, the Aurora link should behave as follows:
- channel_up should be
1, meaning the Aurora channel is active. - lane_up should be
1, meaning the selected serial lane is active. - gt_pll_lock should be
1, confirming that the GT PLL is locked. - hard_err and soft_err should remain
0during a clean test. - mmcm_not_locked_out should become
0once the design clocks are stable. - RX data should match the transmitted incrementing sequence.
- err_cnt should stay at
0during a clean loopback test. - RX latency of several dozen user-clock cycles is normal due to Aurora internal pipeline and state-machine latency.
Quick Troubleshooting Checklist
If the design does not behave as expected, start with the following checks:
- ILA does not appear or signals do not toggle: the PS clock may not be running. Boot or program a known working PS example first and confirm that
pl_clk0is active. - channel_up stays low: the transceiver may not be locked, the loopback setting may be wrong, or reset may not be released correctly. Check
gt_pll_lock, the loopback constant,reset_pb,pma_init, and the reference clock. - lane_up stays low: the selected GT lane, pin constraints, or SFP+ path may be incorrect. Check the selected GT lane, XDC constraints, and SFP+ loopback hardware.
- mmcm_not_locked_out remains high: this usually indicates a clocking issue. Check the reference clock frequency and Aurora shared logic configuration.
- err_cnt increments: the received sequence does not match the expected data. Check reset/reseed behavior, TX/RX clocking, and AXI4-Stream handshakes.
- Internal loopback works but passive SFP+ loopback does not: the issue is likely in the external SFP+ path. Check the loopback module, SFP+ connector, TX/RX pin assignments, and signal integrity.
Appendix: Key Settings Summary
This tutorial uses the following main configuration:
- Vivado version: 2024.2
- Board target: Kria 260 Robotics Kit SOM with Robotics Starter Kit carrier
- Aurora encoding: 64B/66B
- GT type: GTH
- Line rate: 10.0 Gbps
- Number of lanes: 1
- Dataflow mode: Duplex
- Interface: Streaming
- Flow control: None
- DRP: Disabled
- GT reference clock: 156.25 MHz
- init_clk: 100 MHz PS
pl_clk0 - Internal loopback:
loopback[2:0] = 010 - Passive SFP+ loopback:
loopback[2:0] = 000




Comments