TimeQuest User Guide

TimeQuest User Guide

and is something the user should think about as soon as they do a small phase-shift on a clock.

This multicycle is called shifting the window .

If any of this discussion on default setup and hold relationships is confusing, please read

the basics of setup and hold

, as well as the following section on determining default setup and hold relationships.

- Add a create_generated_clock to ripple clocks. Basically anytime a register's output drives the .clk port of another register, that is a ripple clock. Clocks do not propagate through registers, so all ripple clocks must have a create_generated_clock constraint applied to them for correct analysis. Unconstrained ripple clocks will show up in TimeQuest's task "Report

Unconstrained Paths", so they are easily recognized. In general, ripple clocks should be avoided for many reasons, and if possible, a clock enable should be used instead.

- Add a create_generated_clock to clock mux outputs. Without this, all clocks propagate through the mux and will be related. TimeQuest will analysis paths downstream from the mux where one clock input feeds the source register and the other clock input feeds the destination, and vice-versa. Although it could be valid, this is usually not what user’s want. By putting

create_generated_clock constraints on the mux output, relating them to the clocks coming into the mux, the user can correctly group these clocks with other clocks.

I/O Timing

(Note: This section does not explicitly cover source-synchronous interfaces, although they use the same principles.)

There are only two I/O specific .sdc commands, set_input_delay and set_output_delay, and they can be difficult to grasp at first. The most important concept is that these constraints describe what is going on outside of the FPGA, and with that information TimeQuest figures out what is required inside the FPGA. I break this down into 5 steps, which is important for the first time through, although quickly becomes intuitive:

Steps for I/O Timing:

1) Add create_clock to create a virtual clock for the I/O interface

2) Add set_input_delay or set_output_delay to the I/O port/s. Add it twice, once using the option -min and once using -max, and have 0.0 be the value in both cases. (This will be modified in step 5)

3) Determine the default setup and hold relationships between the FPGA clock and the virtual clock

4) Add multicycles if these default relationships are not correct

5) Modify the -max and -min delay values to account for external delays

I want to point out that the values used for the set_input_delay and set_output_delay are entered last, which is the opposite of what most new users do. Going through the first steps will make it apparent why. Also note that bidirectional I/O are really analyzed as inputs and outputs, so they usually have both set_input_delay and set_output_delay assignments.

Step 1) Use create_clock to add a virtual clock for the I/O interface

14

This is always the first step, which is certainly not intuitive. If the FPGA communicates with a PCI device that runs at 66MHz and a DAC running at 200MHz then the user might add the following to their SDC file:

create_clock -period 15.151 -name pci_clk_ext create_clock -period 5.0 -name dac_clk_ext

Note that I did not apply these clocks to anything in the FPGA, which is what makes them virtual clocks; they exist outside of the FPGA. How this will be used becomes apparent in the next few steps, but this step is usually easy since it reflects what's occurring in hardware.

Step 2) Add set_input_delay or set_output_delay on the I/O port/s

Add it twice, once using -min and once using -max. Use the value 0.0 for both delays, and the virtual clock for the clock.

The instructions are long, but it's really quite easy. If constraining an output port called

DAC_DATA[5], I might put in my .sdc:

set_output_delay -clock dac_clk_ext -max 0.0 [get_ports DAC_DATA[5]] set_output_delay -clock dac_clk_ext -min 0.0 [get_ports DAC_DATA[5]]

As specified, the -clock option was filled with the virtual clock created in step 1), and the

-max and -min values are 0.0. That 0.0 is just a placeholder we will modify in step 5 .

For an input bus where I want all ports to have the same constraint, I might do:

set_input_delay -clock adc_clk_ext -max 0.0 [get_ports ADC_DATA[*]] set_input_delay -clock adc_clk_ext -min 0.0 [get_ports ADC_DATA[*]]

This step is straightforward since it’s just following the instructions without any analysis, but it's important to understand what the command does. Intrinsically they do not really

“constrain” anything, and instead describe what is going on outside of the FPGA. Looking at our output constraint, let's break down its components:

1. set_output_delay

2. -clock dac_clk_ext

3. -max/-min 0.0

There is a register being driven by an FPGA output

This register is clocked by our virtual clock dac_clk_ext

The external delay has a max of 0.0 and min of 0.0

4. [get_ports DAC_DATA[5] The register is driven by port DAC_DATA[5]

Let's look at this command in schematic format:

15

As can be seen, we just described a circuit outside the FPGA. We also now have a register feeding another register. This is the standard path analysis done on every path inside the

FPGA.

Step 3) Determine the default setup and hold relationship between the

FPGA clock and virtual clock

This step requires the user to determine the setup and hold relationship between the clock inside the FPGA and the virtual external clock. This is usually very straightforward, as in most cases the launch clock and latch clock have the same period and are edge aligned, and hence have a setup relationship equal to the clock period, and a hold relationship of 0ns, as shown in the top-left example:

16

For I/O, the virtual clock will be the launch clock for input constraints, and the latch clock for output constraints. I've shown a few more cases, but won't delve into too much detail

