Qflow 1.1 Digital Synthesis Flow Tutorial Page

Table of Contents

Digital Flow Example
Verifying the Layout with Netgen
Simulating the Layout with iverilog
Simulating the Layout with IRSIM
Creating a New Digital Flow

Digital Flow Example

Download files for the example in the next section

map9v3.v is an example of a simple Verilog source file. It is a configuration logic block for a chip built by MultiGiG, and by itself it is absolutely useless, not to mention inscrutable, which is why it makes a good choice for an example. Note that I was going to use one of the verilog sources from the OSU standard cell library download, but it has multiple modules per file, and uses specific cell instances in the verilog. Such complications will be covered (eventually) in a separate tutorial.
File Revision Size Date
map9v3.v 1 2.0KB May 11, 2013
load.tcl 0 215B May 11, 2013
map9v3.tcl 0 306B May 11, 2013
map9v3.cel2 0 866B August 24, 2016
osu035_stdcells.gds2 0 339kB June 6, 2013
map9v3_gates_tb.v 0 717B April 28, 2015
osu035_stdcells.v 0 24kB April 28, 2015
setup.tcl 0 162B March 14, 2017
The Verilog subset understood by synthesis frontends such as yosys and Odin-II requires code that does not contain specific timing information (e.g., the "#" construct, although some limited forms of this are parsed and ignored). This reflects the difference between verilog used for simulation (testbench verilog) and verilog used for synthesis (synthesizable verilog). The verilog definition incorporates both styles, so one must be careful not to pass testbench-style verilog to a synthesis tool.

The following is an example of a digital flow from Verilog source to layout.


  1. Install qflow-1.1 and all prerequisites mentioned on the qflow reference page. For the example, the default OSU035 technology can be used, so you don't need to download any additional tech libraries.
  2. Create a working directory somewhere in your workspace; for the purposes of the example, assume that the directory path to the example is held as a variable name called ${project_dir}, which will be used throughout the example to refer to the project top-level directory.

  3. Create three subdirectories of ${project_dir} called source, synthesis, and layout.

  4. Copy the example file map9v3.v to directory ${project_dir}/source.

Note that if you don't have these directories defined, qflow will still work, but it will inconveniently dump everything into the current working directory. Still, flat workspaces appeal to some. . .

All instructions in this tutorial will assume a directory structure like that indicated above.


From the project directory, run:
qflow synthesize place route map9v3
(Note: the above command is for qflow version 1.1; for qflow version 1.0, use "qflow synthesize place buffer route map9v3".)

This command creates three files in the working directory:
qflow_vars.sh is a file containing information about the technology that is collected in one place and passed to each tool in the digital synthesis flow.

qflow_exec.sh is a file containing a sequence of commands to issue for the synthesis, placement, and routing. The simple qflow command without options other than the project name will cause all of the commands to be commented out.
project_vars.sh is a file that will be created once and never overwritten. It is where you would set specific options to fine-tune the synthesis flow to your needs. This tutorial will not cover anything beyond the defaults, so you can ignore this file for now.
Typically, one would run "qflow map9v3" without options, and then work through the steps of the flow by uncommenting each section, one at a time, and running the flow through that section, checking results, then moving on to the next section. Files needed for each section are saved in the working directories, so qflow can pick up where it left off in the previous step.


This example has been vetted so that it should run to completion and give a routed result, assuming that all the tools have been installed properly.

Verifying the Layout with Netgen

A synthesized circuit is supposed to be correct by design, but it is always a good idea to check the circuit both by LVS and by simulation.

To run this tutorial, you will need to have the tool netgen 1.5 installed on your system. Make sure that it is compiled with Tcl/Tk support, or else you will have to refer to the netgen documentation for doing a comparison without using the "lvs" command.

