Home > Community > Blogs > Digital Implementation > programatically capturing cell delay in the encounter digital implementation system
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more convenient.

Register | Membership benefits
Get email delivery of the Digital Implementation blog (individual posts).


* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

Programmatically Capturing Cell Delay In The Encounter Digital Implementation System

Comments(11)Filed under: Digital Implementation, static timing analysis, CTE-TCL, TCL, scripting

A while back we were talking about how to programatically troubleshoot timing violations in Encounter.  That post recieved a lot of good comments (thanks!) but one in particular touched on a point that I've worked on with other users, so I thought to raise it up for visibility here and go more in depth on the topic.  Nataraja G asks:

"how can we get the delay values associated with that cell ? is it possible!"

When I first looked at our CTE-TCL inferface for probing timing programmatically I too thought it would be convenient to capture the delay through a given cell.  Then it would be easy to capture all the instances in a given path with delay greater than a given value, for example.  However, it's a little more complicated than that in practice.  It is possible, however, and choosing the best method depends on what exactly you're looking to achieve.

Let's get right into an example of an actual timing path to see how we might be able to extract information about cell delay programmatically.

In this blog entry I'll be seeking to capture the delay through i0 in this simple reg2reg path that goes through a single buffer:

     | Instance |     Arc     |  Cell | Delay | Arrival | Required |
     |          |             |       |       |  Time   |   Time   |
     | i0       | CK ^        |       |       |   0.000 |    0.309 |
     | i0       | CK ^ -> Q v | DFFX1 | 0.286 |   0.286 |    0.595 |
     | i1       | A v -> Y v  | BUFX1 | 0.156 |   0.442 |    0.751 |
     | i2       | D v         | DFFX1 | 0.000 |   0.442 |    0.751 |

Reporting timing through a given instance

Before going too much further, it's probably worth mentioning the "reportDelayCalculation" command.  It's helpful for asking the tool to write out information about how delay was calculated for a given instance.  Here's an abridged example of what it writes out if we call it:

encounter 1> reportDelayCalculation -from i0/CK -to i0/Q
                           Rise        Fall
Input transition time  : 0.120000 ns 0.120000 ns
Effective capacitance  : 0.003261 pF 0.003261 pF
Cell delay             : 0.377800 ns 0.286200 ns
Output transition time : 0.093300 ns 0.079400 ns

This is perhaps useful information, but what if we want to do something more programmatic?

Programatically capturing the delay for a portion of a path

The "get_arcs" command can be useful in situations where you want to capture the delay from any point to any point.  In this case

encounter 38> get_arcs -from i0/CK -to i0/Q

The 0x36 tells us we've caught a "collection" that we can in turn query for more information.  The "report_property" command can be used to list what information we can query for the collection:

encounter 40> report_property [get_arcs -from i0/CK -to i0/Q]   
property                            | value   
arc_type                            | rising_edge
delta_delay_max_fall                | 
delta_delay_max_rise                | 
delta_delay_min_fall                | 
delta_delay_min_rise                | 
delay_max_fall                      | 0.286
delay_max_rise                      | 0.378
delay_min_fall                      | 0.286
delay_min_rise                      | 0.378
is_cellarc                          | true
is_disabled                         | false
mode                                | 
object_type                         | timing_arc
sdf_cond                            | 
sdf_cond_end                        | 
sdf_cond_start                      | 
sense                               | non_unate
source_pin                          | {...}
sink_pin                            | {...}
when                                |

Note that there are rise and fall arcs that go through the instance.  The 0.286 in the timing report happens to be associated with delay_max_fall.  If we wanted, we could capture one of the values explicitly with "get_property":
encounter 42> get_property [get_arcs -from i0/CK -to i0/Q] delay_max_fall  

Programatically capturing the delay for a given instance

With get_arcs, we needed to select from the rising and falling arcs.  If we want to capture the arc that appears in a given timing report for a specific instance, we can capture a timing collection and query its timing_points.  The timing_points are sorted such that we can perform a subtraction of arrival time to determine the delay through any instance.  Here's a proc that finds the delay through a given instance name in a timing collection:

