Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20638 Discussions

Stop_at_clocks substitute in Quartus Standard

paw_93
Novice
874 Views

Hello,

 

I would like to ask if there is a substitute of the argument Stop_at_clocks (get_fanins) that exist for Quartus Pro but doesn't work for Standard Edition? I always end up with refclock instead of a PLL output.

The error I see is:

"More than 1 positional argument specified: -stop_at_clocks, clk_0"

It looks like interpretation of that argument is not implemented.

 

I would like to retrieve a period of an input and output clock of a synchroniser. My strategy in Quartus Pro is just to take fanin of a register No.1 and figure out a name of the clock. That's easy. I use stop_at_clocks attribute to not to obtain refclock all the time, but the output of PLL if necessary. Then I get all the clock object with the following command.

set clks [all_clocks]

After I have all the clocks in a collection I compare the clock of a register with all the clocks from the set. Based on that I can relate a clock from which I extract a period. This is supposed to modularize my bus synchroniser. Setting max and min delay should ensure correctness of all the bits.

 

 

Additional question. What is the reason to distinguish pin & pin_objects, clock & clock_objects. Can we easily convert between them? Why I cannot easily retrieve clock period information from a clock_object? The naming of the type is provided by the function:

get_object_info -type $my_reg

 

I followed mostly the following example:

Get Clocks Feeding a Pin:

https://www.intel.com/content/www/us/en/support/programmable/support-resources/design-examples/quartus/exm-tq-clocks-feeding-register.html

 

 

The code that works for me in Quartus Pro 20.4 but doesn't in Quartus Standard 21.1:

top.sdc

set_time_format -unit ns -decimal_places 3

set_operating_conditions -model slow -voltage 1100 -temperature 85

create_clock -name clk_in1 -period 84.00MHz [get_ports {clk_in1}]

# Automatically constrain PLL and other generated clocks (there should be clk_in2 derived from this PLL)
derive_pll_clocks -create_base_clocks -use_net_name

# Automatically calculate clock uncertainty to jitter and other effects.
derive_clock_uncertainty

bus_synchroniser.sdc

# Get the register that I want to constrain
set kprs [get_registers {*sync_bus:*|ci_dta_r[*]}]
# Get a list of all clocks in the top-level design
set clks [all_clocks]
foreach_in_collection clk $clks {
   puts [get_clock_info -name $clk]
   set fanins [get_fanins -clock -stop_at_clocks $clk]

}
set cdc_period_ratio 0.95

# Match my register to two of the clocks from the lists - clock feeding the register and a clock of the output signal target.

# Iterate over synchronisation input registers
foreach_in_collection kpr $kprs {
  set str1 "|Register in: "
  set regIn [get_object_info -name $kpr]


# Get a list of all registers driven by each clock
set str3 "|Clock in: "
set clkIn ""
set in_period 0.00ns

set fanins [get_fanins -clock -stop_at_clocks [get_object_info -name $kpr]]
foreach_in_collection fanin $fanins {
   set clkIn [get_object_info -name $fanin]
   set clknet [get_pin_info -net $fanin]

       foreach_in_collection clk $clks {
          if {[get_object_info -name $clk] == [get_object_info -name $clknet]} {
              set in_period [get_clock_info -period $clk]
          }
      }
}

}

 

 

0 Kudos
1 Solution
Ash_R_Intel
Employee
773 Views

Hi Pawel,


Got some ideas from software experts. Please try them and let me know if things work for you.


The following procedures take a node or a pin, and return the list of all clock targets feeding it. You should be able to modify these to make them return the clock target(s) feeding the register. You can then create a map of clock targets to clock names, so that you can find the clocks that exist on those targets. Once you have the clocks, you can simply string-compare them against each other to see if they are equivalent (since clock names are unique).


proc get_clock_targets_feeding_node { node } {

set my_clocks [list]

foreach_in_collection path [get_path -to [get_object_info -name [get_edge_info -src [get_node_info -clock_edges $node]]]] {

lappend my_clocks [get_object_info -name [get_path_info -from $path]]

}

return $my_clocks

}


proc get_clock_targets_feeding_pin { pin } {

set my_clocks [list]

foreach_in_collection path [get_path -to $pin] {

lappend my_clocks [get_object_info -name [get_path_info -from $path]]

}

return $my_clocks

}


Regards


View solution in original post

6 Replies
paw_93
Novice
823 Views

There is no way to extract a period of PLL clock feeding a chosen register in Quartus Standard edition?

0 Kudos
Ash_R_Intel
Employee
805 Views

Hello,

I am sure there is a way to do that. Kindly follow the list of TCL commands provided in the Quartus Help. Combining multiple commands and customizing them as shown in the design example should do the trick.

I am not an expert is Quartus software TCL commands. However, I will get help from experts by raising an internal ticket. Your patience will be appreciated till I get some response from software experts.


Thanks in advance!


Regards


paw_93
Novice
780 Views

Hello Ash_R,

 

Thank you for your reply and engagement. Just to update you - I am playing with get_clock_info -targets  command plus some recursive algorithms. So far without success.

 

0 Kudos
Ash_R_Intel
Employee
774 Views

Hi Pawel,


Got some ideas from software experts. Please try them and let me know if things work for you.


The following procedures take a node or a pin, and return the list of all clock targets feeding it. You should be able to modify these to make them return the clock target(s) feeding the register. You can then create a map of clock targets to clock names, so that you can find the clocks that exist on those targets. Once you have the clocks, you can simply string-compare them against each other to see if they are equivalent (since clock names are unique).


proc get_clock_targets_feeding_node { node } {

set my_clocks [list]

foreach_in_collection path [get_path -to [get_object_info -name [get_edge_info -src [get_node_info -clock_edges $node]]]] {

lappend my_clocks [get_object_info -name [get_path_info -from $path]]

}

return $my_clocks

}


proc get_clock_targets_feeding_pin { pin } {

set my_clocks [list]

foreach_in_collection path [get_path -to $pin] {

lappend my_clocks [get_object_info -name [get_path_info -from $path]]

}

return $my_clocks

}


Regards


paw_93
Novice
742 Views

Dear @Ash_R_Intel

 

Thank you very much for providing these functions. I think I have succeeded with my goal. Of course it needs to be tested and used in a larger design, but in a minimal case it works perfectly.

 

To make it work properly I need to derive pll clocks with -use_net_name attribute.

derive_pll_clocks -use_net_name

 

I also had to add a function that returns a clock from a target - the working principle is opposite to the "-target" attribute:

#provide a target, receive clock
proc returnClkFromTarget {targetIn} {
     set clks [all_clocks]
     set clkOut ""
     foreach_in_collection clk $clks {
         set target [get_clock_info -targets $clk]
         if {[get_object_info -name $targetIn] == [get_object_info -name $target]} {
             set clkOut $clk
     }
}
puts [get_clock_info -name $clkOut]
puts "net found"
return $clkOut
}

 

Now having all these functions above it is possible to obtain a clock and find a period:

 

set clkOut_o [get_clock_targets_feeding_node $regOut]
set clkOut [returnClkFromTarget $clkOut_o]

set out_period [get_clock_info -period $clkOut]

 

 

Thank you once again and have a nice day!

Pawel

0 Kudos
Ash_R_Intel
Employee
722 Views

Glad to know this. Closing the case!


Regards


0 Kudos
Reply