MicroZed Chronicles: 7 Series FPGA IDELAY2 / ODELAY2
One of the greatest things about FPGAs is their IO flexibility. This flexibility allows us to recover high-speed signals, align data coming into the device, and even get us out of a hole if we don’t get the PCB quite right.
One often overlooked capability within the device IO structure is the IDELAY2 and ODELAY2 primitives. These primitives provide the developer with a programmable delay line which consists of 32 taps, enabling adjustable or fixed delays to be applied.
Exactly which primitive is available depends upon the type of IO bank we are working with. High Performance IO (HPIO) provides the user with both IDELAY2 and ODELAY2 primitives, while the High-Range IO (HRIO) provides only IDELAY2 primitives.
We can use both the IDELAY and ODELAY to take out small delays between signals. The resolution between the taps depends on the clock frequency, the device, and the speed grade as shown in the 7 series AC/DC Characteristics data sheet.
When we provide a 200 MHz reference clock, each tap increment increases the delay by 78 ps. This means the total delay would be approximately 2.469 ns.
Both IDELAY and ODELAY primitives can be operated in four modes:
FIXED – The delay is fixed in this mode and cannot be changed at run time.
VARIABLE – This is a variable delay in which the tap value can be incremented or decremented using a simple interface.
VAR_LOAD – Similar to the variable mode, the tap delay can be set via an input vector.
VAR_LOAD_PIPE – This is similar to VAR_LOAD however future delays can be pipelined.
The IDELAY2 module is able to delay a signal from either the logic fabric or an IO input.
Now let’s look at how we can implement a IDELAY function in an application and also create a test bench which demonstrates the different modes.
To get started using the IDELY or ODELAY, we need to implement a IDELAYCNTRL module. This module continually calibrates the individual delay taps in its region. The block is very simple and requires on the reference clock and reset, the RDY output when low indicates the IDELAYCNTRL blocks need to be reset.
These can be instantiated in our code using the language templates provided within Vivado’s text editor.
We can also use the same language template to instantiate the IDELAYCNTRL2. The deign we are going to demonstrate will use one IDELAYCNTRL and two IDELAY2 primatives. This will enable the test bench to show the differences between the delays on the signals when the IDELAY2 are configured differently.
Both IDELAY2 primatives will be configured to operate in the VAR_LOAD format. This allows incrementing and decrementing via the simple CE and INC signal interfaces, along with adjusting the tap delay using the CNTVALUEIN.
The test bench will perform the following elements:
Reset the IDELAYCNTRL.
Input two signals, each one clock wide into both IDELAY2 and set for 0 delay.
Input two signals, each one clock wide into both IDELAY2 when a delay of 2 is applied to both IDEALY.
Increment the second IDELAY2 delay by 1 to 3 while leaving the first IDELAY with a dealy of 2.
Decreement the second IDELAY2 by 1 to have the same delays in both again.
Set the second IDELAY2 to have the maximum delay possible of 31.
The overall simulation can be seen below with such fine-grain delays that it is impossible to see the effects of the delay at this level. We can see the control signals and the tap value changing, however, as the test bench performs the different tests.
The waveform for test one can be seen below. Even though no delay is figured, there is, of course, a delay between the input signal and output signal of about 60 ps.
When the delay is set to 2, the delay is 756 ns which is 156 ps (two tap delays of 78 ps) plus the original 0.6 ns delay.
The third test shows a 78 ps difference between signal one and signal two. Corresponding with the difference in tap settings, this is also shown on the count value out signal.
The fouth test sets both signal paths to have the same delay. Tests three and four demonstrate how the simple increment and decrement interface works. We pulse CE to enable IDELAY2, and depending on the status of INC, the tap delay is incremented or decremented. If INC is set coincident to CE, the tap delay is incremented otherwise the tap delay is decremented.
The final test sets the second signal path to maximum delay. Here it is possible to see that signal two is delayed by 3.018 ns. This is the 2.469 ns of the tap delay plus the original 0.6 ns.
The IDELAY is a very useful tool in our tool box and provides the capability to perform fine-grain alignment of input signals in the FPGA.
Check out my GitHub if you want to take a look at the project and run the simulation.