on how to determine the setup and hold relationship, which is covered in-depth in Timing

Analysis Basics .

Rather than delve into calculating the relationship, I'll show how TimeQuest will show the relationship it is using, and hence the user doesn't have to figure it out beforehand. For example, a user might have a 100MHz clock coming into the FPGA, which goes through a PLL and drives data out at 100Mbps. After following the previous steps, the user creates a 10ns external clock and applies it to the output ports like so: create_clock -period 10.0 -name tx_clk_ext

set_output_delay -clock tx_clk_ext -max 0.0 [get_ports {TX_DATA[*] TX_PAR}] set_output_delay -clock tx_clk_ext -min 0.0 [get_ports TX_DATA[*] TX_PAR}]

In this example, they've created a virtual clock called tx_clk_ext. They also said the ports

TX_DATA[*] and TX_PAR drive external registers clocked by tx_clk_ext, and the max and min delay to those registers is 0.0ns. Since the internal clock also has a period of 10.0ns, and neither is phase-shifted, then the default setup relationship is 10.0ns and the default hold relationship is

0.0ns. If the user is unsure of this, they can read in the .sdc file using the iterative method and

run report_timing to those ports. In TimeQuest's pull-down menu: Reports -> Custom Reports -

> Report Timing. Simply put the virtual clock name, tx_clk_ext, in the To Clock section, and run report_timing twice, once for setup and once for hold. In this example, I got the following two reports:

The left panel is the setup analysis, and the Relationship column, shown in red, is 10ns.

This is expected, as we have a 10ns clock feeding another 10ns clock. Below the Summary of

Paths is the detail for the first path. The 10ns is used such that the launch edge time is 0ns and

17

the latch edge time is 10ns. Likewise for hold analysis, the relationship is 0ns. The launch edge time is 0ns and the latch edge time is 0ns.

So what is this really saying? When the launch clock comes into the FPGA, travels to the source register, which is the output register in this case, then through the output port to the external register, it must get there in greater than 0ns(the hold relationship) and less than

10ns(the setup relationship). Since our external -max and -min delays are 0ns, i.e. there is no external delay, than the delay within the FPGA must be greater than 0ns and less than 10ns. At this point, we have a full constraint that TimeQuest can analyze, but it is probably not the analysis we want.

Step 4) Add multicycles

This step is usually unnecessary. But if step 3) resulted in a default analysis that is incorrect, the user may want to modify the setup and hold relationships with multicycles. The most common cases for this are when the user wants to open the window or shift the window.

Note that we are not accounting for external delays like the Tsu or Tco of an external device or board delays, as that will be done in step 5. This step is just to make sure the clock relationships are correct.

An example would be interfacing to a flash device that takes multiple clock cycles to

perform each operation, than the user may want to open the window . An example may look like

so:

set_multicycle_path -setup -to [get_ports {FLASH_DATA[*]}] 4 set_multicycle_path -hold -to [get_ports {FLASH_DATA[*]}] 3

These two assignments tell TimeQuest that there are 4 clock cycles for the

FLASH_DATA to get out of the FPGA. So if the original setup and hold relationships were

10ns and 0ns, they would now be 40ns and 0ns(assuming the clock period is 10ns).

If the clock inside the FPGA has a phase-shift, generally through a PLL, and the external

clock does not, then the user may want to shift the window . For example, if the FPGA clock

feeding an output register were phase-shifted -500ps in order to help meet output timing, the default setup relationship would be 500ps. To shift the window, the user would add:

set_multicycle_path -setup -to [get_ports {FLASH_DATA[*]}] 2 or:

set_multicycle_path -setup -from [get_clocks {pll|clk[0]} -to [get_clocks clk_ext] 2

The first one modifies the clock relationship on the output path, while the second one modifies all relationships between these clocks. Either one of these will work as long as they cover what the user wants covered. If the clocks have a 10ns period, the multicycle will modify the setup relationship from 0.5ns to 9.5ns, and the hold relationship from -9.5ns to 0.5ns.

Note that if the FPGA clock were phase-shifted forward a little, then a multicycle would most likely not be necessary. If the default setup relationship were 10ns, and the source clock inside the FPGA were phase-shifted 500ps forward, then the default relationship would become

9.5ns, which is probably what the user wants.

18

Inputs work the opposite, whereby if the user phase-shifts the latching clock inside the

FPGA forward a little, then they probably want a multicycle to shift the window, but if they phase-shift the clock back, they probably do not. This is easily seen by drawing the launch and

latch clock waveforms, as explained in the section on default setup and hold , specifically the

affect of phase-shifts .

Step 5) Modify the -max and -min delays to account for external delays.

Now that we have the correct setup and hold relationship, it is time to modify the -max and -min values. They are currently set to 0, which means there is no external delay to the register. This allows the entire data window to be used by FPGA delays. In reality, part of the data window is used by the external device and board delays, only leaving part of the data window for the FPGA. The -max and -min values account for these external delays. Let's see how they affect the analysis before determining how they account for external delays.

