( ESNUG 356 Item 6 ) --------------------------------------------- [8/03/00]
Subject: ( ESNUG 355 #14 ) Find The Driving Cell Of A Specific Net In DC
> It would be great if someone could help me on this. SOLVNET on the web
> hasn't been helpful... I am running Synopsys v1999.05. I would like to
> replace the driver of a a specific net in Synopsys' design, with a driver
> of my own choosing. It would seem I need to:
>
> 1. find the net ("find" command)
> 2. get the driving cell of the net
> 3. delete this cell ("delete_cell" command)
> 4. create a new cell and tie its ports to that of the old cell
> ("create_cell")
>
> It is easy to find the net, with the "find" command. However, I am having
> great difficulty getting the driving cell of the net, once I find the net.
> I can do an "all_connected" on this net, but that gives me a pin list, and
> it includes the loads of the net. I would like to get the driving cell of
> the net, so I can use it as an argument to "delete_cell".
>
> Can anyone tell me how to find the driving cell of a net, assuming I have
> found the net? FYI, we don't have the TCL license.
>
> - Matt Gavin
> Rockwell Collins
From: Bob Cook <rcook@avici.com>
John,
The following command will return the cell driving the net net_name.
cell_name = cell_of(all_fanin(-to find(net, net_name) -level 0))
By the way, if the new cell has the same pinout as the old cell,
you can use the change_link command to make the replacement.
(instead of delete_cell, create_cell, connect_net, ...)
change_link cell_name lib_name/lib_cell
Hope this helps Matt.
- Bob Cook
Avici Systems
---- ---- ---- ---- ---- ---- ----
From: Ken Scott <kenneth.scott@conexant.com>
Hi John,
Here is a script which gets Matt most of the way to finding the driving cell
of a net:
/* the -hier option causes all_connected to return the list */
/* of all pins connected to a net, no matter if they are in */
/* the current_design or in a lower level of hierarchy. It */
/* also prunes out any ports which may be connected to the net. */
pins = all_connected ( -hier find( net NETNAME ) );
/* you can narrown down this list to the single driver PIN by */
/* filtering on the direction of the pin attribute. */
out_pins = filter( pins "@pin_direction == out" );
/* now you need to do some perl magic, which I'm not so familiar with.
Take the output of the echo command: {cellname/pinname} and use
perl to:
1) remove the {}
2) truncate the "/pinname" from what remains
3) insert the remaining text into a command:
dc = find( cell "truncated_cell_name" ); */
echo out_pins > /tmp/foo
sh perl_script_here < /tmp/foo > /tmp/gor
include /tmp/gor
/* at this point, the variable 'dc' now represents the driving cell */
Hope this helps,
- Ken Scott
Conexant
---- ---- ---- ---- ---- ---- ----
From: Paul Zimmer <pzimmer@cisco.com>
John,
The short answer is, maybe you should look at the command "change_link".
If you can't use change_link (because the fct'ty doesn't match), you can
find the driving pin of the net by using:
filter(all_connected(the_net),"@pin_direction == out")
Hope this helps.
- Paul Zimmer
Cisco Systems
---- ---- ---- ---- ---- ---- ----
From: Brian Kane <briank@torrentnet.com>
John, I think
all_fanin -levels 0 -flat -to find(net, foobar) -only_cells
does what Matt wants.
- Brian Kane
Ericsson IP Infrastructure Silver Spring, MD
---- ---- ---- ---- ---- ---- ----
From: Oren Rubinstein <orubinstein@3dfx.com>
John, here's what Matt needs:
net_name = ...
drv_pin = filter(all_connected(net_name), "@pin_direction == out")
drv_cell = cell_of(drv_pin)
That should get him there.
- Oren Rubinstein
3DFX, Inc.
---- ---- ---- ---- ---- ---- ----
From: Jim Horning <jim.horning@lmco.com>
John,
I did this once upon a time, perhaps a variation will work for Matt.
current_design = widget
driver_cell = all_fanin(-to tclk -only_cells)
echo driver_cell > /tmp/dctemp.tmp
driver_cell1 = ""
driver_cell1 = execute( -s "sh ./script/strip_brace.pl /tmp/dctemp.tmp" )
remove_cell driver_cell
create_cell driver_cell1 mylib/inv6
connect_net "clk" (driver_cell1 + "/A")
connect_net "tclk" (driver_cell1 + "/Q")
set_dont_touch driver_cell1 true
Where strip_brace.pl was:
#!/usr/local/bin/perl
while (<>) {
s/[{}]//g;
print;
}
Good luck.
- Jim Horning
Lockheed-Martin
---- ---- ---- ---- ---- ---- ----
From: Tom Cruz <tomcruz@us.ibm.com>
Hi, John,
Below is a quick and dirty example script that will find the driving pin
on a net or list of nets (assuming there isn't more than one cell driving
the net.)
/* Enter the list of nets to change */
LIST_OF_NETS = { n1200 n1201 }
/* Get a list of instance on the net */
foreach(nt, LIST_OF_NETS) {
inst_list = all_connected(find(net,nt))
/* Loop through each instance on the net looking for the output pin */
foreach (item, inst_list) {
pin_dir = get_attribute(item, pin_direction)
if (pin_dir == "out" ) {
/* get the cell name */
drive_cell_tmp = cell_of (item)
foreach(drive_cell, drive_cell_tmp) { } /* knocks the
brackets off */
echo drive_cell "Is the driving cell for net " nt
/* Now do any disconnect, creates etc below */
} /* end if pin_dir */
} /* end foreach item */
} /* end foreach nt */
It should get you part the way there... (I added a few nets so I could
debug it.)
- Tom Cruz
IBM Microelectronics Division
---- ---- ---- ---- ---- ---- ----
From: Matt Gavin <mtgavin@collins.rockwell.com>
To: Tom Cruz <tomcruz@us.ibm.com>
Tom,
Thanks for your help. I am now able to get the driving cell, thanks. Now,
how do I get Synopsys to return the list of all pins on this cell? I need
this info so I can put the cell's fanin nets, on the new cell's fanin. (I
can do an "all_connected" on the cell's input pin, once I get it.)
Unfortunately, all_fanin and all_connected only work on pins and nets,
not cells.
This is harder than I expected!
- Matt Gavin
Rockwell Collins
---- ---- ---- ---- ---- ---- ----
From: Tom Cruz <tomcruz@us.ibm.com>
To: Matt Gavin <mtgavin@collins.rockwell.com>
Hi Matt,
Yes, it is a little more involved than one might think, but not impossible.
To answer your question, if you want to know the list of pins on a cell, do
this:
assuming the cell name is U13158
pin_list = find(pin,U13158/*)
Then pin_list will contain all the pins - for example:
{"U13158/Z", "U13158/A", "U13158/B"}
If you were trying to add it to the little script that I sent it would be
like this (after the section that says do any disconnects, creates etc */ )
pin_list = find(pin,(drive_cell + "/*" ))
echo pin_list
You still may have to use the synopsys execute command along with the unix
command cut to cut off the pin name and build a string for hooking up the
new cell.
Hope this helps
- Tom Cruz
IBM Microelectronics Division
---- ---- ---- ---- ---- ---- ----
From: Matt Gavin <mtgavin@collins.rockwell.com>
To: Tom Cruz <tomcruz@us.ibm.com>
Thanks Tom.
FYI, I figured out how to get pins from the cell, similar to what you
mentioned (use "find" after concatenating the cell with the star operator).
I found the solution on SOLVNET, ID Synthesis-167.html. You have to first
convert the cell to a string variable in order to concatenate the "/*" to
find the pins. They use the "foreach" command as a roundabout way of doing
this. Seems a bit ugly, but it works. At least it's not as ugly as
exiting to UNIX to have perl modify the cell name.
My script to replace Synopsys' buffer with my own, is now thus: All it
assumes is that the name of the net driven by the buffer, is c_clock.
/* convert clock buffer driving c_clock from cdqn0 to cdqn3 */
/* synopsys puts in the cdqn0 since it knows */
/* it is a clock */
/*-------------------------------*/
/* CLK_TOW cdqn3 (~166 loads) */
/*-------------------------------*/
/* find old cdqn */
drv_pin = filter (all_connected(c_clock ),"@pin_direction==out")
drv_cell = cell_of(drv_pin)
/* convert drv_cell to a string */
foreach(drv_cell_str,drv_cell) { }
/* connect driving cell's input to new buffers' input */
/* tie c_clock to new cell */
src_pin = filter (find (pin,drv_cell_str + "/*"),"@pin_direction==in")
create_cell clk_cdqn find(cell,Driver_lib + "/cdqn3")
connect_net all_connected(src_pin) clk_cdqn/A
connect_net c_clock clk_cdqn/Z
remove_cell drv_cell
set_dont_touch find(cell, clk_cdqn)
/* make sure it all worked */
all_connected clk_cdqn/A
all_connected clk_cdqn/Z
all_connected c_clock
No assumptions about the cell or pin names are made. This makes
the script very robust. (John - please post this to ESNUG for me - thanks
to everyone who helped me.)
- Matt Gavin
Rockwell Collins
|
|