Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20640 Discussions

Unable to meet timing requirements for 180 MHz Source-Synch. DDR Interface due to PLL uncertainty

JeDi
Beginner
735 Views

Dear all,

My current project involves an interfacing between an ADC, clocked at 180 MHz with source-synchronous DDR LVDS outputs, and a Cyclone V FPGA (5CSXFC6).

To start, I instantiated a ALTDDIO receiver with the required number of channels and a PLL to create a 90 degree phase shifted version of the ADC clockout signal as its input clock.

With this setup, my timing fails for both the setup and hold analysis by approximately 500 ps each. The reason is that the length of the clock path differs by about 2.5 ns between the setup and hold analysis which shrinks down the data required window to almost zero, making it too small for the uncertainties in the data path and the input delays given by the ADC datasheet.

Changing the compensation mode of the PLL did not seem to have a significant effect. The chip planner showed that the clock signal was routed all over the chip. I was able to reduce the clock path length and improve the timing by assigning a specific regional clock buffer to the PLL output. (Is there any settings I could have changed for the fitter in order for it to try this automatically?). But even with this optimization, the timing fails at the "slow device corners".

When directly clocking the ALTDDIO with the ADC clockout signal, timing analysis goes well with around 0.5 ns slack for both and hold. The relatively large IC delay from the clock buffer to the DDIOs creates exactly the phase shift required.

The ADC can be configured to include a phase shift in the clock signal using an SPI interface but the datasheet recommends doing this within the FPGA. Although not using the PLL and relying on the clock delay seems to work, it is not satisfying. I am wondering if I am doing something wrong or whether a 180 MHz DDR interface is at the edge of the capabilities of the chosen device (5CSXFC6). 

Best regards

0 Kudos
10 Replies
EngWei_O_Intel
Employee
713 Views

Hi Dijkstra

Thanks for your inquiry. Allow me some time to check on your request and get back to you.

 

Thanks.

Eng Wei

 

0 Kudos
KhaiChein_Y_Intel
701 Views

Hi,

Could you share the design for investigation?


Thanks.

Best regards,

KhaiY


0 Kudos
JeDi
Beginner
694 Views

Hi all,

A MWE QPF is attached. It features two ADCs (one single channel, one dual channel) with a total of 20 DDR LVDS outputs + 2 LVDS clocks. Three clocks enter the FPGA: the two clockouts from the ADC as well as the encode clock that is will (externally) drive the ADCs. 

Originally I planned on using the 5CSXFC6C6U23C7 chip until I found out that some of the differential receiver pairs introduce additional delay due to the HMC and should not be used for fast signals. Therefore I will propably change to the 5CSEBA4U23I7 chip which resulted in additional phaenomena:

- Initially, the ADC clocks were connected to the CLK0 / CLK3 and the encode clock to CLK2. With these assignments, the fitter fails for the SE chip (but not the SX chip) because it cannot place one of the PLLs. When changing the input of the encode clock to CLK6, both chips compile fine (and the timing for the SX is improved compared to using CLK2 as input).

- With the 5CSEBA4U23I7 chip I can just meet the timing requirements with the PLL in place, with the 5CSXFC6C6U23C7 chip I still cannot because the "data valid window" becomes negative. Could this be due to the HMC resources which are present in the SX but not in the SE chip?

 

For both chips however,  omitting the PLL leads to significantly improved margings which brings me back to the original question: Is there a mistake in my configuration or is it true that the PLLs add so much uncertainty that a shift (if necessary) in my case should be done at the ADC?

 

Thank you in advance for any help!

0 Kudos
sstrell
Honored Contributor III
674 Views

Can you post your .sdc file?

#iwork4intel

0 Kudos
KhaiChein_Y_Intel
671 Views

Hi,


There are missing files in the attachment. You may provide the design.qar by clicking on Project > Archive Project > Archive


Error (12006): Node instance "systempll_inst" instantiates undefined entity "systemPll_0002"

Error (12006): Node instance "adcpll_inst" instantiates undefined entity "adcPll_0002"

Error (12006): Node instance "adcpll_inst" instantiates undefined entity "adcPll_0002"


Thanks.

Best regards,

KhaiY


0 Kudos
JeDi
Beginner
658 Views

Hi all,

I didn't know about the archive function, sorry. Hopefully it works this time.

Currently the PLL output clocks are used as the clock inputs to the receivers, this can be changed here:

 

inclock => adc2ChClkout_90deg,
--inclock => ADC_2CH_CLKOUT,

 

Thank you!

0 Kudos
KhaiChein_Y_Intel
645 Views

Hi,


You have to use create_clock on the input clock port (ADC_1CH_CLKOUT, ADC_2CH_CLKOUT and ENCODE_CLOCK) of your interface that describes the characteristics of the source clock. If the clock and data arrive at FPGA edge-aligned, you can use a PLL to shift the clock used to latch the data. If the clock and data arrive at FPGA center-aligned, you have to specify the clock phase adjustment on the input clock with the waveform options. According to AN 433, the false path and multicycle path exceptions are applied between the virtual clock and data clock. In the sdc, you are constraining the false path and multicycle path between the virtual clock itself (adc1ChClockout and adc2ChClockout). 


Thanks.

Best regards,

KhaiY


0 Kudos
JeDi
Beginner
642 Views

Hi Khai,

 

