Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16597 Discussions

How to properly constrain generated clock and synchronizer?

fhw72
Beginner
3,185 Views

Hello!

In my Verilog design I have a 25Mhz board clock from which I derive a 100Mhz clock. Coming from an external Pin I have an asynchronous 4.77 Mhz clock which should drive the logic and be synchronized before (using the main clock):

always @(posedge clk_100Mhz_i) begin // Synchronizer chain... hopefully clk4_del0 <= clk4_77_i; // SysClk from ext pin clk4_del1 <= clk4_del0; clk4_del2 <= clk4_del1; end   // Used to clock internal regs assign clock_4_77Mhz = clk4_del2;   // Sample always @(posedge clock_4_77Mhz) begin timerIdx <= timerIdx +1; end

Unfortunately I get the following warning:

 

Warning (332060): Node: X8255_top:x8255|clk4_del2 was determined to be a clock but was found without an associated clock assignment....

 

I also get a warning about an unconstrained clock. I tried to use what the Timing Analyzer suggested and added the fourth line to my .SDC:

# Constrain clock port clk_25MHz_i create_clock -period "25.0 MHz" -name clk_25MHz [get_ports clk_25MHz_i] create_clock -period "4.77 MHz" -name clk_4_77MHz [get_ports clk_4_77_i] create_clock -name {X8255_top:x8255|clk4_del2} -period 210

without success.

 

What am I doing wrong?

 

0 Kudos
8 Replies
sstrell
Honored Contributor III
2,104 Views

Assuming clock_4_77Mhz is a clock that is driving other logic in your design not shown in this code, it would need to be constrained as a generated clock, not a base clock, since it originates inside the device. There should also be a generated clock constraint for clk_100MHz_i since you say it is generated based on clk_25MHz_i. clk_4_77_i is technically not considered a clock by the timing analyzer since it goes into a data input of a register, not a clock pin, but clock_4_77Mhz is a clock. I highly recommend using a PLL to simplify all this.

 

So here's my best guess (without seeing your whole design) as to what your .sdc should look something like:

 

create_clock -period 40 [get_ports clk_25MHz_i] -name clk_25MHz

# use derive_pll_clocks if you're using a PLL (which I'd recommend because it simplifies all of this) or:

create_generated_clock -source [get_ports clk_25MHz_i] -multiply_by 4 <input clock pin of clk4_del0 register> -name clk_100MHz_i

 

create_generated_clock -source <input clock pin of clk4_del2 register> -name clk_4_77MHz -divide_by 21 <output pin of clk4_del2 register>

 

 

0 Kudos
fhw72
Beginner
2,104 Views

At first I'd like to thank you for taking your time. 🙂

 

Unfortunately I was not able to translate your recommandation into a working .SDC.

The 100Mhz clock in my design is created by a PLL instantiated in the top level module "X8255_top" (Name: clk_100Mhz, Output of the PLL: c0):

// // Instantiate clock generator/PLL // wire clk_100MHz; wire pll_locked; X8255_clkgen pll( .inclk0(clk_25MHz_i), .c0(clk_100MHz), .locked(pll_locked) );

This is the .SDC I created:

(Please mind that the clk25/clk100 are asynchronous to the 4.77MHz clock; I added line 11 therefore)

# Constrain clock port clk_25MHz_i create_clock -period "25.0 MHz" -name clk_25MHz [get_ports clk_25MHz_i] create_generated_clock -source [get_pins X8255_top/clk_100MHz] -name clk_4_77MHz -divide_by 21 [get_pins clk4_del2]   # Automatically apply a generate clock on the output of phase-locked loops (PLLs) # This command can be safely left in the SDC even if no PLLs exist in the design derive_pll_clocks derive_clock_uncertainty   # Clocks are unrelated / asynchronous set_false_path -from [get_clocks clk_25MHz] -to [get_clocks clk_4_77MHz ]

Unfortunately I now get these warnings (shortened to make more readable):

 

Warning (332174): Ignored filter at X8255_top.sdc(3): X8255_top/clk_100MHz could not be matched with a pin

