In modern high-speed digital systems, precise timing is critical, because signals arriving at the FPGA often exhibit jitter, a small, unintended variation in signal timing. This phenomenon can disrupt the reliability of data sampling, leading to errors in the data acquisition.
Our implementation is based on the FMC-01, a FMC board connected to a Zynq UltraScale+ FPGA, developed by Emtech that enables both signal capture and generation with an 8-channel/16-bit ADC (ISLA216P25) working at 200 MSPS and a dual-channel 16-bit DAC processing at 400 MSPS.
The causes of jitter were typically attributed to several factors:
To address jitter effectively, examine the clock sources used for sampling the data. A stable and well-designed clock is the foundation of any high-speed system. However, applying solid timing constraints during the FPGA design process ensures the synthesized design meets timing requirements.When these measures do not fully resolve jitter issues, a more precise approach is using the IDELAYE3 IP from Xilinx. This blog details how we optimized interfaced data performance by implementing the Xilinx IDELAYE3 primitive and provides best practices for achieving robust system functionality.
The ADC's data output is delivered in parallel using DDR format. Therefore, each bit pair is handled by instances of the IBUFDS, IDELAYE3, and IDDR1 primitives. Since the data is synchronous with the incoming clock, the input clock is used to prevent any phase misalignment.
Note: Remember that each MMCM should be configured with the “Phase Alignment” option enabled.
Lastly, the IDDRE1 primitive receives the delayed data and outputs a signal divided into rising and falling edges. This signal is then remapped and reconstructed to recover the original data.
According to the device datasheet, the output data is transmitted using a Double Data Rate (DDR) format, where data transitions occur on both the rising and falling edges of the clock signal. Specifically, the odd-numbered data samples are transmitted on the rising edge of the clock, while the even-numbered data samples are transmitted on the falling edge.
At the electrical layer, the DDR interface uses Low-Voltage Differential Signaling (LVDS) to enable high-speed, reliable data transmission. This differential configuration provides significant advantages in minimizing electromagnetic interference (EMI).
Note: take into account the timing considerations that the ADC’s datasheet describes for this application.
The IDELAYE3 IP is a primitive in Xilinx FPGAs that enables fine-tuning of signal timing by introducing precise delays to an input signal, measured in tap values. Its configuration requires careful consideration of attributes and parameters to achieve the desired functionality.
The most critical features to consider are:
Note: These features are the primary sources of misconfiguration due to their dependency on both the FPGA family and the specific data path requirements. The following sections outline how we configured them correctly with a brief description of each attribute.
Possible values:
Used when the signal arrives directly from an IOB (Input/Output Block)
Used when the signal arrives comes from internal logic (e.g. IBUFDS, ISERDES)Since the data goes through an IBUFDS primitive, we set the DELAY_SRC to DATAIN and tied the IDATAIN input to LOW.
This attribute provides two operational modes, that depend on the REFCLK_FREQUENCY:
In this mode, an IDELAYCTRL component must be used according to Xilinx guide, otherwise, Vivado will output an error message. This component will calibrate, control, and maintain the voltage and temperature of the delay line. For our design with eight IDELAYE3 instances, we instantiated a single IDELAYCTRL primitive.
The REFCLK_FREQUENCY attribute must reflect the clock frequency applied to the IDELAYCTRL component. When loading a new value in the IDELAYE3 primitive, take into consideration that 511 equals a delay of 1100ps (for UltraScale+) or 1250ps (for UltraScale)
There is no need to use an IDELAYCTRL component because the delay line is used in the uncalibrated state without voltage and temperature compensation.
- The delay line must be used counting only taps and not counting delay/tap.
- The DELAY_VALUE is expressed as taps (0 to 511).
In this case, leave the REFCLK_FREQUENCY attribute at the default value (300.0 MHz)
The TIME mode is the one selected on the configuration.
This attribute depends on the DELAY_FORMAT attribute and the FPGA used:
In our configuration, the DELAY_VALUE is set to 0.
The REFCLK_FREQUENCY attribute specifies the reference clock of the IDELAYCTRL or BITSLICE_CONTROL frequency in MHz, except when DELAY_FORMAT is set to COUNT (when the attribute can be left at the default value).
These are the possible values:
Note: The input number, is a float with 1 significant digit.
There are three possibilities for this attribute: FIXED, VAR_LOAD, or VARIABLE
This attribute determines when the delay value is updated by the IDELAYE3.
Based on the primitive component guide, we used the ASYNC mode to minimize logic complexity.
We set this attribute to ULTRASCALE_PLUS, matching our FPGA family.
As the maximum delay of 1.1 ns per IDELAYE3 primitive is sufficient for our design, we set this parameter to NONE. For larger delays, providing cascading configurations are recommended.
When instantiating the IDELAYE3 primitive, you will see another 2 attributes:
These attributes were configured based on the logic requirements. We tied IS_CLK_INVERTED LOW and IS_RST_INVERTED HIGH.Here is the final configuration for our component:
The EN_VTC pin handling depends on the DELAY_TYPE and DELAY_FORMAT settings, therefore an FSM (Finite State Machine) RTL is appropriate to handle this configuration.
Here are the steps to take into account when dealing with the EN_VTC signal with DELAY_TYPE = VAR_LOAD and DELAY_FORMAT = TIME:
Note: If there are multiple updates, wait at least 5 cycles and repeat the last 2 steps with the 5 clock waiting until you reach the desired value.
Once all the components are in place, the ADC Device provides an internal custom pattern option configurable via SPI, through the TEST_IO register, to properly calibrate the signals is recommended to use the following patterns:
For last here is a small description of each register map:
Note: For more information about this configuration, check the ADC (ISLA216P25) datasheet.
Below, we present the results of an experiment with a sine wave signal before and after calibration.
Initially, the signal exhibits significant jitter, as expected, due to the absence of manual calibration (Figure 5). The calibration process involves transmitting various test patterns, as described earlier, to detect bit errors and their respective positions, adding the correspondent delays.
As you may see, the sine wave significantly increases its precision and shows as in the Figure 6. However certain values still need appropriate compensation, which will be the focus of the next blog.
We'll explore how to address this through a software-based solution and eventually achieve the following results:
This article introduced how to configure an IDELAYE3 instance and its practical applications. We also shared best practices for addressing timing challenges in high-speed systems, particularly when working with ADC data.
Developed board:
Xilinx Documentation: