Forum Discussion
Need Help to Verify Timing Constraints On Output Pins to External Device
Hi,
I'm relatively new in FPGA designing, so forgive me if my question seem simple. The project I am working on involves using a Cyclone V to control 4 external DDS chips (AD9915). So I'm using the FPGA pins to send data to the DDS chips. I wish to clock my design at 156.25 MHz (which is period of 6.4 ns). These DDS chips supply the 156.25 MHz clocks that I am using to clock my design in the FPGA. The DDS chip requires a setup time of 2 ns and hold time of 0 ns. (http://www.analog.com/static/imported-files/data_sheets/ad9915.pdf [pg 6]) I have read many reference online that specifies that a virtual clock has to be created for the 'set_output_delay' command to reference to. So just taking four pins from my design as an example, the SDC file looks like this. i have just attached a register with a constant value to these output ports just to verify the sdc file, also i put a 0 ns for setup and hold for the external device just to verify. // These are the actual clock coming into the FPGA from the DDS create_clock -name {ddsclk1} -period 6.400 -waveform { 0.000 3.200 } [get_ports {dds_clk_1}] create_clock -name {ddsclk2} -period 6.400 -waveform { 0.000 3.200 } [get_ports {dds_clk_2}] create_clock -name {ddsclk3} -period 6.400 -waveform { 0.000 3.200 } [get_ports {dds_clk_3}] create_clock -name {ddsclk4} -period 6.400 -waveform { 0.000 3.200 } [get_ports {dds_clk_4}] // These are virtual clocks I set up create_clock -name {ddsclk1_ext} -period 6.400 -waveform { 0.000 3.200 } create_clock -name {ddsclk2_ext} -period 6.400 -waveform { 0.000 3.200 } create_clock -name {ddsclk3_ext} -period 6.400 -waveform { 0.000 3.200 } create_clock -name {ddsclk4_ext} -period 6.400 -waveform { 0.000 3.200 }
// and then the setup time and hold time (I have set them to 0 just to verify) set_output_delay -clock { ddsclk1_ext } -max 0.000 [get_ports {func_pin_1[0]}] set_output_delay -clock { ddsclk1_ext } -max 0.000 [get_ports {func_pin_1[1]}] set_output_delay -clock { ddsclk1_ext } -max 0.000 [get_ports {func_pin_1[2]}] set_output_delay -clock { ddsclk1_ext } -max 0.000 [get_ports {func_pin_1[3]}] ......... and the same thing for ddsclk2,3,4_ext for func_pin_2,3,4
set_output_delay -clock { ddsclk1_ext } -min 0.000 [get_ports {func_pin_1[0]}] set_output_delay -clock { ddsclk1_ext } -min 0.000 [get_ports {func_pin_1[1]}] set_output_delay -clock { ddsclk1_ext } -min 0.000 [get_ports {func_pin_1[2]}] set_output_delay -clock { ddsclk1_ext } -min 0.000 [get_ports {func_pin_1[3]}] ......... and the same thing for ddsclk2,3,4_ext for func_pin_2,3,4
I have also set the false paths between the four clock domains. However, when I compile my very simple design and run TimeQuest, TimeQuest reports that my setup slacks for ddsclk1,2,3,4_ext are negative. I find these strange and would expect Cyclone V to be able to run at much faster speed than 156.25 MHz, moreover my design now is just a reg to the output port. http://www.alteraforum.com/forum/attachment.php?attachmentid=10148&stc=1 So, I am suspecting that I did not constrain the design properly. Hope anyone can give their two cents on the way I did the timing constraints. Thanks in advance!
24 Replies
- Altera_Forum
Honored Contributor
Hi all,
Thanks for your replies and guidance. Rsyc, What do you mean specifically by "make sure PLL is compensating". Can you elaborate more on that, or point me in a right direction where I can learn more about it? Thanks! - Altera_Forum
Honored Contributor
Open the PLL in the Megawizard or QSYS and look at the compensation mode. If it's direct, than it's not compensating, but Normal mode means it has a clock fedback into the PLL which is used to shift the output clock, i.e. it tries to align the clock at the end of the global clock tree with the time it enters the PLL. Basically it's like a negative shift of a few ns.
- Altera_Forum
Honored Contributor
Hi all,
I'm really interested in resolving this post as I'm dealing with a very similar situation. I've just a few little differences in my case, but the heart of the problem is the same. I'm interfacing a Cyclone V FPGA with the AD9789 DAC. From the DAC side, I have the same configuration as wzs, the DAC sends me the data clock (which is 144MHz), and expects to receive the data. One difference is that this IF is DDR, but I can ignore this for now to simplify a bit. Then, from the FPGA side, I receive the DAC clock throught a CLK pin, pass it through a PLL with 0ns phase shift, an drive an ALTDDIO_OUT block to get the data out. I've configured the PLL to work in Normal mode and I've selected the output clk as the feedback clock to compensate for. This is the assignment I've manually added to do this: set_instance_assignment -name MATCH_PLL_COMPENSATION_CLOCK ON -to "pll_dac_dco:pll_dac_dco_u|pll_dac_dco_0002:pll_dac_dco_inst|altera_pll:altera_pll_i|outclk_wire[0]" As I understand, using the ALTDDIO megafunction automatically maps the output registers to Fast registers, so from a timing point of view, I'm in the best case. I've also defined the set_output_delay to be 0ns to simplify the things a bit, as it's the less restrictive case. In addition, I've set false paths between the edge transactions I don't to take into account, and I've left the more restrictive cases (I think) that are opposite edge transfers. I think I can change this to same edge transfers and I will be relaxing timing a bit, but I've tried it and I couldn't meet timing anyway. I also think that it shouldn't matter too much as the data is continuosely being sent, so no matter which edge I use to send the data, there will be an edge that will sample it correctly. When I compile the design and run timing analysis I get the same results as wzs. the total data delay through the fpga is longer than the clock period. I'm attaching the report, but it hasn't enough resolution to read it right. Anyway, the waveform view gives some idea of what I'm talking about. I think I can't do much to get rid of this, but there is something I don't understand. Shouldn't the PLL automatically try to phase shift the output clock to meet timing? If it doesn't, how do I properly constrain the design? I think I have to use some multicycle constrain, but I'm not sure how to do that correctly. I was thinking of opening a new post to ask my question, but then I decided that my situation has a lot of similarity with this post and it contribute to resolve the way of constraining this kind of interfaces. Hope anyone can help :) Diego - Altera_Forum
Honored Contributor
when FPGA clock is opposite fpga dout then tCO at fpga pins could be higher than 1 clock period. The remedy options are:
1) use PLL in compensation mode. If successful the pll will deskew clock so that it arrives at register (dout) with no delay relative to pin. check that clock skew does get close to zero. 2) set setup multicycle of 2 and hold should stay as default of zero, from dout path alternatively adjust set_output_delays by 1 clock. I believe you need to subtract one period from max but add one period to min because addition of one clock period means advance based on altera doc. The reason multicycle works is that we can sample correctly as long as we get same stream sequence without edge violations 3)use manual PLL shift. This could make it difficult to manage timing figures. - Altera_Forum
Honored Contributor
--- Quote Start --- when FPGA clock is opposite fpga dout then tCO at fpga pins could be higher than 1 clock period. The remedy options are: 1) use PLL in compensation mode. If successful the pll will deskew clock so that it arrives at register (dout) with no delay relative to pin. check that clock skew does get close to zero. --- Quote End --- I'm using a PLL in Normal compensation mode. What I understand from your answer is that if I still can't meet timing is because there is chance for the PLL to unsuccess. In the example I've attached in the previous post, there is a "COMP" item in the clock path that I suppose is related with this. Its value is ~ -1.6ns. Is there a way to report the skew between the input clock and the clock at output register? --- Quote Start --- 2) set setup multicycle of 2 and hold should stay as default of zero, from dout path alternatively adjust set_output_delays by 1 clock. I believe you need to subtract one period from max but add one period to min because addition of one clock period means advance based on altera doc. The reason multicycle works is that we can sample correctly as long as we get same stream sequence without edge violations --- Quote End --- OK. This is the solution I'm trying. I understand that I must set multicycle of 2 and this will relax timing requirements giving me an extra cycle. I've tried this and I have now two situations to consider, same edge transfers and opposite edge transfers. I think that I must set_false_path to the case I don't want to analyze, but it's confusing for me to decide which one. If I use same edge transfers, I'm meeting timing for both setup and hold, but it's strange to me that setup slack is greater than half a period, so I will be latching in opposite edge :S If I use opposite edge transfers, I meet timing for setup but not for hold. I'm attaching the waveform of these two cases. Is what I'm doing correct? Is this solution applicable when using a PLL or not using it? --- Quote Start --- 3)use manual PLL shift. This could make it difficult to manage timing figures. --- Quote End --- I'm not using this for now, as I understand that the PLL should ajust its phase to ease timing. - Altera_Forum
Honored Contributor
To see clock skew in timequest click on report io timing and see table of values under register to output(setup, or hold).
Regarding your waveforms: it doesn't look right. For example,the same edge case should fail setup as data arrives too early and will be latched by opposite edge. It looks like the tool applies multicycle as if IF is not DDR. I am not sure why. May be you also try adjust set output delay figures instead of multicycle . If these were originally 0/0 then try -UI/+UI or even -period/+period which in theory is same as multicycle of 2/0 (multicycle is only known in clock period units unlike delay which is in time units). I also assume you haven't set your PLL to any positive phase offset. edit: multicycle example from altera: set_multicycle_path -setup -end 0 -rise_from [get_clocks data_clock] -rise_to [get_clocks output_clock] looks like you can define rise_from, rise_to, fall_from, fall_to in order to apply to DDR. In your case you just need mcp of one UI - Altera_Forum
Honored Contributor
Having re-read your last post I think I misunderstood your diagram.
It looks to me that same edge is ok. The issue of slack being more than half period is ok for DDR. - Altera_Forum
Honored Contributor
Hi kaz. I couldn't do any test yesterday. But I still don't understand if it's correct to have a slack time greater than half a period in the DDR case.
I think the data valid window to sample the data should be less than half a period because if not I might be sampling data with the incorrect edge. I will be simplifying the interface to analyze an SDR transfer case to see if and understand the results I get. Thanks a lot. - Altera_Forum
Honored Contributor
I strongly believe it is possible for DDR slacks to be reported more than half period (UI) for either setup or hold and that is direct outcome of setting false paths between unrelated edges.
You should not think of DDR clock as equivalent to SDR at double rate clock in which case it is not possible. The DDR will have two registers to de-interleave data and so changes are ignored by one edge or the other. Regarding same edge Vs opposite edge latching, you are free to try either and see which one passes. Once you choose one case then your design must be aware of it. Remember a stream of Hdata => Ldata if sampled on same edge will retain the sequence and if you decide on opposite edge transfers then the sequence becomes Ldata => Hdata and as long as you interleave/deinterleave back correctly then it should work. If you don't set false paths on irrelevant edges then slack must be less than UI and this is unrealistically too restrictive. - Altera_Forum
Honored Contributor
Hi Rysc, (and Hi to Everybody else)
thanks for writing the TimeQuest User Guide. It is a great help. I have a question about the set_clock_groups: 1) What if I put clocks asynchronous which are synchronous to each other? 2) Are there clocks that come from different sources which should not put asynchronous?