Skip to main content

mflowgen: A Modular ASIC and FPGA Flow Generator

Project description


Documentation Status Build Status

Author: Christopher Torng (

mflowgen is a modular flow specification and build-system generator for ASIC and FPGA design-space exploration built around sandboxed and modular steps.

mflowgen allows you to programmatically define and parameterize a graph of steps (i.e., sandboxes that run anything you like) with well-defined inputs and outputs. Build system files (e.g., make, ninja) are then generated which shuttle files between steps before running them.

Key features and design philosophies:

  • Process and technology independence -- Process technology libraries and variables can be abstracted and separated from physical design scripts. Specifically, a single node called the ASIC design kit (ADK) captures this material in one place for better maintainability and access control.

  • Sandboxed and modular steps -- Traditional ASIC flows are composed of many steps executing with fixed path dependencies. The resulting flows have low reusability across designs and technology nodes and can be confusing and monolithic. In contrast, modularity encourages reuse of the same scripts across many projects, while sandboxing makes each step self-contained and also makes the role of each step easy to understand (i.e., take these inputs and generate those outputs).

  • Programmatically defined build-system generator: A Python-based scripting interface and a simple graph API allows flexible connection and disconnection of edges, insertion and removal of steps, and parameter space expansions. A simple graph can be specified for a quick synthesis and place-and-route spin, or a more complex graph can be built for a more aggressive chip tapeout (reusing many of the same steps from before).

  • A focus on hardware design-space exploration -- Parameter expansion can be applied to steps to quickly spin out parallel builds for design-space exploration at both smaller scales with a single parameter (e.g., sweeping clock targets) as well as at larger scales with multiple parameters (e.g., to characterize the area-energy tradeoff space of a new architectural widget with different knobs). Dependent files are shuttled to each sandbox as needed.

  • Complete freedom in defining what steps do -- Aside from exposing precisely what the inputs and outputs are, no other restrictions are placed on what steps do and a step can be as simple as hello world (one line). A step may conduct an analysis pass and report a gate count. A step can also apply a transform pass to a netlist before passing it to other tools. In addition, a step can even instantiate a subgraph to implement a hierarchical flow.

mflowgen ships with a limited set of ASIC flow scripts for both open-source and commercial tools including synthesis (e.g., Synopsys DC, yosys), place and route (e.g., Cadence Innovus Foundation Flow, RePlAce, graywolf, qrouter), and signoff (e.g., Synopsys PTPX, Mentor Calibre). In addition, we include an open-source 45nm ASIC design kit (ADK) assembled from FreePDK45 version 1.4 and the NanGate Open Cell Library.

More info can be found in the documentation.


mflowgen is offered under the terms of the Open Source Initiative BSD 3-Clause License. More information about this license can be found here:

Quick Start

This repo includes a small Verilog design that computes a greatest common divisor function. You can use this design to demo the ASIC flow with open-source tools. This section steps through how to clone the repo and push this design through synthesis, place, and route using the included open-source 45nm ASIC design kit (ADK), assuming the open-source tools are available.

Clone the repo:

% git clone
% cd mflowgen
% TOP=${PWD}

Install mflowgen with pip as an editable repo:

% pip install -e .

The example design is a greatest-common divisor circuit in RTL. We have created three demo graphs for this design in $TOP/designs/GcdUnit: (1) uses an open-source 45nm ASIC toolflow based on FreePDK45 and the NanGate Open Cell Library; (2) uses a commercial toolflow based on Synopsys, Cadence, and Mentor tools; and (3) expands this commercial toolflow for greater observability. Note: To try different graphs, open $TOP/designs/GcdUnit/.mflowgen.yml and specify one of the three choices. The remainder of this quickstart will assume you have modified this file to choose the open-source toolflow.

% cd $TOP
% mkdir build && cd build
% mflowgen run --design ../designs/GcdUnit

You can show information about the currently configured flow:

% make info      # <-- shows which design is being targeted
% make list      # <-- shows most things you can do
% make status    # <-- prints the build status of each step
% make graph     # <-- dumps a graphviz PDF of the configured flow

Now run synthesis and check the outputs of the sandbox to inspect the area report. Note: For the commercial flow, check make list for the build target name.

% make open-yosys-synthesis
% cat *-open-yosys-synthesis/outputs/synth.stats.txt

You can also run steps using the number from make list:

% make list      # <-- 3 : open-yosys-synthesis
% make 3

The yosys area report will look something like this:

=== GcdUnit ===

   Number of wires:                406
   Number of wire bits:           1011
   Number of public wires:         406
   Number of public wire bits:    1011
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                941
     AOI211_X1                       3
     AOI21_X1                       34
     AOI22_X1                       30
     BUF_X1                        626
     CLKBUF_X1                       5
     DFF_X1                         34
     INV_X1                         48
     NAND2_X1                       42
     NAND3_X1                        3
     NOR2_X1                        34
     NOR3_X1                         3
     NOR4_X1                         4
     OAI211_X1                       1
     OAI21_X1                       40
     OAI221_X1                       1
     OAI22_X1                        2
     OR2_X1                          1
     XNOR2_X1                       18
     XOR2_X1                        12

   Chip area for this module: 932.330000

Report runtimes to check how long each step has taken:

% make runtimes

Then run place-and-route (requires graywolf and qrouter):

% make open-graywolf-place
% make open-qrouter-route


The repository is organized at the top level with directories for the ADKs, designs, and steps (and utility scripts):

├── adks/      -- Each subdirectory is for an ADK
├── designs/   -- Each subdirectory is for a design (can be a cloned repo)
├── steps/     -- Collection of generic steps
│── mflowgen/  -- Source files for the mflowgen Python API
│── utils/     -- Helper scripts
└── configure  -- Config script to select a design

Designs include the graph specification, the source code, and any design-specific steps.

New designs are meant to be cloned into (or symlinked into) the designs subdirectory for easy access when configuring with --design.

Feature in Detail: Process and Technology Independence

The ASIC Design Kit (ADK) is a standard interface to all process technology libraries and variables used across all ASIC scripts in the tool flow. The ADK interface remains constant regardless of where the actual packages and IP libraries are downloaded and how they are organized. The ADK may include process technology files, physical IP libraries (e.g., IO cells, standard cells, memory compilers), as well as physical verification decks (e.g., Calibre DRC/LVS).

mflowgen ships with an open-source 45nm ADK assembled from FreePDK45 version 1.4 and the NanGate Open Cell Library. We place all kits and libraries into the directory adks/freepdk-45nm/pkgs in a relatively unorganized manner (just untar them). We then create different "views" into these packages for different purposes (e.g., front-end only, targeting open-source toolchains, targeting commercial toolchains) by creating subdirectories with different sets of symlinks to the vendor files.

Here is the "view-tiny" interface to the 45nm ADK containing only the files needed by the open-source ASIC flow tools:

adk.tcl                     -- ADK variables setup script               -- Qflow tech file
rtk-tech.lef                -- Routing tech kit LEF
rtk-tech.par                -- Graywolf tech file

stdcells.gds                -- Standard cell library GDS
stdcells.lef                -- Standard cell library LEF
stdcells.lib                -- Standard cell library typical Liberty
stdcells.v                  -- Standard cell library Verilog

Note: The adk.tcl encapsulates the ADK interface for variables. Any information specific to this ADK goes here (e.g., the list of filler cells, min/max routing metal layers).

The "view-standard" interface for the same 45nm ADK has more entries and targets commercial ASIC flow tools. This interface is useful for architectural design-space exploration of block-level designs. Note that we conserve repository space by downloading this view from online at build time:

adk.tcl                     -- ADK variables setup script

rtk-max.tluplus             -- Interconnect parasitics (max timing)
rtk-min.tluplus             -- Interconnect parasitics (min timing)
rtk-typical.captable        -- Interconnect parasitics (typical)
rtk-tech.lef                -- Routing tech kit LEF                 -- Routing tech kit Milkyway techfile             -- Routing tech kit TLUPlus map          -- Stream-out layer map for final GDS

stdcells.gds                -- Standard cell library GDS
stdcells.db                 -- Standard cell library typical DB
stdcells.lef                -- Standard cell library LEF
stdcells.lib                -- Standard cell library typical Liberty
stdcells.mwlib              -- Standard cell library Milkyway
stdcells.v                  -- Standard cell library Verilog
stdcells.cdl                -- Standard cell library LVS spice
stdcells-lpe.spi            -- Standard cell library extracted spice

calibre-drc-block.rule      -- Calibre DRC ruledeck
calibre-lvs.rule            -- Calibre LVS ruledeck

Here is a more complete and general-purpose ADK interface that might target a chip tapeout (files not included):

adk.tcl                     -- ADK-specific setup script
alib                        -- Synopsys DC performance cache
calibre-drc-antenna.rule    -- Calibre DRC antenna rule deck
calibre-drc-block.rule      -- Calibre DRC block-level rule deck
calibre-drc-chip.rule       -- Calibre DRC chip-level rule deck
calibre-drc-wirebond.rule   -- Calibre DRC wire bond rule deck
calibre-fill.rule           -- Calibre ODPO/metal fill utility
calibre.layerprops          -- Calibre DRV display properties
calibre-lvs-DFM             -- Calibre LVS design-for-manufacture rules
calibre-lvs.rule            -- Calibre LVS rule deck
calibre-rcx-DFM             -- Calibre RCX design-for-manufacture rules
calibre-rcx.rule            -- Calibre RCX rules
calibre-rcx-rules           -- Calibre RCX rules
display.drf                 -- Cadence Virtuoso display file
iocells-bc.db               -- IO cell library best-case DB
iocells-bc.lib              -- IO cell library best-case Liberty
iocells-bondpads.gds        -- IO bondpad GDS
iocells-bondpads.lef        -- IO bondpad LEF
iocells.db                  -- IO cell library typical DB
iocells.gds                 -- IO cell library GDS
iocells.lef                 -- IO cell library LEF
iocells.lib                 -- IO cell library Liberty
iocells.spi                 -- IO cell library SPICE
iocells.v                   -- IO cell library Verilog
iocells-wc.db               -- IO cell library worst-case DB
iocells-wc.lib              -- IO cell library worst-case Liberty
klayout.lyp                 -- KLayout GDS viewer display file
pdk                         -- Link to PDK directory
pdk.layermap                -- PDK layer mapping file
pdk-rcbest-qrcTechFile      -- Interconnect parasitics (rcbest)
pdk-rcworst-qrcTechFile     -- Interconnect parasitics (rcworst)
pdk-typical-qrcTechFile     -- Interconnect parasitics (typical)
rtk-antenna-rules.tcl       -- Routing rules to avoid antennas
rtk-cbest.captable          -- Interconnect parasitics (cbest)
rtk-cworst.captable         -- Interconnect parasitics (cworst)
rtk-max.tluplus             -- Interconnect parasitics (max timing)
rtk-min.tluplus             -- Interconnect parasitics (min timing)
rtk-rcbest.captable         -- Interconnect parasitics (rcbest)
rtk-rcworst.captable        -- Interconnect parasitics (rcworst)  -- GDS-to-Milkyway layer map          -- Stream-out layer map for final GDS -- Milkyway-to-GDS layer map
rtk-tech.lef                -- Routing tech kit LEF                 -- Routing tech kit Milkyway techfile             -- Routing tech kit TLUPlus map
rtk-typical.captable        -- Interconnect parasitics (typical)
stdcells-bc.db              -- Standard cell library best-case DB
stdcells-bc.lib             -- Standard cell library best-case Liberty
stdcells.cdl                -- Standard cell library CDL for LVS
stdcells.db                 -- Standard cell library typical DB
stdcells.gds                -- Standard cell library GDS
stdcells.lef                -- Standard cell library LEF
stdcells.lib                -- Standard cell library typical Liberty
stdcells.mwlib              -- Standard cell library Milkyway
stdcells.v                  -- Standard cell library Verilog
stdcells-wc.db              -- Standard cell library worst-case DB
stdcells-wc.lib             -- Standard cell library worst-case Liberty

The ADK interface for variables in the adk.tcl includes the following (with example values given), and examples of steps that use these variables are listed in the comment:

set ADK_PROCESS                     28           # steps/innovus-flowsetup
set ADK_MIN_ROUTING_LAYER_DC        M2           # steps/dc-synthesis
set ADK_MAX_ROUTING_LAYER_DC        M7           # steps/dc-synthesis
set ADK_MAX_ROUTING_LAYER_INNOVUS   7            # steps/innovus-flowsetup
set ADK_POWER_MESH_BOT_LAYER        8            # steps/innovus-plugins
set ADK_POWER_MESH_TOP_LAYER        9            # steps/innovus-plugins
set ADK_DRIVING_CELL                (cell-name)  # steps/constraints
set ADK_TYPICAL_ON_CHIP_LOAD        0.005        # steps/constraints
set ADK_FILLER_CELLS                (list)       # steps/innovus-flowsetup
set ADK_TIE_CELLS                   (list)       # steps/innovus-flowsetup
set ADK_WELL_TAP_CELL               (cell-name)  # steps/innovus-flowsetup
set ADK_END_CAP_CELL                (cell-name)  # steps/innovus-flowsetup
set ADK_ANTENNA_CELL                (cell-name)  # steps/innovus-flowsetup
set ADK_LVS_EXCLUDE_CELL_LIST       ""           # steps/innovus-plugins
set ADK_VIRTUOSO_EXCLUDE_CELL_LIST  ""           # steps/innovus-plugins

Feature in Detail: Sandboxed and Modular Steps

A key philosophy of mflowgen is to avoid rigidly structured ASIC flows that cannot be repurposed and to instead break the ASIC flow into modular steps that can be re-assembled into different flows with high reuse. Specifically, instead of having ASIC steps that directly feed into the next steps, we design each step in modular fashion with an "inputs" directory for inputs and an "outputs" directory for outputs. The build system runs each step in its sandbox, generating the outputs. Then, the build system handles the edges of the graph by moving files between sandboxes.

Sandboxing each step encourages reuse of the same scripts across many projects.

More details to come...

Feature in Detail: A focus on hardware design-space exploration

In contrast to software, hardware design includes both logical design-space exploration (i.e., architecture, RTL source code) and physical design-space exploration (e.g., floorplanning and power strategy). Physical design-space exploration can be uniquely challenging because ASIC tools work extensively with files, making an already challenging problem more difficult due to additional file management for many slightly different builds.

mflowgen supports both parameterization and parallel expansion across a parameter space.

For example, suppose we would like to sweep the clock_period parameter in the open-yosys-synthesis step in this graph:

The mflowgen Python API param_space() expands the node for each parameter value in the list:

  g = Graph()
  (... add steps and connect them together ... )
  g.param_space( 'open-yosys-synthesis', 'clock_period', [ 0.5, 1.0, 1.5 ] )

The expansion propagates to all downstream nodes, resulting in three slightly different builds:

The three builds can be run in parallel and the results compared. All file management is handled cleanly by the build system (which mflowgen generates from the graph).

Note that because parameters are passed as environment variables, parameter sweeping can be flexibly applied across the physical design flow in a very simple manner:

  1. Replace some code with a variable anywhere in your scripts
  2. Identify this variable as a parameter (i.e., in the step's configure.yml)
  3. Use the param_space() mflowgen API to perform a sweep of that variable

This can be useful for automating design-space exploration sweeps involving one parameter or multiple parameters.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for mflowgen, version 0.2.0
Filename, size File type Python version Upload date Hashes
Filename, size mflowgen-0.2.0-py3-none-any.whl (4.0 MB) File type Wheel Python version py3 Upload date Hashes View
Filename, size mflowgen-0.2.0.tar.gz (3.8 MB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page