Skip to content

Latest commit

 

History

History
 
 

common

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
	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
	make install-local		Install EDA tool setup
	make install-vendor-local	Install IP libraries

    (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
	make install-dist		Install EDA tool setup
	make install-vendor-dist	Install IP libraries

    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
	 character "*".  The specific text "/*/" is always replaced by the
	 name of the IP library (if "-library" is an option).  Otherwise,
	 "*" has the usual meaning of matching any characters in a name
	 (see python glob.glob() command for reference).

	 (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.)

	 In some cases, it may be required to process an option like "compile"
	 (see below) on files already in the target path without adding any
	 source files.  In that case, <path> may be any keyword that does not
	 point to a valid directory;  "none" is a recommended choice.

	 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.

	       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.

	       noconvert
		    Install files from source to target, but do not perform
		    any additional conversions (such as CDL to SPICE, or
		    GDS or LEF to magic).

	       ignore=<keyword>[,...]
		    Specifically for CDL and SPICE netlists, ignore any
		    parameter found matching <keyword>

	       rename=<new-name>
		    For single files copied from source to target, the
		    target file should be named <new-name> and not be
		    given the same name as the source file.  When used
		    with the "compile" or "compile-only" options, then
		    the compiled file gets the name <new-name> rather
		    than taking the name of the library.

	       exclude=<file>[,...]
		    Exclude file(s) from the comma-separated list when
		    copying from source to target.  The list items may
		    include glob-style wildcards.

	       excludefrom=<dir>
		    Exclude all files in the listing of directory <dir>
		    from the comma-separated list when copying from source
		    to target.

    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.