Warning (332174): Ignored filter at X8255_top.sdc(3): clk4_del2 could not be matched with a pin

Warning (332049): Ignored create_generated_clock at X8255_top.sdc(3): Argument -source is an empty collection

 

Warning (332174): Ignored filter at X8255_top.sdc(11): clk_4_77MHz could not be matched with a clock

Warning (332049): Ignored set_false_path at X8255_top.sdc(11): Argument <to> is an empty collection

   Info (332050): set_false_path -from [get_clocks clk_25MHz] -to [get_clocks clk_4_77MHz]

Warning (332060): Node: X8255_top:x8255|clk4_del2 was determined to be a clock but was found without an associated clock assignment.

   Info (13166): Register X8255_top:x825..... is being clocked by X8255_top:x8255|clk4_del2

 

0 Kudos
sstrell
Honored Contributor III
2,104 Views

With a PLL, that simplifies your .sdc. It should look like this with the info you've now provided:

 

create_clock -period 40 [get_ports clk_25MHz_i] -name clk_25MHz

derive_pll_clocks

derive_clock_uncertainty

 create_generated_clock -source <output clock pin of PLL> -name clk_4_77MHz -divide_by 21 <output pin of clk4_del2 register>

set_false_path -from [get_clocks clk_25MHz] -to [get_clocks clk_4_77MHz ]

 

derive_pll_clocks has to come before any constraint that uses the clock from the PLL, so your order is wrong. For "output clock pin of PLL" and "output pin of clk4_del2 register", you'll need to use the Name Finder to find the actual names of the pins, accessible from the create_generated_clock dialog box in the Quartus Text Editor. "X8255_top/clk_100MHz" is not correct because that's what you have in your HDL code, which is not the same as the timing netlist used by the timing analyzer.

JonWay_C_Intel
Employee
2,104 Views

There is a kdb on the warning:

https://www.intel.com/content/www/us/en/programmable/support/support-resources/knowledge-base/solutions/rd10022013_898.html

 

I would agree that a PLL would simplify the sdc.

0 Kudos
fhw72
Beginner
2,104 Views

@sstrell:

Many thanks! Your explanation and the provided lines helped to solve the problem

and finally *understand* it!

0 Kudos
fhw72
Beginner
2,104 Views

@sstrell:

 

I'm now trying to constrain the inputs and outputs of my design and appended these lines:

 

# Constrain the input I/O path

set_input_delay -clock clk_1MHz -max 5 [all_inputs]

set_input_delay -clock clk_1MHz -min 0 [all_inputs]

 

# Constrain the output I/O path

set_output_delay -clock clk_1MHz -max 5 [all_outputs]

set_output_delay -clock clk_1MHz -min -1 [all_outputs]

 

5ns is the delay for the level shifters used on the in- and outputs of the design.

However I always get a setup violation?

 

Do you have an idea what I'm doing wrong?

 

PS: What should I do with 'altera_reserved_tck' which appears in my ReporT?

0 Kudos
sstrell
Honored Contributor III
2,104 Views

First of all, you need to define two virtual clocks, clock constraints for the clocks that drive the "upstream" and "downstream" devices. These constraints will have no target:

 

create_clock -period <period> -name <custom name for virtual clock> [-waveform <rise fall>]

 

Your set_input[output]_delay constraints need to reference the virtual clocks. (What is clk_1MHz?)

 

Next, the value you use for these constraints is calculated based on the max and min external delays to and from the FPGA for inputs and outputs, respectively.

 

There's a lot to this, so I'd recommend reviewing this online training for details:

 

https://www.intel.com/content/www/us/en/programmable/support/training/course/odsw1118.html

0 Kudos
fhw72
Beginner
2,104 Views

Ups... I mixed up the SDC from another similar project; it should have been:

clk_4_77MHz (instead of clk_1Mhz)

 

What do you mean by Up- and downstream devices?

What frequency do I have to use for the virtual clocks and why two virtual clocks?

 

I will dig through the tutorials asap... but right now I'm stuck. :-(

Maybe you also have a pointer to a good example too?

 

 

 

 

 

0 Kudos
Reply