proc user_get_inst_delay {inst_name timing_collection} {
  set timing_points [get_property $timing_collection timing_points]
  set previous_arrival_time 0
  foreach_in_collection timing_point $timing_points {
    set pin [get_property $timing_point pin]
    set pin_name [get_property $pin hierarchical_name]
    set inst [file dirname $pin_name]
    set arrival [get_property $timing_point arrival]
    if {[string match $inst_name $inst]} {
      set cell_delay [expr $arrival - $previous_arrival_time]
    set previous_arrival_time $arrival
  puts "Delay for inst $inst_name is $cell_delay"
Then we could query the delay through a given instance in the path as follows (switching up to i1 here just to show a different value than the next example):
encounter 63> user_get_inst_delay i1 [report_timing -collection]
Delay for inst i1 is 0.156
Programatically capturing instances with delay greater than a certain amount

We could also write the script such that we find the instances with delay greater than a certain amount and potentially do something with those instances like upsize them.  Here's an example of how the script could be reworked to do that:

proc user_get_inst_delay_greater_than {max_delay timing_collection} {
  set timing_points [get_property $timing_collection timing_points]
  set previous_arrival_time 0
  foreach_in_collection timing_point $timing_points {
    set pin [get_property $timing_point pin]
    set pin_name [get_property $pin hierarchical_name]
    set inst [file dirname $pin_name]
    set arrival [get_property $timing_point arrival]
    set cell_delay [expr $arrival - $previous_arrival_time]
    if {[expr $cell_delay > $max_delay]} {
      puts "Delay for inst $inst is $cell_delay"
    set previous_arrival_time $arrival

encounter 62> user_get_inst_delay_greater_than 0.2 [report_timing -collection]
Delay for inst i0 is 0.286


Having the ability to programatically query timing in the physical domain can be a powerful tool.  If you're not that into scripting but you still want to troubleshoot timing you might find our Global Timing Debug utility useful.  It provides a menu-driven way to capture categories of paths with certain characteristics.  For example you could create a category that had all of the paths in the design with more than "n" instances with delay greater than "y".

For more information on programming and timing analysis in Encounter check out the Advanced Timing Tcl Scripting Commands chapter of the Encounter Digital Implementation System Text Command Reference.

Question of the Day: Any tips or tricks related to this you'd like to share?  Any suggestions for improvement?

Robert Dwyer


By Nataraja G on July 30, 2010
this was my requirement , Programatically get cell's with greater than some delay .....
foreach_in_collection timing_point $timing_points {
 set pin_name [get_property [get_property $timing_point pin] hierarchical_name]
 set inst_name [file dirname $pin_name]     "
every instance is occurring twice in timing collection , that y u have used
'if {[lsearch $instNameList $inst_name] == -1} { "
thks again :)

By Nataraja G on July 30, 2010
so whats the reason behind that  ! same instance coming twice

By BobD on August 2, 2010
Hi Nataraja,
The reason the the instances occur twice is because we're tracing through the timing points and each pin is considered a timing point.  If we traverse from input pin to output pin both are associated with the same instance.
Hope this helps.  Thanks again for providing the inspiration for this post.

By Nataraja G on August 10, 2010
thks for clarifying

By Nataraja G on August 10, 2010
and what if we have multiple paths in our collection
like : report_timing  max_points 10  -collection , how to traverse between those paths !!

By BobD on August 11, 2010
If you have multiple paths in the collection you can iterate through them with "foreach_in_collection".  For example of you wanted to print out how many timing points were in each of the first 10 worst paths in the design you could do this:
set c [report_timing -max_points 10 -collection]
set count 1
foreach_in_collection path $c {
 set timing_points [get_property $path timing_points]
 puts "Path $count contains [sizeof_collection $timing_points] timing point(s)"
 incr count

By Nataraja G on August 14, 2010
puts "Path $count contains [sizeof_collection $timing_points] timing point(s)"

using this w'll get double the number of actual timing points right ?




these are not a part of  TCL language from where can i get these

the prospect of  " report_timing -collection "  is huge  

thx a lot ,  :)

if not for u blog's i would be writing some perl script to extract those cell delay etc etc from timing reports

By Nataraja G on August 14, 2010
set a [report_timing  -collection]
i have analyzed the path and now want to write it in a report file , readable format
like in normal reports    velocity 10>report_timing > file.tarpt  
can we do this ?!

By BobD on August 16, 2010
@Nataraja The timing points are about double the number of instances since there's typically an input pin and an output pin on each instance.  I say "about" because for a primary input/output there is only 1 timing point.
sizeof_collection and foreach_in_collection are EDI commands that should be public with documentation.  Are you not seeing them as such?  If so let me know what version you're on- it may be a version before they were documented fully.
I don't know of a way to take a collection and get the detailed path report for it.  It may be possible somehow- I'll check.
As a workaround you might be able to pick off points in the path, particularly the start and endpoints, and report_timing from/to them like this:
set c [report_timing -collection]
report_timing -from [get_property $c startpoint] -to [get_property $c endpoint] > file.tarpt
Hope this is helpful.  Thanks for engaging here in the community- really appreciate it.

By Nataraja G on August 18, 2010
This should do for me "
report_timing -from [get_property $c startpoint] -to [get_property $c endpoint] > file.tarpt "
im using encounter 9.1 , yeah i have seen sizeof_collection and foreach_in_collection 2 days back
i'm new to tool , 8 months it has been
thx a lot , Now i have no trouble querying database,dbGet has made my life easier

By Sunil on July 27, 2011
Thanks for the blog,it is help full in timing debug. Do we have any way  to do the same for collection of nets. I dint find option lilke get_arc for nets.

Leave a Comment

E-mail (will not be published)
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.