Home > Community > Blogs > Digital Implementation > saving your skin with quot report timing collection quot
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more conveniennt.

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 Troubleshooting Timing Violations With "report_timing -collection"

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

Has something like the following ever happened to you?

You've placed and optimized a design, and you see what appears to be timing violations that could be fixed with cell changes on the worst path in the design.  Like the path below that has a lot of "X1" strength cells (don't worry, I contrived this case by timing the design prior to running optDesign to exaggerate the point):


If you wanted to test the theory that timing on this path could be improved by changing all of the "X1" strength drivers to "X2" strength, how would you go about it?

I've seen scripts that parse the text output of report_timing and try to find the instance name strings that need to be upsized, but that's clunky and the parsing is a nightmare.  Another approach is to use "report_timing -tcl_list" but that merely creates a massive list of strings that aren't sorted very usefully.

What I *have* found useful is "report_timing -collection".

Here's a script that replaces all of the X1 cells in the worst path in the design with X2 cells:

set collection [report_timing -collection]
set timing_points [get_property $collection timing_point]
set instNameList {}
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]
  if {[lsearch $instNameList $inst_name] == -1} {
      lappend instNameList $inst_name

foreach instName $instNameList {
  set inst [dbGetInstByName $instName]
  set cellName [dbGet $inst.cell.name]
  if {[string match *X1 $cellName]} {
    regsub {X1$} $cellName {X2} newCellName
    ecoChangeCell -inst $instName -cell $newCellName

Okay, let's break it down Kari Summers-style. First, we'll capture a list of the unique instances in the path:

set collection [report_timing -collection] --> capture the output of report_timing -collection to a variabel for later processing (tip: use "report_property $collection" to query all of the fields report_property -collection returns)
set timing_points [get_property $collection timing_points] --> we'll pick off the "timing_points" field which is a list of all the pins along the path
set instNameList {} --> initialize an empty list which we'll use to capture a unique list of instances on the path
foreach_in_collection timing_point $timing_points { --> iterate through each of these timing points
  set pin_name [get_property [get_property $timing_point pin] hierarchical_name] --> the pin names are of the for i0/Y
  set inst_name [file dirname $pin_name] --> this is a handy trick I learned from Ed Martinage (our Common Timing Engine guru) for stripping the tailing "/Y" off pin names
  if {[lsearch $instNameList $inst_name] == -1} { --> add each instance to the list only if it isn't there already to create a unique list of instances
     lappend instNameList $inst_name

Next, we'll iterate through this list and change the cells from "X1" to "X2" strength:

foreach instName $instNameList { --> iterate through each unique instance name
  set inst [dbGetInstByName $instName] --> get the instance pointer...
  set cellName [dbGet $inst.cell.name] --> ...and use dbGet to find the instance's cell name
  if {[string match *X1 $cellName]} { --> check whether the cell name ends in "X1"
    regsub {X1$} $cellName {X2} newCellName --> if so swap it out for an X2 cell:
    ecoChangeCell -inst $instName -cell $newCellName

This in turn will call ecoChangeCell for each matched instance, changing them from X1 cells to X2s:

<CMD> ecoChangeCell -inst DTMF_INST/TDSP_CORE_INST/EXECUTE_INST/top_reg_0 -cell SEDFFX2
Starting refinePlace ...
Statistics of distance of Instance movement in detailed placement:
  maximum (X+Y) =         0.00 um
  mean    (X+Y) =         0.00 um
Total instances moved : 0
*** cpu=0:00:00.1   mem=276.3M  mem(used)=0.0M***


  • If the X2 strength of a given cell doesn't exist, ecoChangeCell will warn and proceed
  • Another approach to this could have been to use "ecoChangeCell -upsize" instead of explicity identifying the desired cell name
  • "setOptMode -updateTiming -false" can be used to suppress timing updates when implementing a series of changes
I think there are lots of situations where "report_timing -collection" could be useful. I personally use it when creating testcases for our developers.  I'll establish a PASS/FAIL criteria that, for example, no HVT cells should appear on the worst path in the design with negative slack (else the HVT cell should have been swapped out for a non-HVT and timing would have been improved). I hope this example shows a framework with sufficient detail that it is a helpful starting point for building other scripts.

By the way, I received inspiration for this kind of post from Nir Dahan's Adventures in Digital ASIC Design (http://asicdigitaldesign.wordpress.com). His focus is a little more front-end than mine, but I like his useful approach to blogging. I'd encourage you to check him out.

Update (July 26, 2010): I wrote some examples of how to capture the delay through an individual instance in this post.

Question of the Day: What do you think of this approach? Have you used "report_timing -collection"? Can you think of other scenarios where this could be useful?


By RahulRc on February 12, 2009
hi BobD,
thank for easy to understand and simple script.
this script can surely be used for HVT-non-HVT swapping.

By Thomas Moore on February 12, 2009
I love it!  When you described the approaches of parsing the reports and tcl_list, I've used both these methods and this simplifies it completely.  One thing I like to do prior to a large set of ecoChangeCell is call 'setOptMode -rPlace false'.  I'm not sure if setOptMode -updateTiming -false does the same thing, but  once all the eco changes have been made, I just call 'refinePlace'.  Saves a lot of time this way!  

By maven7783 on February 12, 2009
Thanks Robert,
your script is very useful.
This is first time i heard and used report_timing -collection,i will work on it post some commetns later.

By BobD on February 13, 2009
Thanks for the comments, folks!
@RahulRc You're absolutely right- the HVT to non-HVT was the original situation for which I wrote this script.
Thom- That is an excellent point about "setOptMode -rPlace false"- I use that one all the time myself.
@maven7783 I'll look forward to your comments!

By eminemshow on February 14, 2009
Bob, it is really exciting to see posts like this, it makes me remind the days when using SOC5.2, that time the Advanced Timing TCL commands are not ready yet.......so I have to analyze the report dumped by report_timing and then parse it. Now with SOC7.1, it is really easy to resize the cells. Your script is a great example of how to use 'get_property' and 'dbGet' commands. Hope to see more scripts like this in the future. Thank you, Bob, you creative AE!

By BobD on February 16, 2009
Hi @eminemshow! Thanks for your kind words- I appreciate them. You raise a good point about this script example- it uses all 3 of the db access mechanisms in conjunction with one another: CTE-TCL (ie, "get_property"), FE-TCL (ie, "dbGetInstByName), and dbGet (ie, dbGet $inst.cell.name). The script could be altered to use more of one mechanism and less of the others, but using CTE-TCL is a must because it gives us report_timing -collection and get_property timing_points. I'll surely follow-up with more scripting examples like this in the future.

By NAADHAN on April 13, 2009
Hi Bob, i like this post very much personally because i have started to learn scripting on my own and this would not only help in learning them...but also help me in timing debugging easily....
I will also think of  other scenarios where this can be used used with little modifications..
thanks a lot BobD :-)

By Nataraja G on June 22, 2010
how can we get the delay values associated with that cell ?? ?
is it possible ! >>
ur blogs are the best :)  nice way to start

By BobD on July 22, 2010
@Nataraja sorry for taking a while to post and reply to your comment.  I'll show an example of getting delay values for an instance in an upcoming blog entry.

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.