FPGA: Please help set up set_output_delay constraints - Page 1
Forum section: electronics / general

author: possum
author_rank: Contributor
timestamp: January 30, 2019, 06:25:25 am
content: I'm a beginner ...I have this simple test project in Quartus 13.0.1Code:module test(input clock_input, output reg data, output clock_output);initial data = 0;assign clock_output = clock_input;always @ (posedge clock_input) begindata <= data + 1'b1;endendmoduleOutput clock and data goes to external device, which requires 5ns setup time and 0.5ms hold time So, I wrote this sdc fileCode:create_clock -name in_clock -period 20 [get_ports {clock_input}]derive_pll_clocksset_output_delay -clock { in_clock } -reference_pin [get_ports {clock_output}] -min -0.5 [get_ports {data}]set_output_delay -clock { in_clock } -reference_pin [get_ports {clock_output}] -max 5 [get_ports {data}]Please note the reference_pin parameter is required since the following does not work correctly, it does not take into account the delay inside clock_output portCode:set_output_delay -clock { in_clock } -min -0.5 [get_ports {data}]set_output_delay -clock { in_clock } -max 5 [get_ports {data}]I verified the output in simulation (ModelSim) and all timings look correct.Now, let's suppose the external device requires 1ns hold time, if I update the sdc file with new timings - it will say timings can not be met - which is correctSo, I added the PLL with 2 clocks, one is 180 degree phase shift relative to another. Module now looks like this:Code:module test(input clock_input, input clock_input_180, output reg data, output clock_output);initial data = 0;assign clock_output = clock_input_180;always @ (posedge clock_input) begindata <= data + 1'b1;endendmoduleand entire project is on the diagram belowI also changes the sdc file toCode:create_clock -name in_clock -period 20.000ns [get_ports {clock_input}]derive_pll_clockscreate_generated_clock -name clock_0 -source [get_pins {inst1|altpll_component|pll|clk}]create_generated_clock -name clock_180 -source [get_pins {inst1|altpll_component|pll|clk}]set_output_delay -clock { clock_180 } -min -1 [get_ports {data}]set_output_delay -clock { clock_180 } -max 5 [get_ports {data}]of course, it does not take into account the delay inside clock_output port, so I tried to add the reference_pin parameter but got the following errorCode:Warning (332079): Reference pin clock_output is invalid. It is not clocked by the clock specified in set_input_delay/set_output_delay's -clock option.What can I do?

author: Daixiwen
author_rank: Frequent Contributor
timestamp: January 30, 2019, 09:54:58 am
content: I have never used the reference pin option, usually for this type of constraints I create a generated clock linked to the pin used as clock output to. Something like that:Code:create_generated_clock -name out_clock -source clock_180 [get_ports {clock_output}]set_output_delay -clock { out_clock } -min -1 [get_ports {data}]set_output_delay -clock { out_clock } -max 5 [get_ports {data}](not tested)Rather than modelsim I suggest that you check the timing diagrams generated by Timequest after you compiled the project. It is a good way to check that Timequest understood your constraint as you meant it.If you haven't read it, I strongly suggest to read the unofficial Timequest user guide by RSyc.https://fpgawiki.intel.com/uploads/3/3f/TimeQuest_User_Guide.pdfIt has unfortunately never been finished (and especially it doesn't cover your case, with a synchronous interface using a FPGA pin as clock for the connected device) but it has a lot of useful information, and is better than the official documentation imho.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 30, 2019, 03:35:56 pm
content: Xilinx also recommends "create_generated_clock".In your design, your clock and data pass through substantially different paths. Clock goes to the output directly. Data has a flip-flop delay (perhaps 0.5 ns). Also, data and clock are likely to have different routing which would further delay data relative to the clock. This might be Ok at 50 MHz, but it'll cause problems at higher speeds.To avoid such problem, a technique called "clock forwarding" is commonly used, which puts a flip-flop on the path of the clock, and also makes sure that both clock and data are launched as close to package pins as possible. Xilinx has an ODDR primitive, which is used for this purpose. I guess Altera must have something similar.As the name suggests, ODDR outputs a DDR (double data rate) signal. Aside of the clock, ODDR has two inputs. One input (D1) accepts a signal which is clocked out at the rising edge of the clock. Other input (D2) accepts a signal which is clocked out at the falling edge of the clock.To forward your clock out, you instantiate an ODDR and feed it with your clock. Then you feed D1 with '1' and D2 with '0'. This creates a clock at the output of the ODDR which goes strait to the package pin. In your case you need an inverted clock (shifted by 180), so you can do the opposite - feed D1 with '0' and D2 with '1' - this will invert the clock automatically. This way you don't need a PLL.To make sure the data delay is the same as the clock delay, you can also instantiate ODDR for each of your data lines. Since you don't need DDR, you simply feed your data to both D1 and D2 of the ODDR.Once you've done this, you minimized your skew as much as you possibly can. All is left is the clock skew and the skew through output buffers, but you cannot eliminate these. At this stage, you realize that it doesn't make much sense to do the timing analysis because the tools cannot either improve or worsen the timing. You may still do it to see if the clock skew is small enough, perhaps change your clocking scheme, but it'll make no difference at 50 MHz. If you do the timing analysis, keep in mind that there may be difference in lengths of your PCB traces, which you may want to take into account as well.

