Tutorial:Place & Route Tutorial1

From NCSU EDA Wiki
Jump to: navigation, search

Place & Route Tutorial #1

In this tutorial you will create the layout for the same circuit as in Layout Tutorial #3, except that this time, you will use the automated place and route tool Encounter from Cadence to create the layout. You will be able to extract the wire capacitances and simulate the design with SPICE, as before, but you will also be able to check the timing with the static-timing-analysis tool PrimeTime from Synopsys. To save time, you will not run these tools individually, but rather in batch mode using the SSHAFT scripting framework.

To begin, log into a Sun/Solaris machine such as compute.ece.ncsu.edu (SSHAFT is not currently supported on LINUX machines) and source the SSHAFT setup script:

source /afs/eos.ncsu.edu/lockers/research/ece/wdavis/tools/sshaft/2005.00/dist/tech/TSMC_CMOS020/setup.csh

Copy-and-paste the command above into your UNIX shell or put the command in your .mycshrc file.

Next, create a directory for this tutorial and copy the following two files into that directory: addreg_netl.v techfile.sshaft

You may need to use the wget command to fetch these files directly, as your web browser may corrupt these files with invisible formatting characters.

  1. addreg_netl.v – This file is a Verilog netlist of a sample design. This netlist basically contains the same information that is in a schematic, but without the graphics: a name for the module, input and output ports, instances, and nets. In this case, the design is called “addreg,” and it basically consists of a 4-bit adder followed by a 4-bit register. Note the following things about the file:
    • The first line declares the module and its port-names.
    • The next 7 lines declare the widths and directions for the ports as well as the internal *:nets. The port names must match the names in the module declaration.
    • The format for the rest of the lines is the following:
      [cell-name] [instance-name]  ( .[port-name](  [net-name] ) … );
      The net-names here must match the names declared at the top of the file.
    • Names that contain brackets [] have been “escaped” with a backslash character. This character is not considered to be part of the name.
    • The file also contains two special output ports: T0 and T1. These ports basically illustrate what to do if you want the input of a cell to be “tied-low” (i.e. connected to ground) or “tied-high” (i.e. connected to VDD). Note that the net-names in this case are 1’b0 for ground and 1’b1 for VDD.
  2. techfile.sshaft – This file defines special variable for use by scripts written in the SSHAFT framework. It is basically here to provide arguments for the scripts, so that you don’t have to keep typing them in over and over. This file will be read by any SSHAFT script that you invoke from this directory. In this case, the file defines the following variables:
    • TopModule – The name of the top-level module defined in the Verilog netlist
    • NetlistFile – The path to the Verilog netlist file, relative to the current directory
    • ClockPeriod – The desired clock-period for the design, in nano-seconds
    • ClockPort – The name of the input port that connects to the clock
    • Library – The name of the library to store this design

Next, execute the following commands:

pr.py -log flow.log &
tail -f flow.log

The first command executes a SSHAFT script written in the language Python and sets the log file to be flow.log. (Due to a bug, the script will not currently work unless you specify a log file). The second command echoes the log messages written to the file as they happen.

You will see the following error-message printed to the screen twice. Please ignore it. (Sorry for the noise):

RuntimeWarning: Python C API version mismatch for module openaccess: 
This Python has API version 1012, module openaccess has version 1011.
import sshaft, sys, string, openaccess

The script may take 10 minutes or more to run. Once complete, you should see the following message:

