( 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


 Sign up for the DeepChip newsletter.
Email
 Read what EDA tool users really think.


Feedback About Wiretaps ESNUGs SIGN UP! Downloads Trip Reports Advertise

"Relax. This is a discussion. Anything said here is just one engineer's opinion. Email in your dissenting letter and it'll be published, too."
This Web Site Is Modified Every 2-3 Days
Copyright 1991-2024 John Cooley.  All Rights Reserved.
| Contact John Cooley | Webmaster | Legal | Feedback Form |

   !!!     "It's not a BUG,
  /o o\  /  it's a FEATURE!"
 (  >  )
  \ - / 
  _] [_     (jcooley 1991)