thank you for your response. There were no virtual clocks in my SDC file because I specified my input delays relative to the ADC clockout with the timings specified in the datasheet. I did this because I also wanted to analyze the timings from data launched by the input receivers and latched by the ENCODE_CLOCK. I don't think that this deviation from the AN433 affects my timing issue. To make sure, I changed the SDC file accordingly:

 

- Add virtual clocks (data is delayed to clock by typically 0.4 ns)

create_generated_clock -name adc2ChDataClock_virt -source [get_ports {ADC_2CH_CLKOUT}] -offset 0.4
create_generated_clock -name adc1ChDataClock_virt -source [get_ports {ADC_1CH_CLKOUT}] -offset 0.4

 

- Set the input delays, false paths and multicycle paths relative to the virtual clocks:

set_input_delay -min -clock [get_clocks {adc2ChDataClock_virt}] -0.1 [get_ports ADC_2CH_DATA*] -add_delay
set_input_delay -min -clock [get_clocks {adc2ChDataClock_virt}] -0.1 [get_ports ADC_2CH_DATA*] -clock_fall -add_delay
set_input_delay -max -clock [get_clocks {adc2ChDataClock_virt}] 0.15 [get_ports ADC_2CH_DATA*] -add_delay
set_input_delay -max -clock [get_clocks {adc2ChDataClock_virt}] 0.15 [get_ports ADC_2CH_DATA*] -clock_fall -add_delay

set_input_delay -min -clock [get_clocks {adc1ChDataClock_virt}] -0.1 [get_ports ADC_1CH_DATA*] -add_delay
set_input_delay -min -clock [get_clocks {adc1ChDataClock_virt}] -0.1 [get_ports ADC_1CH_DATA*] -clock_fall -add_delay
set_input_delay -max -clock [get_clocks {adc1ChDataClock_virt}] 0.15 [get_ports ADC_1CH_DATA*] -add_delay
set_input_delay -max -clock [get_clocks {adc1ChDataClock_virt}] 0.15 [get_ports ADC_1CH_DATA*] -clock_fall -add_delay


set_false_path -setup -fall_from [get_clocks {adc2ChDataClock_virt}] -rise_to [get_clocks {adc2ChClockout}]
set_false_path -setup -rise_from [get_clocks {adc2ChDataClock_virt}] -fall_to [get_clocks {adc2ChClockout}]
set_false_path -hold -fall_from [get_clocks {adc2ChDataClock_virt}] -fall_to [get_clocks {adc2ChClockout}]
set_false_path -hold -rise_from [get_clocks {adc2ChDataClock_virt}] -rise_to [get_clocks {adc2ChClockout}]

set_false_path -setup -fall_from [get_clocks {adc1ChDataClock_virt}] -rise_to [get_clocks {adc1ChClockout}]
set_false_path -setup -rise_from [get_clocks {adc1ChDataClock_virt}] -fall_to [get_clocks {adc1ChClockout}]
set_false_path -hold -fall_from [get_clocks {adc1ChDataClock_virt}] -fall_to [get_clocks {adc1ChClockout}]
set_false_path -hold -rise_from [get_clocks {adc1ChDataClock_virt}] -rise_to [get_clocks {adc1ChClockout}]


set_multicycle_path -setup -rise_from [get_clocks {adc1ChDataClock_virt}] -rise_to [get_clocks {adc1ChClockout}] 0
set_multicycle_path -setup -fall_from [get_clocks {adc1ChDataClock_virt}] -fall_to [get_clocks {adc1ChClockout}] 0

set_multicycle_path -setup -rise_from [get_clocks {adc1ChDataClock_virt}] -rise_to [get_clocks {adc2ChClockout}] 0
set_multicycle_path -setup -fall_from [get_clocks {adc1ChDataClock_virt}] -fall_to [get_clocks {adc2ChClockout}] 0

 

- I also had to remove the clock latency because it is not recognized anymore as common clock path pessimism). This is OK for the MWE

#set_clock_latency -source -early -0.3 [get_clocks {adc2ChClockout}]
#set_clock_latency -source -late 0.2 [get_clocks {adc2ChClockout}]
#set_clock_latency -source -early -0.3 [get_clocks {adc1ChClockout}]
#set_clock_latency -source -late 0.2 [get_clocks {adc1ChClockout}]

 

 

With these changes, the timing analysis for the capture paths is exactly the same.

0 Kudos
KhaiChein_Y_Intel
599 Views

Hi,


Correct me if I understand wrongly. ADC_2CH_CLKOUT and ADC_1CH_CLKOUT are the output clock from the ADC and these two clocks will be shifted by 90 degree using the PLL. If this is the case, you have to use create_clock to constrain ADC_2CH_CLKOUT and ADC_1CH_CLKOUT but not create_generated_clock because you have an input port assigned to it. Besides this, the false path and multicycle constraints are applied between the virtual clock and data clock. In your latest sdc, you have applied the constraint between adc1ChDataClock_virt and adc1ChClockout. This is correct only if you are using adc1ChClockout to latch the data. You have to use the generated clock from the PLL in the false path and multicycle assignment if you are using the PLL shifted clock to latch the data.


Thanks.

Best regards,

KhaiY


0 Kudos
KhaiChein_Y_Intel
579 Views

Hi,


We do not receive any response from you to the previous question/reply/answer that I have provided. This thread will be transitioned to community support. If you have a new question, feel free to open a new thread to get the support from Intel experts. Otherwise, the community users will continue to help you on this thread. Thank you


Best regards,

KhaiY


0 Kudos
Reply