Finished pr.py (elapsed time: …

Use CTRL-C to cancel the “tail” command and examine the flow.log file (see the one provided with this tutorial for an example of the expected output). flow.log You should see the following things happening in the file (in this order):

  1. Begin pr.py
    – This is a log message that indicates that the pr.py script has begun execution.
  2. Creating run/cds/.cdsinit …
    – These messages indicate that the script is creating a directory to run the Cadence Design Framework. It copies default versions of .cdsinit and cds.lib into this directory, so that when you run icfb later, it will load the Design-Kit and standard-cell library.
  3. Chdir run/cds
    – This indicates that the current working directory is being changed to the one that was just created.
  4. Writing command to exe.il: ncsuCreateLib( ?lib "mylib" …
    – The first thing that the script needs to do is create a library to store the results, so it writes a command file for icfb called exe.il to run a SSHAFT SKILL script to do just that. This log message gives the name of the file that it is writing and the command arguments.
  5. Executing: icfb -log CDS.log …
    – This message gives the command-line used to run the Cadence Design Framework and execute the command file.
  6. Begin ncsuCreateLib
    – Once the SKILL script begins execution, control of the log-file is handed off to icfb, which writes this message to indicate that control has been transferred. The message is indented by a TAB character to indicate that this process is a child of the pr.py script.
  7. Finished ncsuCreateLib (elapsed time: 0h 0m 1s actual)
    – Once the library is created, this message is printed to indicate that control is being relinquished to the parent process. The elapsed time is printed so that you can have a record of how long this step took, so that you can budget your time later on.
  8. Chdir ../..
    – Indicates that the current working directory is being changed back to where it started.
  9. Executing: ihdl -f -param verilogIn.param …
    – In order to run LVS later on, the pr.py script writes the verilogIn.param file and runs the program ihdl to import the Verilog netlist as a Cadence schematic.
  10. Creating run/enc/.encrc
    Chdir run/enc
    Writing command to exe.tcl: set errorflag [catch {PRInit …
    Executing: encounter -log encounter.log …
    Begin PRInit
    – These commands are similar to the ones we saw earlier, except that the scipt is creating a directory to run Cadence Encounter, changing to that directory, and executing a SSHAFT TCL script for Encounter called PRInit. This script reads in the Verilog file and initializes a floorplan for the design and saves it as run/enc/addreg_init.enc. This step also creates a DEF file called addreg_init.def. DEF stands for Design Exchange Format. It is a file format used for exchange of place-and-route data.
  11. Creating run/oa/cds.lib
    Chdir run/oa
    def2oa -def ../enc/addreg_init.def …
    genconstraints.py …
    – In order to properly predict delays in Cadence Encounter, a timing constraints file needs to be written that specifies every input port. These commands setup an OpenAccess run-directory, import the initialized DEF file into OpenAccess, and execute a short OpenAccess Python script that searches for the input ports and writes the constraints to the file run/enc/vlogin.tc.
  12. Begin PRPlace
    Begin PRCTS
    Begin PRRoute
    – These are SSHAFT TCL scripts for Encounter that place the design, synthesize the clock-tree, and route the design. This design has no clock-tree constraints specified, so no clock tree is created (These constraints will be discussed more in a future clock-tree synthesis tutorial). The design is saved in each step as addreg_placed.enc, addreg_cts.enc, and addreg_routed.enc in the run/enc directory. A DEF file for the final design is also written to the file addreg.def. Also, a SPEF file is created called addreg.spef. SPEF stands for Standard Parasitic Exchange Format. This file contains an RC-trees model for every wire in the design.
  13. spef2spice.pl ../enc/addreg.spef …
    – Because the SPEF file contains a wire model that is more accurate than the lumped-capacitances extracted in icfb, we want to generate a SPICE model of the design for simulation. This step generates that model and saves it in the file run/enc/addreg.sp.
  14. Writing command to exe.il: ncsuImportDEF( ?filename "../enc/addreg.def" …
    – This step indicates that the DEF file with the routes is being imported into the Cadence Design Framework.
  15. def2oa -def ../enc/addreg.def …
    gensinklist.py -log flow.log …
    – In order to properly verify the delay of the clock-tree with Synopsys PrimeTime, the name of the clock-sink nodes need to be written to a TCL script. These commands run an OpenAccess script to generate this list. (These steps will be discussed more in the clock-tree synthesis tutorial).
  16. Creating run/pt/.synopsys_pt.setup
    Chdir run/pt
    Writing command to exe.tcl: ptVerifyTiming
    Executing: pt_shell -f exe.tcl
    Begin ptVerifyTiming
    – These steps indicated that a run directory is being created for Synopsys PrimeTime, and a SSHAFT TCL script for PrimeTime is executed to verify the timing for the system.
  17. Finished pr.py (elapsed time: …
    – This line indicates that the script is done. Make note of the time so that you can estimate how long it will take in the future.

Just for fun, execute the following command:

 pr.py -log flow2.log

This executes the script as before, but saves the log to the file flow2.log. You should notice that the script executes much faster this time (a few seconds). How did this happen? Examine the flow2.log file, and you should see a number of messages of the form “Targets up to date, skipping substep…”. This is one of the features of the SSHAFT framework. The pr.py script specifies various dependencies and targets, much like a Makefile. If the targets are up-to-date with respect to their dependencies, then the step is not re-executed. We will make more use of this capability in future tutorials.

Unfortunately, the script is currently unable to run DRC and LVS checks in batch mode. You must run these steps manually. To do so, you must first add icfb to your path and start the Cadence design framework. To do this, you may simply use "add cadence2005" and "add cadence_cdk", as usual, but you are likely to get a "Word Too Long" error with this approach. Therefore, SSHAFT has added a trimmed-down version of the cadence setup script to your "run/cds" directory. You may start cadence now with the following commands:

 cd run/cds
 source add_cadence
 icfb &

Open the schematic view of the “addreg” cell in library “mylib”. You should see something like the schematic below:

PRtutorial1 addreg sch.PNG

Zoom in to the lower-right. You should see that the supply nets have been tied to vdd! and gnd! as shown below. PRtutorial1 supplynets vdd gnd sch.PNG

Next, close the schematic and open the layout view. You should see a layout such as the one below. PRtutorial1 layout view.PNG

Note that the LSW is missing! This is because the Cadence Design Framework has recognized this layout as coming from an imported DEF file, so it loads it in the Preview application, rather than the Layout Editor application that we’re familiar with. One indication of this is the fact that we have an OSW (Object Selection Window) rather than an LSW (Layer Selection Window), as shown below.

PRtutorial1 ObjectSelectionWindow.PNG

In order to get to the more familiar Layout Editor application, choose Tools->Layout from the menu at the top of the window. Another bug of the SSHAFT flow is that it doesn't create pins for the supply rails. Create those now as illustrated below:

PRtutorial1 SupplyPins.PNG

Now you should be able to run DRC, extraction, and LVS as you normally do. Do this now and convince yourself that it works. Isn’t that a lot easier than doing it by hand? Of course, the layout isn’t as compact, but that’s the price you pay for automation.

Another benefit of the automation is fast estimates of delay. Look in the file run/enc/timing_extracted.rpt. You should see the following lines:

    +----------------------------------------------------------------+
    |  Instance |    Arc     |   Cell   | Delay | Arrival | Required |
    |           |            |          |       |  Time   |   Time   |
    |-----------+------------+----------+-------+---------+----------|
    |           | B[0] v     |          |       |   0.000 |    0.278 |
    | U13       | A v -> Y ^ | NAND2X1  | 0.168 |   0.168 |    0.447 |
    | U5        | D ^ -> Y v | OAI22X1  | 0.128 |   0.297 |    0.575 |
    | U16       | B v -> Y ^ | AOI21X1  | 0.113 |   0.410 |    0.688 |
    | U15       | A ^ -> Y v | XNOR2X1  | 0.097 |   0.507 |    0.785 |
    | \Z_reg[3] | D v        | DFFPOSX1 | 0.000 |   0.507 |    0.785 |
    +----------------------------------------------------------------+

These lines show the critical-path delay as estimated by Cadence Encounter, taking into account the RC-models of each wire as represented in the run/enc/addreg.spef file. What this plot shows is that the longest delay comes from a falling edge at the input port at B[0], into the A-port of a NAND2X1 cell, followed by a rising-edge on the Y-output of that cell, etc. The “Arrival Time” column gives delay from the first event to that point in the path. Finally, the path arrives at the D-input of the Z_reg[3] flip-flop, with a delay of 507ps. The “Requred Time” column gives the delay that would be needed to meet the 1ns timing constraint that we specified in the techfile.sshaft file.

Synopsys also makes a timing analysis tool. Look in the run/pt/timing_extracted.rpt file to see the delays as predicted by Synopsys PrimeTime. You should see the following:

 Point                                    Incr       Path
 ---------------------------------------------------------------
 clock (input port clock) (rise edge)     0.00       0.00
 input external delay                     0.00       0.00 f
 B[0] (in)                                0.00       0.00 f
 U13/Y (NAND2X1)                          0.12 &     0.12 r
 U5/Y (OAI22X1)                           0.13 &     0.25 f
 U16/Y (AOI21X1)                          0.11 &     0.37 r
 U15/Y (XNOR2X1)                          0.10 &     0.47 r
 Z_reg[3]/D (DFFPOSX1)                    0.00 &     0.47 r
 data arrival time                                   0.47

This output shows that PrimeTime is predicting the same critical path as Encounter (which is good), but the delay is almost 40 ps less (470 ps total). This program is using exactly the same cell-delay models and wire-models as Encounter. Why are they different? Each tool is using an algorithm to predict delay that has some error associated with it. You must decide which you trust more. To do that, we will run SPICE simulations and compare the results.

Now, lets repeat this process for the design you did in Layout Tutorial #3. The first thing we need is to create a Verilog netlist to drive Cadence Encounter. To do that, close the icfb application and change to the directory where you completed Layout Tutorial #3. Re-start icfb and open the schematic view for the “tut3” cell. An image of that schematic is shown below, to refresh your memory. Note that wire-labels have been added to the internal nodes (n0, n1, … n4). You can add these labels with the Add->Wire Name menu option. They will help to make it easier to find these nets in the SPICE files generated later. (Be sure to Check-and-Save after you add the names).

PRTutorial1 EncounterSchematic.PNG

Next, choose Tools->Simulation->NC-Verilog from the menu at the top of the window. You should see the NC-Verilog window appear as shown below.

PRTutorial1 NC Verilog.PNG

In the NC-Verilog window, choose Commands->Initialize Design followed by Setup->Netlist… from the menu at the top of the window. You should see an options window like the one below appear. Make sure that the “Netlist Explicitly” Option is set. Without it, you won’t get the ports written properly to the Verilog file. Click “OK”.

PRTutorial1 NC Netlist.PNG

Next, choose Commands->Generate Netlist from the menu at the top of the window. Then choose Results->Netlist… from the menu. You will see a browser window appear.

PRTutorial1 View netlist runfiles.PNG

Select your library and then the “tut3” cell. Click “View”. You should see the verilog netlist appear as shown below.

PRTutorial1 VerilogNetlist.PNG

Choose File->Save As… and save the file as tut3.v. That’s what we need to start. Exit icfb.

We do need to edit the file to get rid of the lines not recognized by Cadence Encounter. Open tut3.v in your favorite text editor. Delete the line that begins with `timescale', as well as the lines 'specify' and 'endspecify' and all lines between them. Also, Synopsys PrimeTime will fail with the file as it is, because the “module” line has ports explicitly named by bit, while the “input” and “output” lines have busses indicated. To fix this problem, change the line to the following:

module tut3 ( B, A, CLK );

Remember that the names on the line above must match the names of the nets in port-declarations on the next few lines. Be sure to use your names and not mine, if your names differ.

Save this file. Now, create a new directory to re-run the pr.py script. Copy the tut3.v file to this directory, along with the techfile.sshaft file. Open techfile.sshaft in a text editor, and change the options as follows:

  • TopModule = tut3 (or whatever the name is of the module in your Verilog file)
  • NetlistFile = tut3.v (or the name of your Verilog file)
  • ClockPeriod = 1
  • ClockPort = CLK (or the name of the clock port in your Verilog file)

Execute the script pr.py again in this directory. Run DRC, extract, and run LVS on the result to verify that it worked properly. Turn in a plot of your layout and your LVS results using Wolfware.

Next, we will extract the parasitics and simulate in HSPICE. Unfortunately, we don’t have any of the internal nodes (n0, n1, … n4) labeled in the layout, so none of these nodes will appear in our HSPICE netlist. In order to allow these nodes to appear, we’ll need to find the nets and create labels. To do this, choose Tools->Virtuoso Preview from the menu and then Edit->Search… . You should see the following search form appear.

PRTutorial1 Searchfor.PNG

Select the “Net” button, followed by the “Net Name” selection in the “By:” box. In the text-box to the right of the “==” symbol, enter “n4”. Then click “Select”. You should see the net selected as shown below. Note: this won’t work unless you created the wire labels in your schematic as noted above.

PRTutorial1 Verilog Layout.PNG

Once you have found each net, return to the layout editor with Tools->Layout and create labels for the nodes with the Create->Label… menu option. Now you should be able to extract your layout with parasitics and run an HSPICE simulation, using the same stimulus that you used for Layout Tutorial #3. Make note of the delay.

Next, look in the files run/enc/timing_extracted.rpt. and run/pt/timing_extracted.rpt. How do these delays compare to what you simulated? Which do you trust more? Remember that there is a difference between your SPICE simulation and the Encounter and PrimeTime predictions, namely that they are using an RC-tree model for the wires, while we have used a lumped-model for each wire. In order to do a more accurate comparison, we will need to perform a SPICE simulation using an RC-tree model for each wire.

Next, in the run/enc directory, you should see two files, named tut3.sp and tut3.spef. As mentioned in step 12 of the pr.py script, the SPEF file contains an RC-tree model for every wire, and the SPICE file contains a model that was generated from that file. Simulating this model will give a more accurate idea of the delays in your circuit, especially if your design contains long wires.

Look in the tut3.sp file. It’s a hierarchical SPICE file, except that the names don’t match the names in your schematic. This is because the names have been mapped in the SPEF file. The names of the nodes in this file match the names in the SPEF file. In order to run a simulation, you will need to change the names in your vector files, clock-source, .IC, and .MEASURE statements. To figure out how the names are mapped, look in the tut3.spef file. Close to the top, you should see something like the following (your names may differ):

*NAME_MAP
*1 A[0] *2 A[1] *3 A[2] *4 B[0] *5 B[1] *6 CLK *7 n0 *8 n1 *9 n2 *10 n3 *11 n4 *12 I6 *13 I1 *14 I5 *15 I4 *16 I3 *17 I2 *18 I0

These lines tell you how the names are mapped. For instance, the port named A[0] has been mapped to the number 1. Note also that the instances have been mapped. Instance I3 (which, you will note, is an DFFPOSX1 gate in the Verilog netlist above), has been mapped to the number 16.

Next, look in the tut3.sp file.

    x6 vdd n16_D 0 n16_Q n16_CLK DFFPOSX1

This is the subcircuit instantiation for the DFFPOSX1 cell. Note that in the Verilog netlist, it’s connected to nets A[0], n0, and CLK. Why do those names not appear here? It’s because the notion of a “node” has been changed. What was once a node is now and RC tree, consisting of many nodes. The new node-names, as we can tell from this line, consist of the the letter “n”, followed by the number of the instance in the SPEF file (16 in this case), followed by and underscore “_”, and finally the port-name on the cell. You will need to put these new node-names in your .MEASURE and .IC statements. Refer to the Layout Tutorial #3 solution for an idea of how to do this.

What about the vector-files and clock-source? For a reference to the input port, simply use the letter “n” followed by the node number. For example, the CLK node at the input is now the node “n6”.

Now you should be able to make the necessary changes to the SPICE file and simulate to get a new measurement of the critical-path delay. Make a note of this delay.

Finally, compare this delay to the delays in the files run/enc/timing_extracted.rpt. and run/pt/timing_extracted.rpt. How do these delays compare to what you simulated? Which do you trust more?

Congratulations! You have finished Place & Route Tutorial #1. Take some time to celebrate.