02-16-2013 12:43 PM
Hi!
I have question about LVDS DDR inputs constraints.
I'm using ADC AD9255BCPZ-125 chip and Spartan6 FPGA.
Datasheet
System is source synchronous (using ADC DCO), running at 125MHz.
Input data from ADC to FPGA looks like this:
adc_data_in_p -> LVDS (IBUFDS) -> wire -> IDDR2 -> adc_regs
Clock distribution in FPGA is done through DCM. I'm using CLK0 and CLK180 to drive IDDR2 clock pins.
Ok, I created constraints for data and clock as follows:
NET "adc_clk" TNM_NET = adc_clk;
TIMESPEC TS_adc_clk = PERIOD "adc_clk" 125 MHz HIGH 50% INPUT_JITTER 52 ps;
INST "adc_data_in_p<*>" TNM = adc_data;
TIMEGRP "adc_data" OFFSET = IN -0.3 ns VALID 2.5 ns BEFORE "adc_clk" RISING; (2.448 ns after subtracting clock jitter)
TIMEGRP "adc_data" OFFSET = IN -0.3 ns VALID 2.5 ns BEFORE "adc_clk" FALLING; (2.448 ns after subtracting clock jitter)
First question: are those values in OFFSET IN correct for the chip I'm using and clock (125MHz)?
After implementation I'm getting:
The clock adc_clk associated with TIMEGRP "adc_data" OFFSET = IN -0.3 ns VALID 2.448 ns BEFORE COMP
"adc_clk" "FALLING" does not clock any registered input components.
Timing constraint TIMEGRP "adc_data" OFFSET = IN -0.3 ns VALID 2.448 ns BEFORE COMP "adc_clk" "FALLING"
ignored during timing analysis
How can I constraint those input for both RISING and FALLING edges? Is it ok to put constraint (?):
TIMEGRP "adc_data" OFFSET = IN -0.3 ns VALID 2.5 ns BEFORE "adc_clk";
and it will be valid for both RISING and FALLING edges?
And last question :)
Looking at datasheet for Spartan6 LXT45-3 with DCM input registers timing are:
0.85 setup/ 0.7 hold
So I need to shift clock backwards (with DCM) by 1.15 ns to meet timing needs (setup)?
Btw, is it possible to place adc_regs in IOB of IDDR2 (probably not because IDDR2 already have registers)?
Thanks and best regards,
Peef
02-16-2013 03:14 PM
Peef,
The constraints look correct according to the datasheet (although the datasheet is fairly confusing - why is the uncertainty in LVDS mode so much higher than it is in LVCMOS mode - that doesn't really make sense).
I don't know why it is not properly accepting the "FALLING" constraint - I suspect it has something to do with the fact that the DCM really is taking the rising edge of the input clock and shifting it by 180 degrees - therefore its really the rising edge that is capturing both window - one is just done via a clock that is shifted by 180 degrees. I would call this a tool bug, and would consider opening a webcase on it.
That being said, the rising and falling edge windows are completely symmetrical, and the capture mechanism for it is completely fixed. Therefore, the slack on the RISING edge window will be identical to the slack on the FALLING edge window. So even if you can't succeed in constraining the FALLING edge, its not really going to make any difference to the design - if the RISING edge passes, then the FALLING edge will too.
The timing of the DCM also looks correct - providing you have placed the DCM in SOURCE_SYNCHRONOUS mode (which is probably best for this interface). However, at 1.15ns, you will have 0ns of setup slack, and 0.95ns of hold slack - you might want to distribute the slack a little more evenly (i.e. get the sampling in the middle of the window). This would be 1.625ns of shift. But, you should really look at the TRCE results - the Tpsdcm_0/Tphdcm_0 are good starting points, but the actual values should always come from TRCE. In fact, TRCE will generate a datasheet report for this interface (if enabled) which will tell you "Clock Offset to Center" (or something like that), which tells you what the ideal additional clock shift would be to center the sampling in the data window.
As you suspected, the IDDR2 is the IOB FFs. In this case, it one FF on C0 (CLK0 from your DCM) and one on C1 (CLK180 from your DCM). Thus, the Q0 output of the IDDR2 is clocked on CLK0 and the Q1 on CLK180. If adc_regs is clocked on CLK0, then there will be a 1/2 clock cycle path from the IDDR2 to the adc_regs. To help with internal FPGA timing, you can use the IDDR2 with DDR_ALIGNMENT=C0 - this will add an additional FF (clocked on C0) on the Q1 output (this is 1/2 of your adc_regs).
Avrum
02-16-2013 03:14 PM
Peef,
The constraints look correct according to the datasheet (although the datasheet is fairly confusing - why is the uncertainty in LVDS mode so much higher than it is in LVCMOS mode - that doesn't really make sense).
I don't know why it is not properly accepting the "FALLING" constraint - I suspect it has something to do with the fact that the DCM really is taking the rising edge of the input clock and shifting it by 180 degrees - therefore its really the rising edge that is capturing both window - one is just done via a clock that is shifted by 180 degrees. I would call this a tool bug, and would consider opening a webcase on it.
That being said, the rising and falling edge windows are completely symmetrical, and the capture mechanism for it is completely fixed. Therefore, the slack on the RISING edge window will be identical to the slack on the FALLING edge window. So even if you can't succeed in constraining the FALLING edge, its not really going to make any difference to the design - if the RISING edge passes, then the FALLING edge will too.
The timing of the DCM also looks correct - providing you have placed the DCM in SOURCE_SYNCHRONOUS mode (which is probably best for this interface). However, at 1.15ns, you will have 0ns of setup slack, and 0.95ns of hold slack - you might want to distribute the slack a little more evenly (i.e. get the sampling in the middle of the window). This would be 1.625ns of shift. But, you should really look at the TRCE results - the Tpsdcm_0/Tphdcm_0 are good starting points, but the actual values should always come from TRCE. In fact, TRCE will generate a datasheet report for this interface (if enabled) which will tell you "Clock Offset to Center" (or something like that), which tells you what the ideal additional clock shift would be to center the sampling in the data window.
As you suspected, the IDDR2 is the IOB FFs. In this case, it one FF on C0 (CLK0 from your DCM) and one on C1 (CLK180 from your DCM). Thus, the Q0 output of the IDDR2 is clocked on CLK0 and the Q1 on CLK180. If adc_regs is clocked on CLK0, then there will be a 1/2 clock cycle path from the IDDR2 to the adc_regs. To help with internal FPGA timing, you can use the IDDR2 with DDR_ALIGNMENT=C0 - this will add an additional FF (clocked on C0) on the Q1 output (this is 1/2 of your adc_regs).
Avrum
02-17-2013 06:20 AM
Hi Peef,
Which device are you using? For Spartan -6 and Virtex-6 DDR's there are two clock inputs. One is the positive clock and the other clock should be a 180 degrees phase shifted clock. Both the clocks work separately and the DDR infact works like this. The rising edge data is latched at the rising edge of FF 1. The falling edge data is nothing but the rising edge of the 180 degrees phase shifted clock.
The rising and falling keywords work only if we are giving a single clock as an input to the DDR, which internally uses 2 clocks. In your case, the falling keyword fails as the edge is not falling but infact the rising edge of the 180 degrees phase shifted clock. If your device is a Virtex-6 then this constraint would not fail.
In such a case you might be thinking what would be the alternative to write timing constraints in this case. There is a very good article to guide you on this. Check the Answer Record - http://www.xilinx.com/support/answers/34634.htm.
Just try applying the constraint as per this article to correctly analyze the timing.
Hope this information clarifies your basic query.
Thanks,
03-22-2013 04:18 AM