author: possum
author_rank: Contributor
timestamp: January 31, 2019, 06:58:31 am
content: Quote from: Daixiwen on January 30, 2019, 09:54:58 amI tried thisCode:create_clock -name in_clock -period 20.000ns [get_ports {clock_input}]derive_pll_clockscreate_generated_clock -name clock_0 -source [get_pins {inst1|altpll_component|pll|clk}]create_generated_clock -name clock_180 -source [get_pins {inst1|altpll_component|pll|clk}]create_generated_clock -name out_clock -source clock_180 [get_ports {clock_output}]set_output_delay -clock { out_clock } -min -1 [get_ports {data}]set_output_delay -clock { out_clock } -max 5 [get_ports {data}]and got errors below, all constraints were ignoredCode:Warning (332174): Ignored filter at counter.sdc(6): clock_180 could not be matched with a port or pin or register or keeper or netWarning (332049): Ignored create_generated_clock at counter.sdc(6): Argument -source is an object ID that does not link to any objectInfo (332050): create_generated_clock -name out_clock -source clock_180 [get_ports {clock_output}]Warning (332174): Ignored filter at counter.sdc(7): out_clock could not be matched with a clockWarning (332049): Ignored set_output_delay at counter.sdc(7): Argument -clock is not an object IDInfo (332050): set_output_delay -clock { out_clock } -min -11.5 [get_ports {data}]Warning (332049): Ignored set_output_delay at counter.sdc(8): Argument -clock is not an object IDInfo (332050): set_output_delay -clock { out_clock } -max 5 [get_ports {data}]Warning (332061): Virtual clock clock_0 is never referenced in any input or output delay assignment.Warning (332061): Virtual clock clock_180 is never referenced in any input or output delay assignment.Quote from: Daixiwen on January 30, 2019, 09:54:58 amChecked, the diagram confirms my ModelSim observation - clock delay is not included in calculationQuote from: Daixiwen on January 30, 2019, 09:54:58 amYes I had a look at this user guide, didn't find anything useful for my case. The only thing I found was this, they give option to use create_generated_clock or reference_pin, but only reference_pin works. It's amazing how bad all this entire TimeQuest stuff is documented ...https://web.archive.org/web/20101121073539/http://www.altera.com/support/examples/timequest/exm-tq-basic-source-sync.html

author: possum
author_rank: Contributor
timestamp: January 31, 2019, 07:03:03 am
content: Quote from: NorthGuy on January 30, 2019, 03:35:56 pmNot sure if Cyclone 2 supports this, but even if it may work in this particular scenario, next time I may need another phase shift, for example 45 or 27 degree to fit into external device constraints. And I see only one way to do it properly - by giving second clock with phase shift to the external device. Correct me if I wrong.The issue is not with the design, the issue is with proving it will work (by writing constraints).

author: NorthGuy
author_rank: Super Contributor
timestamp: January 31, 2019, 02:56:10 pm
content: Quote from: possum on January 31, 2019, 07:03:03 amThis wasn't about the clock phase, but the output stages.Quote from: possum on January 31, 2019, 07:03:03 amIt's always about the design. Because the last thing you want to do is to prove that the design doesn't work.I only work with Xilinx. Based on what would work for Xilinx, I would replace this:Code:create_generated_clock -name out_clock -source clock_180 [get_ports {clock_output}]with this:Code:create_generated_clock -name out_clock -source [get_pins {inst1|altpll_component|pll|clk}] -divide_by 1 [get_ports clock_output]However, I suggest you read the docs on "create_generated_clock" to make sure your timing analysis proves what you want it to prove.

author: Daixiwen
author_rank: Frequent Contributor
timestamp: February 01, 2019, 09:29:06 am
content: It's weird, I think I have used named clocks in the source parameter before with success in Quartus, but indeed you could use a get_pins call instead to find your clock.In Timequest if you use the "report clocks" option, do you see clock_180 in the list?