Initial commit of public repository open_pdks.
diff --git a/README b/README new file mode 100644 index 0000000..24fc238 --- /dev/null +++ b/README
@@ -0,0 +1,574 @@ +open_pdks : A system for installing silicon foundry PDKs for open-source EDA tools +(also maybe works for installing commercial tools) + +---------------------------------------------------------------------------------- + +Written by Tim Edwards 2019 / 2020 for efabless (efabless.com) +and Open Circuit Design (opencircuitdesign.com) + +---------------------------------------------------------------------------------- + +Introduction: + + 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 below for details). + + The general file structure created by open_pdks is as follows: + + <foundry_root>/ + <name_of_pdk_variant_1>/ + <name_of_pdk_variant_2>/ + ... + <name_of_pdk_variant_x>/ + libs.tech/ + <name_of_EDA_tool_1>/ + <name_of_EDA_tool_2>/ + ... + <name_of_EDA_tool_x>/ + <EDA_tool_setup_files> + libs.ref + <name_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_files> + + 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. + + Current EDA tools supported in this version of open_pdks: + Tool Directory name + -------------------------- + ngspice ngspice + magic magic + netgen netgen + klayout klayout + qflow qflow + openlane openlane + + Current IP library file formats supported in this version of open_pdks*: + 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. Those that + are known (SkyWater, MOSIS SCMOS) are included in the repository. 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. Each foundry + directory should contain a README file that details how to obtain + downloads from the foundry, and what files need to be downloaded. + 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, so needs to be done in + stages. The first stage installs setup files for all the EDA tools. + The second stage installs IP libraries (e.g., standard cells, padframe + I/O, analog circuits) and depends heavily on the use of the open EDA + tools themselves to fill in any missing file formats. Therefore the + tool setup files need to be installed first, and then the IP libraries. + If using a distributed install (see below), then the tool setup files + need to be installed and distributed (relocated to the final run-time + location) before the IP libraries are installed. + + There are two distinct install types supported by open_pdks: + + (1) 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. + + The local install sequence is: + + make Generate local staging area + make install-local Migrate to install directory + + (2) 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. + + The distributed install sequence is: + + make Generate local staging area + make install-dist Migrate to distribution directory + + Note that local installs may opt to make symbolic links back to the + foundry sources, where possible (see options for foundry_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. + +Prerequisites: + + The following tools/software stacks are needed to run open_pdks: + + python3 + + magic opencircuitdesign.com/magic or github.com/RTimothyEdwards + + assumed to be installed and discoverable in the standard + search path as defined by the shell (version 8.2+ 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 two main scripts are "preproc.py" and + "foundry_install.py", with a host of supporting scripts. + + 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. + + (Needed: A "make makefile" script that generates the "local" and "dist" + automatically, and potentially can also make all the different PDK + targets automatically, from a much shorter and simpler master Makefile.) + + 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>) [...] + #ifdef <variable> + #ifndef <variable> + #elseif <variable> + #else + #endif + + #define <variable> [...] + #undef <variable> + + #include <filename> + + <variable> may be + <keyword> + <keyword>=<value> + + <keyword> without '=' is effectively the same as <keyword>=1 + Lack of a keyword is equivalent to <keyword>=0, in a conditional. + + Boolean operators (in order of precedence): + ! NOT + && AND + || OR + + Comments: + 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 installation. It generates the local 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. + + foundry_install.py Usage: + + foundry_install.py [option [option_arguments]] ... + + 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: + -link_from <type> + Make symbolic links to vendor files from target + Types are: "none", "source", or a PDK name. + Default "none" (copy all files from source) + -source <path> + Path to source data top level directory + -target <path> + Path to target top level directory + -local <path> + For distributed installs, this is the local + path to target top level directory. + + -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. + + 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 "-". + + 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). However, for backwards + compatibility with earlier versions of open_pdks, the library name + in the path may also be wildcarded with "*" in the specific text + "/*/". + + Library name wildcarding in either form 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: + + -library <type> <name> [<target>] + + <type> may be one of the following: + + digital Digital standard cells + primitive Primitive devices + general All others + + Analog and I/O libraries fall under the category "general". + + <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). + + 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. + + Common foundry_install.py options when used with "-library": + + -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 + + 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. + + 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_*/*.lib + + would install all .lib files directly into + libs.ref/<libname>/liberty/*.lib while + + -liberty x/y/z/PVT_*/*.lib up 1 + + would 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. + + 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 + 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. + + File conversions handled by foundry_install.py: + + 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. + + open_pdks additional Makefile notes: + + 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: + + 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. + + 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. + + +Goals of the open_pdks project: + + The intended goal of open_pdks is to be able to support as many open source + EDA tools as practical, and to be able to generate all needed files for + those tools from any sufficiently complete set of vendor files. + + A number of file converions are not available but would be useful to have: + + SPICE to liberty: Create timing files by running simulations + on SPICE netlists using ngspice. + + liberty to verilog: Use the function statements in liberty + format to create verilog primitives. Maybe + use liberty timing information to generate + LEF specify sections. + + verilog to liberty: Reverse of the above. Use verilog logic + tables and specify sections to generate liberty + functions and timing tables. + + File formats that need to be supported: + + Schematic and symbol: There are few standards, so either everyone + needs to agree on a good format to use, or there + needs to be a lot of scripts to do conversions + between formats. Open EDA tools that could be + supported include: + + electric, xcircuit, kicad, sue2 + + Other open source EDA tools that need to be supported: + + OpenROAD + Coriolis2 + (add more here. . .) + + Commercial EDA tools can potentially be supported under this same system, + provided sufficient compatibility with the file system structure. + + Other scripts needed: + + Project setup script: It would be useful to define a "standard + project file structure" that is similar to the standard PDK file + structure defined in open_pdks. The preferred project setup + based on the efabless model is: + + <project_name> + .config/ + techdir (symbolic link to open_pdks PDK) + project.json (information file for tools) + <tool_name> (magic, qflow, ngspice, etc.) or + <format_name> (spice, gds, verilog, etc.) + + In general, <tool_name> directories are intended to be workspaces + for specific EDA tools (and may have their own nested hierarchies; + e.g., qflow/<digital_block>/source,synthesis,layout) while + <format_name> is a place to keep (final) files of a specific format, + with the intention that any project can easily be made into an + IP library and folded into the open_pdks scheme with little effort. + + The project.json file contains project information that can be used + by a script to build a setup for any EDA tool. One goal of the + project.json file is to define "datasheet" (documented elsewhere) + that can be used to drive characterization simulations and create + a datasheet for the project. Field "ip-name" of "datasheet" is + the canonical name of the project, which can be distinguished from + the project directory top-level name, such that the project can be + moved or copied without affecting the tool flows.