February 18, 2022
Editor’s Note: This content is republished from the MicroZed Chronicles, with permission from the author.
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:
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:
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 60ps.
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 simualtion.