Home > Community > Blogs > Digital Implementation > encounter puzzler 2 finding registers beneath a hierarchy
 
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).
 

Email

* 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: *

Encounter Puzzler #2: Finding Registers Beneath a Hierarchy

Comments(10)Filed under: Digital Implementation, dbGet, encounter, TCL, puzzler

I hope you enjoyed our first Encounter Puzzler: Where Did My Fences Go?  The source of inspiration for this week's puzzler came from an internal alias that we have here at Cadence where folks ask and answer questions about Encounter.  An applications engineer received a request from a customer and wanted to know: How can I select all of the registers beneath a given logical hierarchy?

 

The image above shows the scenario.  To clarify exactly what we're talking about, here's a sample Verilog netlist:

module testcase();
 DFFX1 \i_a/i0 ();
 BUFX1 i1();
 a i_a();
 b i_b();
endmodule

module a();
 a_sub i_a_sub();
 DFFX1 i2();
 BUFX1 i3();
endmodule

module a_sub();
 DFFX1 i0();
 BUFX1 i1();
endmodule

module b();
 DFFX1 i0();
 BUFX1 i1();
endmodule 

Given this netlist, we'd like to select all of the registers beneath the hierarchical instance i_a.  In this case, the script should therefore select i_a/i2 and i_a/i_a_sub/i0.

Tips:

  • The first thing that comes to mind is using dbGet, but there are a number of ways this could be done including Advanced Timing TCL Scripting Commands.
  • In this context "registers" are just another word for sequential elements.  They're marked as such in the .lib and can be keyed off in the db.
  • Consider using dbSelectObj -or- selectInst to select the instances.
  • Beware of the \i_a/i0 instance at the top level of the design -- it is not beneath the hierarchical instance i_a. I threw that in there to keep things interesting.

This is a little more open-ended than our last puzzler.  Leave a comment below with your solution -- I'll look forward to seeing what you come up with.  I'll post some solutions and further discussion this coming Friday.

Check back on Friday for the answer.  Or better yet subscribe to the Digital Implementation blogs to get new content delivered to your inbox or favorite feed reader. 

Bob Dwyer

Comments(10)

By Edwin on September 20, 2010
The escaped one makes it annoying :)
How about this:
deselectAll
foreach inst [dbGet -p2 [dbGetHInstByName i_a].allTreeInsts.cell.name DFF*] {
 dbSelectObj $inst
}

By Vishnu Chada on September 20, 2010
set x [get_cells -hier -filter "hierarchical_name =~ i_a/*  && is_sequential == true"
foreach_in_collection y $x {
 selectInst [get_object_name $y] }

By BobD on September 21, 2010
Awesome responses so far Edwin and Vishnu!  I especially appreciate that one used dbGet and the other used Timing TCL commands.
@Edwin your solution is almost exactly what I proposed.  Could you show an example of how you'd make the script not rely on the sequential cells being called DFF*?  There's a db marking you could key off that would make the solution more library-name-independent.  If you or anyone else would like to refine the solution to use that marking it would be useful I think.
@Vishnu very cool to see use of this style of commands.  I ran your script on my toy database and I see the top-level \i_a/i0 instance being selected because the escaped name resolves to i_a/i0 once the design has been imported.  I wonder if it would be possible to modify the search such that it doesn't catch this top-level instance -or- whether we'd need to do something like what Edwin shows where we query the instances beneath the hinst directly rather than relying on instance names.
If anyone else would like to chime in that would be great - I'll follow up with more discussion on Friday.
-Bob

By Vishnu Chada on September 21, 2010
How about adding negation to the filter list ?
set x [get_cells -hier -filter "hierarchical_name =~ i_a/* && hierarchical_name !~  \* is_sequential == true"]

By LaurentL on September 22, 2010
What about this one for selecting register inside a specific area:
set area [list 600 600 1200 1200]
foreach i [dbGet [dbQueryInstInBox \
     [dbMicronsToDBU [dbBoxLLX $area]] \
     [dbMicronsToDBU [dbBoxLLY $area]] \
     [dbMicronsToDBU [dbBoxURX $area]] \
     [dbMicronsToDBU [dbBoxURY $area]]].cell.isSequential 1 -p2] {
   dbSelectObj $i
}

By LaurentL on September 22, 2010
For sure this only applicable if your hierarchy is a fence! ;o)

By BobD on September 22, 2010
@LaurentL an area-based would certainly be useful in a lot of scenarios.  Thanks for mentioning that.
Along these lines I think the "dbQuery" command slated to be officially documented in 9.1.USR3 will be of interest in a lot of situations.  It makes an area-based search like the example you showed more concise.

By BobD on September 22, 2010
@Vishnu that syntax would work if the leading backslash weren't hidden.  It's kind of a wacky side-issue but the leading backslash is hidden by default so you can't key off a leading "\" until you "set dbgIsBackslashInNamesHidden 0".
Once you set that, you can indeed filter out the top level \i_a/i0 instance with this:
set x [get_cells -hier -filter "hierarchical_name =~ i_a/* && hierarchical_name !~ \\* && is_sequential == true"]
foreach_in_collection y $x {
  selectInst [get_object_name $y]
}
Well played!

By jgentry on September 22, 2010
Bob,
Here's an "old school" method for doing this.  When dealing with hierarchy, you need to delve into the "VInst" data structures (assumed to mean "Verilog" instance?).  This procedure will loop through all the first-level instances within the specified hierarchical instance and check if the instance itself is hierarchical, else if it is sequential.  If the former, it will simply recurse.  If the later, it will select it.
proc selectHierRegisters {hinstName} {
dbForEachCellVInst [dbHInstCell $hinstName] viPtr {
  if {[dbIsCellHier [dbVInstCell $viPtr]]} {
    selectHierRegisters $hinstName/[dbVInstName $viPtr]
  } elseif {[dbIsCellSequential [dbVInstCell $viPtr]]} {
    selectInst $hinstName/[dbVInstName $viPtr]
  }
}
}
One interesting question with the use of 'dbGet'; does it also require internal looping when applying the sequential filter?
JasonG

By BobD on September 23, 2010
Hey Jason!
Thanks for reminding me about the old school commands.  I've never used VInst commands myself but I tested your script and see it working exactly as you'd expect it to.
It might be more efficient to use "dbForEachHInstTreeInst" as it iterates through all of the instances beneath a given hierarchical level (and sees down through intermediate levels of hierarchy).  I'll show more how to use it in a post I'm writing now but thought to mention it for your thoughts.
Regarding dbGet and internal looping when applying the sequential filter I'm not sure I follow 100% but it sounds like you may be considering whether a list of all the instance are built up -and then- the filter is applied?  If so, yes, I believe that's how it works.  There's not a separate data structure built up that stores the instances that are sequential in the db so it needs to work that way I believe.  Let me know if I didn't quite get that nuance correctly for sure.
Thanks as always for your participation in these forums - it's much appreciated.

Leave a Comment


Name
E-mail (will not be published)
Comment
 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.