Using Open_PDKs Version 1.0
SkyWater 130nm process
Open_PDKs: A system for installing silicon foundry PDKs for open-source EDA tools
Silicon foundry PDKs are notoriously non-standard, and files obtained from the foundry may end up in any possibly configuration of files and folders. In addition, silicon foundries are notorious among open source EDA tool enthusiasts for supplying user setups for commercial EDA tools and all but ignoring open source EDA tools. Open_pdks aims to mitigate the problem by defining a standard layout of files and directories for known open standard formats (e.g., SPICE, verilog, liberty, LEF, etc.) and for various open source EDA tools (e.g., magic, netgen, OpenROAD, klayout) using a Makefile system and a number of conversion scripts to ensure that for any process, all files needed by all EDA tools can be found in predictable locations.The scripts aim to be as general-purpose as possible to allow easy adaptation to new tools, formats, and foundries. Where foundry data is intractably unusable, custom install files can be added to overwrite or annotate vendor data as needed.
Each foundry process is a subdirectory of the open_pdks top level and has its own Makefile. The typical install process is to cd to the foundry top level and run "make" (see the Install page for details).
The general file structure created by open_pdks is as follows:
foundry_root/Note that this format is very general and does not constrain the EDA tools supported or file formats supported, so long as there are scripts in the system to provide that support. It is intended that open_pdks can be extended as needed to support new tools or new file formats.name_of_pdk_variant_1/
name_of_pdk_variant_2/
...
name_of_pdk_variant_x/libs.tech/name_of_EDA_tool_1/libs.ref
name_of_EDA_tool_2/
...
name_of_EDA_tool_x/
EDA_tool_setup_filesname_of_IP_library_1/
name_of_IP_library_2/
...
name_of_IP_library_x/name_of_file_format_1/
name_of_file_format_2/
...
name_of_file_format_x/vendor_filesCurrent EDA tools supported in this version of open_pdks:
Current IP library file formats supported in this version of open_pdks*:
Tool Directory name ngspice ngspice magic magic netgen netgen klayout klayout qflow qflow openlane openlane
Format Directory name CDL cdl SPICE spice magic mag, maglef LEF lef, techlef GDS gds verilog verilog liberty lib PDF** doc (* "Supported" meaning expected/handled by conversion scripts; as noted, the install is very general purpose and any name can be used as a target for any vendor or custom files.)(** or HTML or any valid document format, plus supporting files.)How to use open_pdks:
There are a seriously limited number of open foundry PDKs. Initial support is provided for the Google/SkyWater sky130 process. Other known open foundry PDKS such as MOSIS SCMOS* or LibreSilicon will be added when we get around to it, or when such organizations helpfully provide me with setup files in the form of a github pull request.In other cases (X-Fab XH035, XH018) it is possible to get an extension to open_pdks from a known trusted source through NDA verification with the foundry. In all other cases, foundries should be berated until they agree to support the open_pdks format. Open_pdks does not attempt to keep any foundry data to the extent possible. Instead, it adapts to the file structure available from whatever system each foundry uses for downloads (in the case of the Google/SkyWater sky130 process, this is a github repository, as found in the link above). Each foundry directory in open_pdks should contain a README file that details how to obtain downloads from the foundry, and what files need to be downloaded. This information will be duplicated on the Install Page for open_pdks. Since the download methods vary wildly, it is up to the user to obtain the foundry data as instructed. The Makefile in the open_pdks foundry directory then needs to be edited to set the correct path to the foundry source data.
The installation is a bootstrapping process, and is done in two stages. The first stage creates all tool setup files and IP library files in a staging area, one directory per PDK variant. The tool setup files are generated first, and then the IP libraries. The second stage migrates all the files to the installation target.
There are two distinct install types supported by open_pdks:
Both install sequences are as follows:
- Local install:
Use a local install when the EDA tools will be run on a single host, and all the PDK data are on the same host.
- Distributed install:
Use the distributed install when the PDK will be run from multiple hosts, but will be installed into a different location such as a git repo which is then distributed to all hosts, and may not itself reside in the same root directory tree.
Note that local installs may opt to make symbolic links back to the foundry sources, where possible (see options for staging_install.py, below). Distributed installs and local installs may also make symbolic links from any PDK variant back to a "master" PDK variant, where possible (that is, where the files are the same). For example, a standard cell library will probably be compatible with all metal back-end stacks, and so only one copy of all the library files is needed in one of the PDK variants. For the other PDK variants, the same files are all symbolic links to the files in the first PDK variant. But an I/O library would have different layouts for different metal back-end stacks, so layout-dependent files like GDS would be different for each PDK, but layout-independent files like verilog might be symbolic links to files in the first PDK.
configure options Declare type of install and the install location make Generate and populate local staging area make install Migrate to install directory Prerequisites:
The following tools/software stacks are needed to run open_pdks:Tools and applications are assumed to be installed and discoverable in the standard search path as defined by the shell.
- python3
- Install with a package manager if not already installed.
- magic
- magic or github:magic (version 8.3.25+ required).
How to make or update an open PDK:
The backbone of the open_pdks system is a set of scripts found in the common/ subdirectory. The three main scripts are "preproc.py", "foundry_install.py", and "staging_install.py", with a host of supporting scripts.Open_PDKs additional Makefile notes:Creating a new PDK starts with generating a Makefile, which can be done by copying a Makefile from an existing project. The first thing to do is to define the number of PDK variants (usually based on back-end metal stacks available, but can also include front-end options, especially if they are mutually exclusive rather than simply additional masks). Then create the make and make-install targets for local and distributed install, including install (plain), install-vendor, and install-custom. Define the default source and target paths.
Create the basic scripts for tools. Since foundries do not support open EDA tools, it is inevitable that these files need to be created by hand unless there is an option to import other formats. Because Magic is used heavily by open_pdks to create missing file formats from other existing file formats, a Magic techfile is critical. Each of the basic scripts will contain #ifdef ... #endif and similar conditionals to allow the script to be parsed for each target PDK variant. Each of these scripts is passed through common/preproc.py to handle the conditionals. Of course, it is possible to make a separate file for each PDK variant as long as the Makefile handles them properly, but use of the preproc.py script allows all the PDK variants to be handled in the same way, simplifying the Makefile.
preproc.py Usage:preproc.py input_file [output_file] [-D variable ...]
Where variable may be a keyword or a key=value pair
Syntax: Basically like cpp. However, this preprocessor handles only a limited set of keywords, so it does not otherwise mangle the file in the belief that it must be C code. Handling of boolean relations is important, so these are thoroughly defined (see below)#if defined(variable) [...]variable may be
#ifdef variable
#ifndef variable
#elseif variable
#else
#endif
#define variable [...]
#undef variable
#include filename
keywordBoolean operators (in order of precedence):
keyword=value
keyword without '=' is effectively the same as keyword=1.
Lack of a keyword is equivalent to keyword=0, in a conditional.Comments:
- !
- NOT
- &&
- AND
- ||
- OR
Most comments (C-like or Tcl-like) are output as-is. A line beginning with "###" is treated as a preprocessor comment and is not copied to the output.Examples;#if defined(X) || defined(Y)
#else
#if defined(Z)
#endif
The script common/foundry_install.py handles all the IP library processing and installs into a local "staging area" directory. It generates the staging directory structure and populates the directories with foundry vendor data, and filters or otherwise uses open EDA tools to generate missing standard file formats or create file formats needed by the open EDA tools. The resulting file structure is self-contained and can be used from the staging area.
foundry_install.py Usage:foundry_install.py [option [option_arguments]] ...File conversions handled by foundry_install.py:
All options begin with "-" and may be followed by one or more arguments (that do not begin with "-"). The foundry_install.py script may be called multiple times, although it is best to group together all files for the installation of an IP library, since the options given will be used to determine what files are missing and need to be generated.
Global options:All other options represent installation into specific directories. The primary rule is that if foundry_install.py is passed an option "-library" (see syntax below), then all other non-global options represent subdirectories of the IP library, given the same name as the option word following the "-". If the foundry_install.py command line does not have an option "-library", then all non-global options represent per-EDA tool subdirectories, where the name of the subdirectory is the same as the option word following the "-".
- -source path
- Path to source data top level directory
- -target path
- Path to the staging top level directory. This is typically defined to be the open_pdks subdirectory for the technology being compiled.
- -library type name
- The install target is an IP library with name name.
- -ef_format
- Use the original efabless format for file installs. This has several differences from then no-efabless install. The most important is that the order of directories for IP libraries is file_format/library_name instead of library_name/file_format. As the efabless platform migrates to the open_pdks developing standard, this use should eventually be deprecated. In open_pdks, the option is set from the EF_FORMAT variable setting in the Makefile.
Each tool install option has the syntax:-tool_name path [option_arguments]Each IP library install option has the syntax:-file_format_name path [option_arguments]The path is a directory path that is relative to the path prefix given by the -source option. The path may be wildcarded with the escape string "%l", which is replaced by the name of the library, and for simplicity with versioning, "%v" will be interpreted to match any versioning string in the form "major[.minor[.rev]]". Note that only the numerical part of a versioning string is represented, so, for example, to match "/V1.1.0/" the path should use "/V%v/". In the unlikely event of a percent character in the path, use the escape string "%%".
"*" has the usual meaning of matching any characters in a name (see python glob.glob() command for reference).
Library name wildcarding is only valid if "-library" is given as an an option.
(Note that the INSTALL variable in the Makefile starts with "set -f" to suppress the OS from doing wildcard substitution; otherwise the wildcards in the install options will get expanded by the OS before being passed to the install script.)
Library option:Any number of libraries may be supported, and one "-library" option may be provided for each supported library. The use of multiple libraries for a single run of foundry_install.py only works if the formats (gds, cdl, lef, etc.) happen to all work with the same wildcards. But it is generally most common to declare only one library name per call to foundry_install.py.-library type name [target]type may be one of the following:Analog and I/O libraries fall under the category "general".
- digital
- Digital standard cells
- primitive
- Primitive devices
- general
- All others
name is the vendor name of the library.
[target] is the (optional) local name of the library. If omitted, then the vendor name is used for the target (there is no particular reason to specify a different local name for a library).
Common foundry_install.py options when used with "-library":Any name can be used after the "-" and the installation of files will be made into a directory of that name, which will be created if it does not exist. The names used above are preferred, for the sake of compatibility between EDA tools.
- -techlef path [option_arguments]
- Technology LEF file
- -doc path [option_arguments]
- library documentation
- -lef path [option_arguments]
- LEF file
- -spice path [option_arguments]
- SPICE netlists
- -cdl path [option_arguments]
- CDL netlists
- -lib path [option_arguments]
- Liberty timing files
- -gds path [option_arguments]
- GDS layout data
- -verilog path [option_arguments]
- Verilog models
Of special note is "techlef", as technology LEF files are often associated with a PDK and not an IP library. In this system, the technology LEF file should be associated with each standard cell library for which it is intended.
[option_arguments] may be one of the following:
- up=number
- Any tool option can use this argument to indicate that the source hierarchy should be copied entirely, starting from number levels above the files indicated by path. For example, if liberty files are kept in multiple directories according to voltage level, then
-liberty x/y/z/PVT_*/*.libwould install all .lib files directly into libs.ref/libname/liberty/*.lib while-liberty x/y/z/PVT_*/*.lib up 1would install all .lib files into libs.ref/liberty/libname/PVT_*/*.lib.- nospec
- Remove timing specification before installing (used with verilog files only; could be extended to liberty files).
- compile
- Create a single library from all components. Used when a foundry library has inconveniently split an IP library (LEF, CDL, verilog, etc.) into individual files.
- compile-only
- Same as argument "compile", except that the individual files are not copied to the target; only the compiled library is created.
- stub
- Remove contents of subcircuits from CDL and SPICE netlist, or verilog files. This is useful to LVS and other tools to know the order of pins in a circuit (for CDL or SPICE), or simply to ignore the contents of the file (any format) so that the circuit in question is treated as a "black box".
- priv
- Mark the contents being installed as privleged, and put them in a separate root directory libs.priv where they can be given additional read/write restrictions.
- rename=file_name
- Rename the file being copied to the name of the argument. This can be used to copy one file into multiple destination libraries and give each copy a name related to the destination library.
- filter=script_file_path
- Process all files through the script script_file_path, which is given as a relative path to the directory containing the Makefile. The filter script traditionally is put in local subdirectory custom/scripts/. The filter script should be written to take a single argument, which is the path to a file, and process that file, and overwrite the file with the result. Commonly used filters are found in the common/ directory. See common/fixspice.py for an example.
- sort=script_file_path
- After collecting a list of all files for generating a compiled library, write a file called filelist.txt and then run the script at script_file_path. The script should read the file filelist.txt, modify it to put the files in the order that they should appear in the compiled library, and rewrite the same file filelist.txt. If not specified, then a natural sort order script is used.
- exclude=file_list
- Where file_list is a comma-separated list of one or more files (including extension), and may be wild-carded. If any entry contains a file path, then the file path component is used to find the specified files (which may also be wild-carded). This is a list of files in the source directory which should not be copied to or used in the target. The files then are excluded from any compiled library. This is intended to ignore unwanted files that are part of the vendor library. Note that if an unwanted vendor file needs to be replaced with a custom version, no-copy should be used instead of exclude (see below).
- no-copy=file_list
- Where file_list is a comma-separated list of one or more files (including extension), and may be wild-carded. If any entry contains a file path, then the file path component is used to find the specified files (which may also be wild-carded). This list indicates files that should not be copied from the source directory to the target. It is intended to be used for replacing a vendor file with a custom file. This requires a two-part entry in the Makefile; one to copy the custom files from source to target, then one to copy the vendor files from source to target while specifying the custom files with no-copy.
- include=file_list
- Where file_list is a comma-separated list of one or more files (including extension), and may be wild-carded. If any entry contains a file path, then the file path component is used to find the specified files (which may also be wild-carded). This list indicates files that should have been placed in the target directory by a prior run of the script, and should be added to the list of files copied from source when doing additional processing such as compiling a library or generating additional views. If using compile-only, then these files will also be removed from the target directory after compiling into a library.
- noclobber
- Mainly diagnostic. When specified, any temporary files used during installation will be retained instead of deleted after use. This includes, for example, scripts passed to magic for running extraction or file format generation. It is useful when debugging problems with the install.
- anno (or annotate)
- Currently only supported for LEF files. This argument indicates that the vendor LEF files should be used only for annotating GDS input with port location information, but the LEF files themselves should not be installed.
The following file format conversions can be done automatically by foundry_install.py:
- CDL to SPICE:
- A CDL netlist or library can be converted to a general-purpose SPICE netlist that can be read by any tool that can read Berkeley SPICE 3f5 syntax.
- GDS to LEF:
- An abstract view can be generated from a full layout view using Magic.
- GDS to SPICE:
- In the absence of any netlist, Magic will extract a SPICE netlist from a full layout.
- SPICE (any) to SPICE (ngspice):
- The fixspice.py script will attempt to convert any SPICE model file, cell library, or netlist to a form that is compatible with ngspice version 30.
The script common/staging_install.py handles the installation of the files in the staging area to the destination. It generates the local directory structure and populates the directories, making subtitutions as needed where the target directory appears in file data. If the -link_from option is selected to be source, then files that are unchanged from the original vendor data are replaced with symbolic links to the original vendor files.
staging_install.py Usage:staging_install.py [option [option_arguments]] ...
All options begin with "-" and may be followed by one or more arguments (that do not begin with "-"). The staging_install.py script is called once after all calls to foundry_install.py have been made, and the staging area is fully populated.
Global options:
- -link_from type
- Make symbolic links to vendor files from target Types are: "none", "source", or a PDK variant name. Default "none" (copy all files from source). Note that using "source" implies that the original vendor sources must remain and cannot be moved, or the symbolic links will become broken. Also note that using "source" with a distributed install implies that the vendor sources will be found on all hosts where the PDK is copied, in the same location. Use of a PDK variant name is only meaningful for technologies with multiple variants, but can save considerable space when there are files that are the same in multiple variants, by having only one copy of the file, and multiple symbolic links to it. In all cases, the determination of making a symbolic link is automatic, based on a comparison of the files. Only if the file data are the same will one file be replaced by a symbolic link to the other.
- -source path
- Path to staging area top level directory (the same path as passed to foundry_install.py as -target).
- -writeto path
- Path to target top level directory. For distributed installs, this can be a temporary location such as a git repository that will get copied to multiple hosts. For local installs, this is the final install location, and the -finalpath option (see below) is not used. (Option previously was -target, which is also accepted as an alternative to -writeto.)
- -finalpath path
- For distributed installs, this is the local (run-time) path to target top level directory; that is, the directory where the files will ultimately reside. (Option previously was -local, which is also accepted as an alternative to -finalpath. The option name was changed due to the ambiguity of the term "local".)
The "make install-local" ("make install-dist") step is generally broken into individual make sections, one for each tool (e.g., magic, netgen, klayout). There is an additional section called "general" which installs a ".config" directory at the PDK top level, containing a file "nodeinfo.json" which has general information about the PDK that may be used by any tool that understands the key:value pairs used in the JSON file. Keys used are as follows:Note that the JSON file is, like other EDA tool setup files, usually a master file that is parsed by preproc.py; therefore when specifying "options", use #undef before specifying each option name so that the option name itself is ignored by the pre-processor.
- foundry :
- Short name of the foundry, equal to the foundry directory root, above the PDK variants.
- foundry-name :
- Long name of the foundry.
- node :
- The name of the PDK variant
- feature-size :
- The foundry process feature size (e.g., 130nm)
- status :
- "active" or "inactive". May be used by tools to present or hide specific PDK variants.
- description :
- Long text description of the process variant (e.g., 6-metal stack + MiM caps)
- options :
- List of options, corresponding to the definitions used in the Makefile and passed to preproc.py.
- stdcells :
- List of standard cell libraries available for this PDK variant.
- iocells :
- List of I/O pad cell libraries available for this PDK variant.
The Makefile script takes the source files and generates files for local PDK names "SKY130A", "SKY130B", etc. (Note there is currently only one PDK variant "A".)
The definition of each PDK is made in the Makefile using defines; e.g., -DMETAL5, etc.
The make script makes use of the python script "preproc.py" (in the ../common directory) to parse each source file for "#ifdef ..."-type macros. See the description of the preproc.py script above.
Files generated:The installation directory below LOCAL_PATH is the name of the PDK; e.g.,
- .tech
- techfile for magic (full DRC, extract, GDS)
- -GDS.tech
- techfile for magic, vendor mask layers
- .tcl
- PDK script for magic
- -BindKeys
- key binding script for magic partly matching Cadence defaults
- .magicrc
- magic startup script (copy to local directory as .magicrc)
- _setup.tcl
- netgen setup script for LVS
- .sh
- qflow master setup script
- .par
- graywolf setup file
The installation directory hierarchy below the PDK name looks like the following:
- sky130A/
- 5-metal stack with MiM cap and redistribution layer
Each subdirectory of libs.ref is further divided into sections based on the IP type. The section names are largely foundry-dependent. For SkyWater Sky130, these sections include one or more of:
- libs.tech/
- technology and setup files
- ngspice/
- device models and libraries for use with ngspice.
- magic/
- magic techfiles, startup file, PDK script, and key binding script.
- netgen/
- netgen setup file
- qflow/
- qflow scripts and graywolf setup files.
- klayout/
- setup files for klayout
- openlane/
- setup files for openlane
- libs.ref/
- foundry data
- cdl/
- CDL netlists
- doc/
- Foundry documentation
- gds/
- GDS files
- lef/
- LEF macro files
- lib/
- Timing files
- mag/
- Magic files derived from GDS
- maglef/
- Magic files derived from LEF macros
- spice/
- SPICE netlists (ngspice compatible)
- techlef/
- LEF technology files
- verilog/
- verilog modules
The target installation destinations assume the directory structure above. Changing this requires editing the source files.
- sky130_fd_sc_hd/
- 1.8V digital logic (high density)
- sky130_fd_sc_hdll/
- 1.8V digital logic (high density low leakage)
- sky130_fd_sc_lp/
- 1.8V digital logic (low power)
- sky130_fd_sc_hvl/
- 3.3V digital logic
- sky130_fd_sc_hs/
- 1.8V digital logic (high speed)
- sky130_fd_sc_ms/
- 1.8V digital logic (medium speed)
- sky130_fd_sc_ls/
- 1.8V digital logic (low speed)
- sky130_fd_io/
- Standard I/O
- sky130_fd_pr/
- Primitive devices with fixed layout
email: | ![]() |
Last updated: November 15, 2021 at 9:50am