With both -max and -min at 0, we are stating that there are no external delays, and basically have no affect on the analysis. As the -max value gets larger, it cuts into our setup relationship. So if the our default setup relationship were 10ns, and the -max output delay were

4ns, that would mean the FPGA must get it's data out in less than 6ns to meet timing. Note the setup relationship is still 10ns, but the FPGA's delay plus the external delay must be less than that. So the larger -max gets, the more quickly the FPGA needs to get its data out and the harder it is to meet timing. As the -max value gets larger, the FPGA needs a faster Tco.

The -min value is often more confusing because it works in the opposite way, whereby the smaller it gets, the harder it is to meet timing. If the hold relationship is 0ns, and the -min value was -1ns, then the only way to meet timing would be for the FPGA to get its data out in more than 1ns. Looking at this through waveforms:

The top waveform shows the default relationships, while the second waveform shows what happens after accounting for the external delays. Rather than the FPGA needing to get it's data out between 0ns and 10ns, it must now get out between 1ns and 6ns. Likewise, for internal paths, if a user entered similar external delays:

19

It may seem confusing that the green and purple arrows do not start at the same point.

What's being shown is that when the external clock launches data, it can take anywhere from -

1ns to +4ns to reach the FPGA. We use the larger number for the setup analysis, and the smaller number for the hold analysis.

How these external delays are actually added into the timing reports is shown in the

upcoming section on correlating constraints to the timing reports .

One thing to note is that, as the difference between -max and -min values grows, the more difficult it is for the FPGA to meet timing. In the output example above, the default relationship says the data must transfer between 0ns and 10ns. As the external delay spreads from our original placeholder of 0ns for -min and -max, to -1ns and 4ns, the external device now uses 5ns of that 10ns window, and so the FPGA only has 5ns to work with. I wanted to point this out, because users often don't see the relationship right away, and it often helps with understanding.

So now that we conceptually know how the external delays work, let's account for real external delays by looking at the output side first:

External device parameters:

Tsu_ext = Tsu of external device

Th_ext = Th of external device

Data delays on board:

Max_fpga2ext = Max board delay to external device min_fpga2ext = min board delay to external device set_output_delay -max = Tsu_ext + Max_fpga2ext set_output_delay -min = -Th_ext + Min_fpga2ext

For input constraints, they look like so:

External device parameters:

Tco_ext = Tsu of external device minTco_ext = Th of external device

Data delays on board:

Max_ext2fpga = Max board delay from external device to FPGA min_ext2fpga = min board delay from external device to FPGA

Clock delays on board:

20

Max_clk2fpga = Max delay from board clock to FPGA min_clk2fpga = min board delay from clock to FPGA

Max_clk2ext = Max delay from board clock to external device min_clk2ext = min board delay from clock to external device set_input_delay -max = Tco_ext + Max_ext2fpg set_input_delay -min = minTco_ext + min_ext2fpga

The user could actually put variables and equations into their .sdc file, which is shown in

the Tcl Syntax section.

Note that these equations did not take into account board level clock skew, and is basically assuming the clock to the FPGA and external device are equivalent. There is a very nice .sdc constraint for entering board-level clock delays, which I will show in a second, but what I see most users do is roll their board-level clock skews into the -max and -min values.

(Note that clock skew is positive when the delay to the destination is larger than the delay to the source). Anyway, rolling clock skew into the delays looks like so:

External device parameters:

Tsu_ext = Tsu of external device

Th_ext = Th of external device

Data delays on board:

Max_fpga2ext = Max board delay to external device min_fpga2ext = min board delay to external device

Clock delays on board:

Max_clk2fpga = Max delay from board clock to FPGA min_clk2ext = min board delay from clock to external device

Max_clk2ext = Max delay from board clock to external device min_clk2fpga = min board delay from clock to FPGA set_output_delay -max = Tsu_ext + Max_fpga2ext - (min_clk2ext - Max_clk2fpga)

= Tsu_ext + Max_fpga2ext - (min_clk_skew) set_output_delay -min = -Th_ext + min_fpga2ext - (Max_clk2ext - min_clk2fpga)

= -Th_ext + min_fpga2ext - (Max_clk_skew)

For input constraints:

External device parameters:

Tco_ext = Tco of external device minTco_ext = min Tco of external device

Data delays on board:

Max_ext2fpga = Max board delay from external device to FPGA min_ext2fpga = min board delay from external device to FPGA

Clock delays on board:

Max_clk2fpga = Max delay from board clock to FPGA min_clk2fpga = min board delay from clock to FPGA

Max_clk2ext = Max delay from board clock to external device min_clk2ext = min board delay from clock to external device set_input_delay -max = Tco_ext + Max_ext2fpg - (min_clk2fpga - Max_clk2ext)

= Tco_ext + Max_ext2fpg - (min_clk_skew) set_input_delay -min = minTco_ext + min_ext2fpga - (Max_clk2fpga - min_clk2ext)

21

Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Related manuals

Download PDF

advertisement

Table of contents