After running qflow through the detailed routing, use Magic to read in the circuit. There is a limitation of the layout tool in which it understands of the cell bounding boxes defined in the LEF file for standard cell placement, but this understanding does not transfer to layout files in the standard database format. The best way to ensure that the physical layout view matches the abstract LEF view is to do the following:

  1. Magic will need access to the technology file for the process used by the OSU035 standard cells, which is the scalable-CMOS rules from MOSIS with a few modifications. The modified technology file is included with the qflow distribution. More recent revisions of qflow (from 1.0.13) will install a startup script ".magicrc" in the layout directory. This startup script is responsible for loading the correct technology file from the qflow install directory. For versions of qflow prior to 1.0.13, you will need to copy the techfile SCN4M_SUBM.20.tech from the qflow install directory (/usr/local/share/qflow/tech/osu035/) to the local layout directory.
  2. Start Magic, for example, "magic -d OGL" in the layout directory (or just "magic" if you don't have OpenGL support).

  3. Load the abstract LEF views, using:
    lef read /usr/local/share/qflow/tech/osu035/osu035_stdcells.lef
    There will be a number of warnings related to statements that the LEF reader in magic doesn't handle; these can be ignored.
  4. Load the routed DEF file, using:
    def read map9v3.def
  5. If you wish to see the routing grid, use
    grid 1.6um 2.0um
    All of the steps from the "lef read" command up to and including the "grid" command are included in the script file "load.tcl" in the download sections at the top of the tutorial. If you downloaded this file, put it in the layout directory. Then, start Magic and type into the console:
    source load.tcl
    and proceed from the next step.

  6. Save the top-level design. In this case, you do not want to save the abstract views, although it can be helpful to keep the database versions of the abstract files in a separate directory and use the "addpath" command (see below) to switch between the abstract and physical views. To write the database for just the top-level cell, do:
    writeall force map9v3
  7. Now quit Magic to lose the abstract cell views (say "Yes" to the prompt, you really do want to exit!)

  8. If you have downloaded the OSU standard cell set, skip this step and go to the next one. Otherwise, download the file osu035_stdcells.gds2 from the download list at the top of the page (put it in the layout subdirectory). I recommend downloading the OSU standard cell set from the OSU website to get the most up-to-date version. However, the version posted here will suffice for the tutorial.

    Because there are a lot of standard cells, you may want to keep these layout views in a subdirectory of the layout directory, so from the layout directory, do:

    mkdir digital
    cp .magicrc digital
    cd digital
    Start magic without specifying a file to load:
    magic -d OGL
    Then load the GDS file, and save all of the standard cells:
    gds read osu035_stdcells.gds2
    writeall force
    Note that you may need to specify a complete path to osu035_stdcells.gds2 in the statement above for magic to be able to find the file. The set of commands above assumes that the GDS file has been placed in the digital subdirectory.

    Now return to the layout directory. The .magicrc script already has an "addpath digital" command in it, so it will be able to find all the standard cell layout views. Skip the next step.

  9. If you have downloaded the OSU standard cell set, you will want to execute the "addpath" command to access the Magic database views of the standard cells. For example, if the OSU distribution was put under ~/osu, then the command would be:
    addpath ~/osu/cadence/lib/source/magic
    This statement can be added to the ".magicrc" script file so that it will be applied every time magic is run from the layout directory.

  10. Load the layout view of the project top-level, which will now reference the physical layout views, not the abstract LEF views:
    magic -d OGL map9v3
  11. In this version of qflow (as of this writing, May 2013), qflow does not place power busses. To make sure that all the vdd and gnd rows on the standard cells are connected, extend the vdd metal1 lines out to the right and connect them vertically with metal1 (easiest) or metal2; do the same on the left with the gnd metal1 lines. Then, put the cursor box on the vdd metal1 bus and type
    label vdd n m1
    And similarly, putting the cursor box on the gnd metal1 bus, type
    label gnd n m1
    and then save again using
    writeall force map9v3
    The layout should now be a valid, operable digital circuit. It may not look exactly like the picture above, depending on the option choices (the one above had the number of rows of standard cells set to six).
  12. Generate a SPICE netlist from the design using the following sequence of commands:
    extract all
    ext2spice hierarchy on
    ext2spice scale off
    ext2spice renumber off
    ext2spice cthresh infinite
    ext2spice rthresh infinite
    This step will produce a file "map9v3.spice", a hierarchical description of the circuit down to the transistor level. It is the physical view, extracted from the connectivity of the wires. We want to compare it with the original netlist produced by the synthesis.

    Note that the use of "cthresh infinte" and "rthresh infinite" disables the generation of parasitic devices, which are not wanted for LVS comparison; otherwise you get capacitor ("c") devices in the layout netlist that are not matched in the schematic netlist.

  13. While you're at it, also create the .sim format file for the IRSIM simulation described below. Use the command
  14. Quit Magic---its job is done.

  15. The Qflow synthesis and resynthesis scripts generate a SPICE netlist directly from the BLIF format netlist, so this is what we want to compare against. It is found in the synthesis subdirectory, and has the name "map9v3.spc".

  16. Download the file "setup.tcl" from the downloads list above, and put it in the project top-level directory. This is the file that tells netgen important information about the technology and the standard cell set. In particular, it is needed to avoid counting the filler cells in the layout as something needing to match the schematic.

  17. From the project top-level directory, run netgen version 1.5:
  18. The SPICE netlist generated from the BLIF netlist uses the SPICE netlists for the standard cell subcircuits directly from the standard cell distribution. These will be compared against the extracted standard cell circuits from the layout. While the layout views that were read from the standard cell distribution are expected to match the netlists from the same distribution, this is a good check against errors in scaling, failure to tap wells and substrate, or formatting errors in general.

    Even if the standard cells match, we have to deal with the discrepancy between the way the SPICE netlists are formatted. The extracted view has no information about ports, as the circuit would need to connect to something at a higher level (such as a chip top level). The SPICE netlist generated from the BLIF netlist and standard cell netlist library, on the other hand, has all the port information for the top-level cell and generates a ".subckt" record for it. The way to handle this in netgen is to call the "lvs" command with a list for the second circuit containing the filename of the SPICE netlist, and the name of the subcircuit (see below).

    Since both the extracted circuit and standard cell netlist library are expected to refer to the same set of device models, both SPICE netlists should use the same names for low-level components (e.g., "nfet" and "pfet").

    The command to run in netgen is:

    lvs layout/map9v3.spice {synthesis/map9v3.spc map9v3}
  19. Again, if everything has gone according to plan, then the last two lines of output from netgen should be:
    Result: Circuits match uniquely.
    LVS Done.
    If this does not happen then a detailed report of the LVS errors will be dumped into a file called comp.out. It is worth taking a look at the comp.out file anyway, to see a summary of the comparison.
    For example, a failure to extract without parasitics will result in a netlist mismatch with the layout device showing many capacitor devices that are not present in the schematic view.

    Note that netgen can be called entirely from the command line, without the console, using the form:

    netgen -batch lvs layout/map9v3.spice "synthesis/map9v3.spc map9v3"

Simulating the Layout with iverilog

LVS netlist comparison is only a check for the internal consistency of the placement, and routing of a design (which is itself complicated and therefore prone to error, even in expensive commercial tools). But the LVS compares the layout against the schematic generated by the synthesis stage, and so it says nothing about the functional validity of the gate-level netlist. It is wise to do functional verification of the gate-level netlist with a verilog simulator. Because qflow generates a gate-level verilog netlist as a synthesis output, it is easy to run a verilog simulator on both the original verilog source code and the structural (gate-level) verilog netlist.

Note that prior to version 1.0.94 (April, 2015), the structural verilog netlist "project_name.rtlnopwr.v" could contain undefined references to "vdd" and "gnd", and to simulate correctly would need the additional verilog statements "wire gnd = 1'b0;" and "wire vdd = 1'b1;" added to the netlist by hand. From qflow version 1.0.94, these two statements are automatically written to the output file.

Download the verilog testbench "map9v3_gates_tb.v" from the download section above. Also, you will want the verilog of the standard cells ("osu035_stdcells.v"), which you can download from the section above, get from the OSU standard cell download, or from the installed techfile directory in qflow (by default, /usr/local/share/qflow/tech/osu035/osu035_stdcells.v) (and thanks to Leandro Marsó for converting the original IRSIM testbench into verilog!).

The structural verilog can be simulated in any verilog simulator; Icarus verilog ("iverilog") is a good choice, and the one I recommend. To run the testbench, you will just need to pass to iverilog the three verilog files needed: The standard cell definitions, the gate netlist, and the testbench:

iverilog osu035_stdcells.v map9v3.rtlnopwr.v map9v3_gates_tb.v
Icarus verilog is a compiler, so by default it generates an executable called "a.out", which must be run to obtain the testbench output:
This testbench generates an output file "map9v3_tb.vcd", if you want to look at waveforms using a waveform viewer (such as dinotrace). However, it also generates diagnostic output that is enough to show that the circuit is working as expected:
VCD info: dumpfile map9v3_tb.vcd opened for output.
At time 0, counter = 00 (0), sr = 00 (0), dp = 000 (0)
At time 530000, counter = 94 (148), sr = 00 (0), dp = 000 (0)
At time 550000, counter = 93 (147), sr = 01 (1), dp = 000 (0)
... At time 3490000, counter = 00 (0), sr = 33 (51), dp = 000 (0)
At time 3510000, counter = ff (255), sr = 67 (103), dp = 000 (0)
At time 3530000, counter = ff (255), sr = 67 (103), dp = 0ce (206)
The last line in the output above shows the first latched value in dp, which is (decimal) 206, and is the expected output. The waveform view of map9v3_tb.vcd using dinotrace is shown below.

Simulating the Layout with IRSIM

I mentioned above that running a verilog compiler/simulator like icarus will verify the function of the original source code and/or the gate-level netlist produced by the synthesis tool. A layout-vs.-schematic (LVS) tool will show a topological equivalence between the gate-level netlist and the layout. Generally speaking, the two of those together are sufficient to prove the validity of the layout.

In the end, however, you may want to ensure the correctness of the physical layout directly, by a simulation at the lowest (i.e., transistor) level, in particular to be done with an extracted netlist containing a (reasonably accurate) estimation of parasitic capacitances and resistances in the physical layout.

The best way is to extract a ".sim" netlist from Magic (see above), and simulate using IRSIM. IRSIM (see the IRSIM website on opencircuitdesign.com) has commands that make it very easy to construct a simulation that exactly matches a Verilog testbench. So you can simulate through IRSIM and check the results in the analyzer against the output of, say, iverilog and dinotrace. Another way is to extract the SPICE netlist from Magic and simulate using a SPICE simulator such as ng-spice (note that such a SPICE netlist will differ from the one generated above for the netgen LVS, because the netlist for LVS does not contain parasitic devices). However, SPICE simulation, while very accurate, does not scale very well with size; a moderately complicated verilog module can end up taking hours, days, or even weeks to simulate in SPICE. IRSIM, by contrast, works at the same base level of components like transistors, resistors, and capacitors, but with simplified models that strike a good balance between accuracy and simulation performance.

  1. For convenience, copy the IRSIM parameter file from the qflow technology directory to your layout directory:
    cd layout
    cp /usr/local/share/qflow/tech/osu035/osu035.prm .
  2. Download the IRSIM command file "map9v3.tcl" from the download list above, and also place that in the layout directory.
  3. Run IRSIM using:
    irsim osu035.prm map9v3.sim
  4. Once the IRSIM command window is up and the netlist has been loaded in, run the testbench simulation by typing into the console:
    source map9v3.tcl
  5. The script should automatically generate the logic analyzer window. Expand to the full view of the simulation by clicking on the target icon in the lower left-hand corner of the analyzer window. What you should is is that in the simulation, the circuit is given a start pulse, the counter and shift register start changing every clock cycle, and after about 100 clock cycles, the "done" signal goes high and the output "dp" is latched. The simulation uses an input value N of (decimal) 220 and should get as output a value for dp of (decimal) 410. If you see these values, then the circuit has been (minimally) functionally verified!


Last updated: March 15, 2017 at 10:32am