Author Topic: FPGA: Please help set up set_output_delay constraints  (Read 5124 times)

0 Members and 1 Guest are viewing this topic.

Offline possumTopic starter

  • Contributor
  • Posts: 13
  • Country: au
FPGA: Please help set up set_output_delay constraints
« on: January 30, 2019, 06:25:25 am »
I'm a beginner ...

I have this simple test project in Quartus 13.0.1

Code: [Select]
module test(input clock_input, output reg data, output clock_output);
initial data = 0;
assign clock_output = clock_input;
always @ (posedge clock_input) begin
data <= data + 1'b1;
end
endmodule

Output clock and data goes to external device, which requires 5ns setup time and 0.5ms hold time So, I wrote this sdc file

Code: [Select]
create_clock -name in_clock -period 20 [get_ports {clock_input}]
derive_pll_clocks
set_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 port
Code: [Select]
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 correct

So, I added the PLL with 2 clocks, one is 180 degree phase shift relative to another. Module now looks like this:

Code: [Select]
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) begin
data <= data + 1'b1;
end
endmodule

and entire project is on the diagram below



I also changes the sdc file to

Code: [Select]
create_clock -name in_clock -period 20.000ns [get_ports {clock_input}]
derive_pll_clocks
create_generated_clock -name clock_0 -source [get_pins {inst1|altpll_component|pll|clk[0]}]
create_generated_clock -name clock_180 -source [get_pins {inst1|altpll_component|pll|clk[1]}]
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 error

Code: [Select]
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?







« Last Edit: January 31, 2019, 06:52:24 am by possum »
 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 365
  • Country: no
Re: FPGA: Please help set up set_output_delay constraints
« Reply #1 on: January 30, 2019, 09:54:58 am »
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: [Select]
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.pdf
It 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.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: ca
Re: FPGA: Please help set up set_output_delay constraints
« Reply #2 on: January 30, 2019, 03:35:56 pm »
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.

 

Offline possumTopic starter

  • Contributor
  • Posts: 13
  • Country: au
Re: FPGA: Please help set up set_output_delay constraints
« Reply #3 on: January 31, 2019, 06:58:31 am »
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 ...

I tried this

Code: [Select]
create_clock -name in_clock -period 20.000ns [get_ports {clock_input}]
derive_pll_clocks
create_generated_clock -name clock_0 -source [get_pins {inst1|altpll_component|pll|clk[0]}]
create_generated_clock -name clock_180 -source [get_pins {inst1|altpll_component|pll|clk[1]}]
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 ignored

Code: [Select]
Warning (332174): Ignored filter at counter.sdc(6): clock_180 could not be matched with a port or pin or register or keeper or net
Warning (332049): Ignored create_generated_clock at counter.sdc(6): Argument -source is an object ID that does not link to any object
Info (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 clock
Warning (332049): Ignored set_output_delay at counter.sdc(7): Argument -clock is not an object ID
Info (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 ID
Info (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.


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.

Checked, the diagram confirms my ModelSim observation - clock delay is not included in calculation

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.pdf
It 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.

Yes 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


 

Offline possumTopic starter

  • Contributor
  • Posts: 13
  • Country: au
Re: FPGA: Please help set up set_output_delay constraints
« Reply #4 on: January 31, 2019, 07:03:03 am »
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.

Not 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).
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: ca
Re: FPGA: Please help set up set_output_delay constraints
« Reply #5 on: January 31, 2019, 02:56:10 pm »
Not 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.

This wasn't about the clock phase, but the output stages.

The issue is not with the design, the issue is with proving it will work (by writing constraints).

It'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: [Select]
create_generated_clock -name out_clock -source clock_180 [get_ports {clock_output}]

with this:

Code: [Select]
create_generated_clock -name out_clock -source [get_pins {inst1|altpll_component|pll|clk[1]}] -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.

 

Offline Daixiwen

  • Frequent Contributor
  • **
  • Posts: 365
  • Country: no
Re: FPGA: Please help set up set_output_delay constraints
« Reply #6 on: February 01, 2019, 09:29:06 am »
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?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf