Initial commit of public repository open_pdks.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..38d0f2e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+*.swp
+*.vvp
+*.vcd
+*.raw
+__pycache__
+**/.DS_Store
+**/.Trashes/
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..02000c3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,81 @@
+#---------------------------------------------------
+# Makefile for efabless project open_pdks
+# Tim Edwards, 11/21/2016
+# Updated 10/19/2018 for use independently of the
+# efabless /ef/ tree filesystem setup.
+# Updated 5/5/2020 for use with the 2-stage install
+#---------------------------------------------------
+#
+# Typical usage:
+#
+# make
+# generates the tech files from source masters.
+#
+# make install-local
+#
+# installs the tech files locally.
+#
+# make install-dist
+#
+# installs the tech files in the git project
+# that is used for distribution of software
+# across the system.
+#
+# make clean
+#
+# clean up all files generated by 'make'
+#
+#---------------------------------------------------
+#
+# The following definitions are tied to the contents
+# of this repository and should not be changed.
+
+TECHS = sky130
+
+#---------------------------------------------------
+
+all: ${TECHS}
+ for tech in ${TECHS}; do \
+ ${MAKE} tech_$$tech; done
+
+#---------------------------------------------------
+
+tech_sky130:
+ (cd sky130 && ${MAKE} all)
+
+#---------------------------------------------------
+
+install-sky130-local: sky130
+ (cd sky130 && ${MAKE} install-local)
+
+install-sky130-dist: sky130
+ (cd sky130 && ${MAKE} install-dist)
+
+clean-sky130:
+ (cd sky130 && ${MAKE} clean)
+
+veryclean-sky130:
+ (cd sky130 && ${MAKE} veryclean)
+
+#---------------------------------------------------
+
+install:
+ ${MAKE} install-local
+
+install-local: ${TECHS}
+ for tech in ${TECHS}; do \
+ ${MAKE} install-$${tech}-local; done
+
+install-dist: ${TECHS}
+ for tech in ${TECHS}; do \
+ ${MAKE} install-$${tech}-dist; done
+
+#---------------------------------------------------
+
+clean:
+ for tech in ${TECHS}; do \
+ ${MAKE} clean-$${tech}; done
+
+veryclean:
+ for tech in ${TECHS}; do \
+ ${MAKE} veryclean-$${tech}; done
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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12651e0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+Open-PDKs (open_pdks)
+-----------------------------------------
+
+Summary:
+
+Automatic setup of PDKs for open-source tools from foundry sources.
+
+Builds out and populates a new set of directories and subdirectories in
+the efabless format, with the efabless name for the PDK at the top,
+followed by categories "libs.ref" (IP) and "libs.tech" (EDA tool setup),
+each with subcategories corresponding to layout, abstract views,
+netlists, etc. for the IP; and magic, netgen, qflow, etc., for the
+EDA tool setup.
+
+The populated PDK directories can contain either copies of files from
+the foundry sources, links to the foundry sources, or links back to
+another PDK.
+
+Generates magic layout views for all vendor IP for which either a GDS
+view or a LEF view exists. Annotates the views as needed to handle
+ports, bounding boxes, etc.
+
+-----------------------------------------
+
+This distribution contains sources for building out the SkyWater s8
+130nm process. Sources for the foundry process data must be obtained
+separately. Read the README file in subdirectory s8/ for instructions
+on obtaining and building the SkyWater s8 PDK.
+
+-----------------------------------------
+
+Instructions:
+
+There is a top-level Makefile but generally it is recommended to cd
+to the directory for the target foundry process and follow the instructions
+in the README file there.
+
diff --git a/common/README b/common/README
new file mode 100644
index 0000000..decfec1
--- /dev/null
+++ b/common/README
@@ -0,0 +1,584 @@
+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>[,...]
+ When using "compile" or "compile-only", exclude any
+ file in the target directory matching the name <file>.
+
+ 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.
diff --git a/common/cdl2spi.py b/common/cdl2spi.py
new file mode 100755
index 0000000..02e3bb7
--- /dev/null
+++ b/common/cdl2spi.py
@@ -0,0 +1,969 @@
+#!/usr/bin/env python3
+"""
+cdl2spi.py : netlist processor
+Copyright (c) 2016, 2020 efabless Corporation.
+All rights reserved.
+
+usage: cdl2spi.py <inCDLfile> [<outSPCfile>] [options...]
+Writes to .spi to outSPCfile, or stdout if no output argument given. Sets exit
+status if there were non-zero errors. Most errors/warnings are annotated in-line
+in the stdout each before the relevant line.
+"""
+
+import sys, getopt
+import os
+import re
+import textwrap
+
+# Convert linear scale to area scale suffix
+# (e.g., if linear scale is 1e-6 ('u') then area scales as 1e-12 ('p'))
+
+def getAreaScale(dscale):
+ ascale = ''
+ if dscale == 'm':
+ ascale = 'u'
+ elif dscale == 'u':
+ ascale = 'p'
+ elif dscale == 'n':
+ ascale = 'a'
+ return ascale
+
+# Check nm (instanceName) in the context of sub (subckt): is it used yet?
+# If not used yet, mark it used, and return as-is.
+# Else generate a unique suffixed version, and mark it used, return it.
+# If 1M suffixes don't generate a unique name, throw exception.
+# hasInm : global hash, key of hash is (subckt, iname)
+
+hasInm = {}
+def uniqInm(sub, nm):
+ subl=sub.lower()
+ nml=nm.lower()
+ if not (subl, nml) in hasInm:
+ hasInm[ (subl, nml) ] = 1
+ return nm
+ for i in range(1000000):
+ nm2 = nm + "_q" + str(i)
+ nm2l = nm2.lower()
+ if not (subl, nm2l) in hasInm:
+ hasInm[ (subl, nm2l) ] = 1
+ return nm2
+ # not caught anywhere, and gives (intended) non-zero exit status
+ raise AssertionError("uniqInm: range overflow for (%s,%s)" % (sub, nm))
+
+# Map illegal characters in an nm (instanceName) in context of sub (subckt).
+# For ngspice, '/' is illegal in instanceNames. Replace it with '|', BUT
+# then make sure the new name is still unique: does not collide with a name
+# used so far or another already derived unique name.
+
+inmBadChars='/'
+inmRplChars='|'
+inmBadCharREX=re.compile( "["+ inmBadChars+"]" )
+
+def mapInm(sub, nm):
+ nm2 = inmBadCharREX.sub(inmRplChars, nm)
+ return uniqInm(sub, nm2)
+
+# Process subckt line (array of tokens). Return new array of tokens.
+# There might be a ' /' in the line that needs to be deleted. It may be standalone ' / ', or
+# butting against the next token. It may be before all pins, after all pins, or between pins.
+# Do not touch / in a parameter assignment expression.
+# Do not touch / embedded in a pinName.
+# May touch / butting front of very first parameter assignment expression.
+# .subckt NM / p1 p2 p3 x=y g=h
+# .subckt NM /p1 p2 p3 x=y g=h
+# .subckt NM p1 p2 / p3 x=y g=h
+# .subckt NM p1 p2 /p3 x=y g=h
+# .subckt NM p1 p2 p3 / x=y g=h
+# .subckt NM p1 p2 p3 /x=y g=h
+# .subckt NM p1 p2 p3 x=y g=(a/b) (don't touch this /)
+# .subckt NM p1 p2/3/4 p3 x=y g=(a/b) (don't touch these /)
+
+def mapSubcktDef(tok):
+ # find index of one-past first token (beyond ".subckt NM") containing an =, if any
+ param0 = len(tok)
+ for i in range(2, len(tok)):
+ if '=' in tok[i]:
+ param0 = i+1
+ break
+ # find first token before or including that 1st-param, starting with /:
+ # strip the slash.
+ for i in range(2, param0):
+ if tok[i][0] == '/':
+ tok[i] = tok[i][1:]
+ if tok[i] == "":
+ del tok[i]
+ break
+ return tok
+
+def test_mapSubcktInst1():
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc / p1 p2 p3".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc /p1 p2 p3".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 /p3".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 / p3".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3 x=4 /y=5".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3 x=4/2 y=5".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3 / x=4/2 y=5".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3 x=4/2 /y=5".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1 p2 p3 /x=4/2 y=5".split())))
+ print( " ".join(mapSubcktDef( ".subckt abc p1/2/3 p2 p3 /x=4/2 y=5".split())))
+
+# Process subckt instance line (array of tokens). Return new array of tokens.
+# (This function does not map possible illegal-chars in instanceName).
+# There might be a ' /' in the line that needs to be deleted. It may be standalone ' / ', or
+# butting against the next token. It can only be after pins, before or butting subcktName.
+#
+# Do not touch / in, butting, or after 1st parameter assignment expression.
+# Do not touch / embedded in a netName.
+# Do not touch / embedded in instanceName (they are handled separately elsewhere).
+# xa/b/c p1 p2 p3 / NM x=y g=h
+# xa/b/c p1 p2 p3 /NM x=y g=h
+# xabc p1 p2/3/4 p3 /NM x=(a/b) g=h
+# xabc p1 p2/3/4 p3 / NM x=(a/b) g=h
+# xabc p1 p2/3/4 p3 NM x=(a/b) / g=h (don't touch; perhaps needs to be an error trapped somewhere)
+# xabc p1 p2/3/4 p3 NM / x=(a/b) g=h (don't touch; perhaps needs to be an error trapped somewhere)
+# xa/b/c p1 p2/3/4 p3 NM x=(a/b) g=h (don't touch these /)
+
+def mapSubcktInst(tok):
+ # find index of first token (beyond "x<iname>") containing an =, if any
+ param0 = tlen = len(tok)
+ for i in range(1, tlen):
+ if '=' in tok[i]:
+ param0 = i
+ break
+ # Determine modelName index. Either just prior to 1st-param (if any) else last token.
+ modndx = tlen - 1
+ if param0 < tlen:
+ modndx = param0 - 1;
+ # If modndx now points to a standalone /, that can't be (would yield missing/empty modelName).
+ # Actual modelName must be before it. We need to check, possibly strip / on/before actual modelName.
+ # (Even though standlone / after model are most likely an independent error: we don't touch 'em).
+ while modndx > 1 and tok[modndx] == "/":
+ modndx-=1
+ # Check for standalone / before modelName. Else for modelName starting with /.
+ slashndx = modndx - 1
+ if slashndx > 0 and tok[slashndx] == "/":
+ del tok[slashndx]
+ else:
+ if modndx > 0 and tok[modndx].startswith("/"):
+ tok[modndx] = tok[modndx][1:]
+ return tok
+
+def test_mapSubcktInst2():
+ print( " ".join(mapSubcktInst( "xa/b/c p1 p2 p3 / NM x=y g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c p1 p2 p3 /NM x=y g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 /NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 / NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 NM x=(a/b) / g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 NM / x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 /NM / x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xabc p1 p2/3/4 p3 / NM / x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c p1 p2/3/4 p3 NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c / NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c /NM x=(a/b) g=h".split())))
+ print( " ".join(mapSubcktInst( "xa/b/c /NM".split())))
+
+# Primitives with M=<n> need to add additional par1=<n>.
+# Process token list, return new token list.
+# note: line at this point may be like: m... p1 p2 p3 p4 NMOS M=1 $blah W=... L=...
+# meaning M=1 is not necessarily in a block of all parameter-assignments at EOL.
+# But by processing the line from end backwards, we pick up LAST M= if there are
+# multiple (which condition really should get flagged as an error).
+# And M= is more likely towards end of the line than front of line (thus faster).
+# If "M=" with no value, do nothing (should also be a flagged error).
+
+def mapMfactor(tok, options={}):
+ # find index of M=* if any, starting from end.
+ # "addinm" is an additional parameter that takes the same argument as M
+ addinm = options['addinm'] if 'addinm' in options else []
+ mndx = 0
+ val = ""
+ for i in range(len(tok)-1, 0, -1):
+ if tok[i].lower().startswith("m="):
+ mndx = i
+ break
+ if mndx > 0:
+ val = tok[i][2:]
+ if val != "":
+ for p in addinm:
+ tok += [ addinm + val]
+ return tok
+
+def test_mapMfactor():
+ print( " ".join(mapMfactor( "m1 p1 p2 p3 p4 NM M=joe".split())))
+ print( " ".join(mapMfactor( "m1 p1 p2 p3 p4 NM M= $SUB=agnd".split())))
+ print( " ".join(mapMfactor( "m1 p1 p2 p3 p4 NM M=2 $SUB=agnd WM=4".split())))
+ print( " ".join(mapMfactor( "m1 p1 p2 p3 p4 NM".split())))
+
+# From $nm=... strip the $. Preserve order on the line. No attempt to
+# detect any resultant collisions. "W=5 $W=10" becomes "W=5 W=10".
+# Don't touch $SUB=... or $[...] or $.model=... or $blah (no assigment).
+
+def mapCDLparam(tok):
+ for i in range(1, len(tok)):
+ if not tok[i].startswith("$"):
+ continue
+ eqi = tok[i].find("=")
+ if eqi > 1:
+ pnm = tok[i][1:eqi]
+ pnml = pnm.lower()
+ if pnml in ("sub",".model"):
+ continue
+ tok[i] = tok[i][1:]
+ return tok
+
+def test_CDLparam():
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M=joe".split())))
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M= $SUB=agnd $.model=NM3 $LDD".split())))
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M= $SUB=agnd $[NM3]".split())))
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M=joe $X=y".split())))
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M= $SUB=agnd $.model=NM3 $Z=4 $Z=5".split())))
+ print( " ".join(mapCDLparam( "m1 p1 p2 p3 p4 NM M= W=1 $W=2 W=3 $SUB=agnd $[NM3]".split())))
+
+# Extract $SUB=<tname>. and $[mnm] (or $.model=<mnm>) from tokens.
+# Return array of three items: [ <tname>, <mnm>, tok ] where tok is remainder.
+# Absent $SUB= or model directives give "".
+# Since we delete tokens, process tokens in reverse order.
+
+def mapCDLtermModel(tok):
+ cdlTerm=""
+ cdlModel=""
+ for i in range(len(tok)-1, 0, -1):
+ if not tok[i].startswith("$"):
+ continue
+ tokl = tok[i].lower()
+ if tokl.startswith("$sub="):
+ if cdlTerm == "":
+ cdlTerm = tok[i][5:]
+ del tok[i]
+ continue
+ if tokl.startswith("$.model="):
+ if cdlModel == "":
+ cdlModel = tok[i][8:]
+ del tok[i]
+ continue
+ if tokl.startswith("$[") and tokl.endswith("]"):
+ if cdlModel == "":
+ cdlModel = tok[i][2:-1]
+ del tok[i]
+ continue
+ return [ cdlTerm, cdlModel, tok ]
+
+def test_CDLtermModel():
+ print( mapCDLtermModel( "m1 p1 p2 p3 p4 NM M=joe".split()))
+ print( mapCDLtermModel( "m1 p1 p2 p3 p4 NM $SUB=agnd".split()))
+ print( mapCDLtermModel( "m1 p1 p2 p3 p4 NM $SUB= $[PMOS] M=joe".split()))
+ print( mapCDLtermModel( "m1 p1 p2 p3 p4 NM $sUb=vssa $.MoDeL=PM4 M=joe".split()))
+
+# Determine if a single word looks like a plain numeric spice value.
+# It means a real-number with optional scale suffix, and optional unit suffix.
+# Only unit-suffix we support is m (meters) (because CDL-std describes it).
+# Only scale factors supported are: t,g,meg,k,mil,m,u,n,p,f
+# This does not arithmetically compute anything.
+# Just returns True or False.
+# 220p 10nm -40g 2milm .34e+3 3.1e-4 .34e+3pm 3.1e-4meg
+# (Arguable we should strip a unit-suffix)?
+# def isPlainNumeric(word):
+
+# Segregate any remaining $* items from input tokens.
+# Return [ assignments, directives, remaining ] where each are lists.
+# Those that look like assigments $nm=... are separated from $blah.
+
+def mapDiscard(tok):
+ tlen = len(tok)
+ assign=[]
+ directive=[]
+ for i in range(len(tok)-1, 0, -1):
+ if not tok[i].startswith("$"):
+ continue
+ if "=" in tok[i]:
+ assign += [ tok[i] ]
+ del tok[i]
+ continue
+ directive += [ tok[i] ]
+ del tok[i]
+ return [ assign, directive, tok ]
+
+def test_mapDiscard():
+ print( mapDiscard( "m1 p1 p2 p3 p4 NM $X=4 $LDD M=joe $SUB=agnd ".split()))
+ print( mapDiscard( "m1 p1 p2 p3 p4 NM $X $LDD M=joe $SUB=agnd ".split()))
+ print( mapDiscard( "m1 p1 p2 p3 p4 NM M=joe SUB=agnd ".split()))
+
+# From a token-slice, partition into assignments and non-assignments.
+# Return [ assigns, nonAssigns] where each are lists.
+
+def mapPartAssign(tok):
+ tlen = len(tok)
+ assign=[]
+ nona=[]
+ for i in range(len(tok)):
+ if "=" in tok[i]:
+ assign += [ tok[i] ]
+ continue
+ nona += [ tok[i] ]
+ return [ assign, nona ]
+
+def test_mapPartAssign():
+ print( mapPartAssign( "NM X=4 220nm -1.2e-5g LDD M=joe".split()))
+ print( mapPartAssign( "X=4 M=joe".split()))
+ print( mapPartAssign( "NM 220nm -1.2e-5g LDD".split()))
+ print( mapPartAssign( "".split()))
+
+# Find an assignment to nm in the token list (nm=val).
+# Return [val, tok]. If edit is True, the nm=val is removed from return tok.
+# If multiple nm=... the last one is used. If del is True, all nm=... are removed.
+
+def mapLookup(tok, nm, edit):
+ tlen = len(tok)
+ val=""
+ nmeq = nm.lower() + "="
+ nmeqlen = len(nmeq)
+ for i in range(len(tok)-1, 0, -1):
+ if not tok[i].lower().startswith(nmeq):
+ continue
+ if val == "":
+ val = tok[i][nmeqlen:]
+ if edit:
+ del tok[i]
+ return [ val, tok ]
+
+def test_mapLookup():
+ print( mapLookup( "cnm t1 t2 area=220p PERimeter=100u M=joe par1=1".split(), "periMETER", True))
+ print( mapLookup( "m1 p1 p2 p3 p4 NM $X=4 $LDD M=joe $SUB=agnd ".split(), "x", True))
+ print( mapLookup( "m1 p1 p2 p3 p4 NM X=4 $LDD M=joe $SUB=agnd ".split(), "x", True))
+ print( mapLookup( "m1 p1 p2 p3 p4 NM x=4 $LDD M=joe $SUB=agnd ".split(), "x", True))
+ print( mapLookup( "m1 p1 p2 p3 p4 NM x=4 X=5 xy=6 $LDD M=joe $SUB=agnd ".split(), "x", True))
+ print( mapLookup( "m1 p1 p2 p3 p4 NM x=4 X=5 xy=6 $LDD M=joe $SUB=agnd ".split(), "x", False))
+
+# Format a diode. cdlTerm and cdlModel are passed in but ignored/unused.
+# Processes tok and returns a final token list to be output.
+# If after "dnm t1 t2 modelName ", there are plain numerics (index 4,5), take them as area and peri,
+# (override other area= peri= parameters), format them as area=... peri=...
+# (Caller already error checked the 1st minimum FOUR fields are there).
+
+def mapDiode(cdlTerm, cdlModel, tok, options={}):
+ ignore = options['ignore'] if 'ignore' in options else []
+ # strip remaining $* directives
+ [ ign, ign, tok ] = mapDiscard(tok)
+ # Find explicit area= peri=, remove from tok.
+ [area, tok] = mapLookup(tok, "area", True)
+ [peri, tok] = mapLookup(tok, "peri", True)
+ for p in ignore:
+ [ign, tok] = mapLookup(tok, p, True)
+ # For just token-slice after modelName, partition into assignments and non-assigns.
+ [assign, nona] = mapPartAssign(tok[4:])
+ tok = tok[0:4]
+ # TODO: If we have more than two non-assignments it should be an error?
+ # Override area/peri with 1st/2nd non-assigment values.
+ if len(nona) > 0:
+ area = nona.pop(0)
+ if len(nona) > 0:
+ peri = nona.pop(0)
+ if area != "":
+ tok += [ "area=" + area ]
+ if peri != "":
+ tok += [ "peri=" + peri ]
+ tok += nona
+ tok += assign
+ return tok
+
+def test_mapDiode():
+ print( mapDiode( "", "", "dnm t1 t2 DN 220p 100u M=joe par1=1".split()))
+ print( mapDiode( "", "", "dnm t1 t2 DN peri=100u area=220p M=joe par1=1".split()))
+ print( mapDiode( "", "", "dnm t1 t2 DN M=joe par1=1".split()))
+
+# Format a mosfet. cdlTerm and cdlModel are passed in but ignored/unused.
+# Processes tok and returns a final token list to be output.
+# If after "mnm t1 t2 t3 t4 modelName ", there are plain numerics (index 6,7), take them as W and L,
+# (override other W= L= parameters), format them as W=... L=...
+# (Caller already error checked the 1st minimum SIX fields are there).
+
+def mapMos(cdlTerm, cdlModel, tok, options={}):
+ ignore = options['ignore'] if 'ignore' in options else []
+ # strip remaining $* directives
+ [ ign, ign, tok ] = mapDiscard(tok)
+ # Find explicit W= L=, remove from tok.
+ [w, tok] = mapLookup(tok, "w", True)
+ [l, tok] = mapLookup(tok, "l", True)
+ for p in ignore:
+ [ign, tok] = mapLookup(tok, p, True)
+ # For scaling, find AS, PS, AD, PD, SA, SB, SC, and SD
+ [sarea, tok] = mapLookup(tok, "as", True)
+ [darea, tok] = mapLookup(tok, "ad", True)
+ [sperim, tok] = mapLookup(tok, "ps", True)
+ [dperim, tok] = mapLookup(tok, "pd", True)
+ [sa, tok] = mapLookup(tok, "sa", True)
+ [sb, tok] = mapLookup(tok, "sb", True)
+ [sd, tok] = mapLookup(tok, "sd", True)
+
+ dscale = options['dscale'] if 'dscale' in options else ''
+ ascale = getAreaScale(dscale)
+
+ # For just token-slice after modelName, partition into assignments and non-assigns.
+ [assign, nona] = mapPartAssign(tok[6:])
+ tok = tok[0:6]
+ # TODO: If we have more than two non-assignments it should be an error?
+ # Override W/L with 1st/2nd non-assigment values.
+ if len(nona) > 0:
+ w = nona.pop(0)
+ if len(nona) > 0:
+ l = nona.pop(0)
+ if w != "":
+ tok += ["W=" + w + dscale]
+ if l != "":
+ tok += ["L=" + l + dscale]
+ if darea != "":
+ tok += ["AD=" + darea + ascale]
+ if sarea != "":
+ tok += ["AS=" + sarea + ascale]
+ if dperim != "":
+ tok += ["PD=" + dperim + dscale]
+ if sperim != "":
+ tok += ["PS=" + sperim + dscale]
+ if sa != "":
+ tok += ["SA=" + sa + dscale]
+ if sb != "":
+ tok += ["SB=" + sb + dscale]
+ if sd != "":
+ tok += ["SD=" + sd + dscale]
+ tok += nona
+ tok += assign
+ return tok
+
+def test_mapMos():
+ print( mapMos( "", "", "mnm t1 t2 t3 t4 NM 220p 100u M=joe par1=1".split()))
+ print( mapMos( "", "", "mnm t1 t2 t3 t4 NM L=100u W=220p M=joe par1=1".split()))
+ print( mapMos( "", "", "mnm t1 t2 t3 t4 PM M=joe par1=1".split()))
+
+# Format a cap.
+# Processes tok and returns a final token list to be output.
+# Optional cdlTerm adds a 3rd terminal.
+# If after "cnm t1 t2 ", there is plain numeric or C=numeric they are DISCARDED.
+# area/peri/perimeter assignments are respected. Both peri/perimeter assign to perm=
+# in the output. No perimeter= appears in the output.
+# (Caller already error checked the 1st minimum 3 fields are there; plus cdlModel is non-null).
+
+def mapCap(cdlTerm, cdlModel, tok, options={}):
+ ignore = options['ignore'] if 'ignore' in options else []
+ # strip remaining $* directives
+ [ ign, ign, tok ] = mapDiscard(tok)
+ # Find explicit area= peri= perimeter=, remove from tok. peri overwrites perimeter,
+ # both assign to perim. Lookup/discard a C=.
+ [area, tok] = mapLookup(tok, "area", True)
+ [perim, tok] = mapLookup(tok, "perimeter", True)
+ [length, tok] = mapLookup(tok, "l", True)
+ [width, tok] = mapLookup(tok, "w", True)
+ [peri, tok] = mapLookup(tok, "peri", True)
+ if peri == "":
+ peri = perim
+ [ign, tok] = mapLookup(tok, "c", True)
+ for p in ignore:
+ [ign, tok] = mapLookup(tok, p, True)
+ # For just token-slice after modelName, partition into assignments and non-assigns.
+ # We ignore the nonassignments. Need remaining assignments for M= par1=.
+ [assign, nona] = mapPartAssign(tok[3:])
+ dscale = options['dscale'] if 'dscale' in options else ''
+ ascale = getAreaScale(dscale)
+ tok = tok[0:3]
+ if cdlTerm != "":
+ tok += [ cdlTerm ]
+ if cdlModel != "":
+ tok += [ cdlModel ]
+ if area != "":
+ tok += [ "area=" + area + ascale]
+ if peri != "":
+ tok += [ "peri=" + peri + dscale]
+ if length != "":
+ tok += [ "L=" + length + dscale]
+ if width != "":
+ tok += [ "W=" + width + dscale]
+ tok += assign
+ return tok
+
+def test_mapCap():
+ print( mapCap( "", "CPP", "cnm t1 t2 area=220p peri=100u M=joe par1=1".split()))
+ print( mapCap( "", "CPP", "cnm t1 t2 area=220p perimeter=100u M=joe par1=1".split()))
+ print( mapCap( "", "CPP", "cnm t1 t2 area=220p peri=199u perimeter=100u M=joe par1=1".split()))
+ print( mapCap( "", "CPP", "cnm t1 t2 M=joe par1=1".split()))
+ print( mapCap( "", "CPP", "cnm t1 t2 C=444 area=220p peri=199u perimeter=100u M=joe par1=1".split()))
+ print( mapCap( "", "CPP", "cnm t1 t2 444 M=joe par1=1".split()))
+ print( mapCap( "agnd", "CPP2", "cnm t1 t2 $LDD 220p M=joe par1=1".split()))
+
+# Format a res.
+# Processes tok and returns a final token list to be output.
+# Optional cdlTerm adds a 3rd terminal.
+# If after "rnm t1 t2 ", there is plain numeric or R=numeric they are DISCARDED.
+# W/L assignments are respected.
+# (Caller already error checked the 1st minimum 3 fields are there; plus cdlModel is non-null).
+
+def mapRes(cdlTerm, cdlModel, tok, options={}):
+ dscale = options['dscale'] if 'dscale' in options else ''
+ ignore = options['ignore'] if 'ignore' in options else []
+ # strip remaining $* directives
+ [ ign, ign, tok ] = mapDiscard(tok)
+ # Find explicit w/l, remove from tok.
+ # Lookup/discard a R=.
+ [w, tok] = mapLookup(tok, "w", True)
+ [l, tok] = mapLookup(tok, "l", True)
+ [r, tok] = mapLookup(tok, "r", True)
+ for p in ignore:
+ [ign, tok] = mapLookup(tok, p, True)
+ # For just token-slice after modelName, partition into assignments and non-assigns.
+ # We ignore the nonassignments. Need remaining assignments for M= par1=.
+ [assign, nona] = mapPartAssign(tok[3:])
+ if len(nona) > 0:
+ r = nona.pop(0)
+ tok = tok[0:3]
+ if cdlTerm != "":
+ tok += [ cdlTerm ]
+ if cdlModel != "":
+ tok += [ cdlModel ]
+ if w != "":
+ tok += [ "W=" + w + dscale]
+ if l != "":
+ tok += [ "L=" + l + dscale]
+ # Convert name "short" to zero resistance
+ if r == "short":
+ tok += [ "0" ]
+ tok += assign
+ return tok
+
+def test_mapRes():
+ print( mapRes( "", "RPP1", "rnm t1 t2 w=2 L=1 M=joe par1=1".split()))
+ print( mapRes( "", "RPP1", "rnm t1 t2 444 w=2 L=1 M=joe par1=1".split()))
+ print( mapRes( "", "RPP1", "rnm t1 t2 R=444 w=2 L=1 M=joe par1=1".split()))
+ print( mapRes( "", "R2", "rnm t1 t2 L=2 W=10 M=joe par1=1".split()))
+ print( mapRes( "", "RM2", "rnm t1 t2 area=220p perim=199u perimeter=100u M=joe par1=1".split()))
+ print( mapRes( "", "RM2", "rnm t1 t2 M=joe par1=1".split()))
+ print( mapRes( "agnd", "RM3", "rnm t1 t2 $LDD 220p M=joe par1=1".split()))
+ print( mapRes( "agnd", "RM3", "rnm t1 t2 $LDD 220p L=4 W=12 M=joe par1=1".split()))
+
+# Format a bipolar. cdlTerm is optional. cdlModel is ignored.
+# Processes tok and returns a final token list to be output.
+# Optional cdlTerm adds an optional 4th terminal.
+# If after "qnm t1 t2 t3 model", there are plain numeric (not x=y) they are DISCARDED.
+# (Caller already error checked the 1st minimum 5 fields are there; plus cdlModel is null).
+
+def mapBipolar(cdlTerm, cdlModel, tok, options={}):
+ # strip remaining $* directives
+ ignore = options['ignore'] if 'ignore' in options else []
+ [ ign, ign, tok ] = mapDiscard(tok)
+ for p in ignore:
+ [ign, tok] = mapLookup(tok, p, True)
+ # For just token-slice after modelName, partition into assignments and non-assigns.
+ # We ignore the nonassignments. Need remaining assignments for M= par1=.
+ [assign, nona] = mapPartAssign(tok[5:])
+ # Start with "qnm t1 t2 t3". Insert optional 4th term. Then insert modelName.
+ model = tok[4]
+ tok = tok[0:4]
+ if cdlTerm != "":
+ tok += [ cdlTerm ]
+ tok += [ model ]
+ tok += assign
+ return tok
+
+def test_mapBipolar():
+ print( mapBipolar( "", "any", "qnm t1 t2 t3 QP1 M=joe par1=1".split()))
+ print( mapBipolar( "", "", "qnm t1 t2 t3 QP2 M=joe par1=1".split()))
+ print( mapBipolar( "", "", "qnm t1 t2 t3 QP2 $EA=12 M=joe par1=1".split()))
+ print( mapBipolar( "", "", "qnm t1 t2 t3 QP3 M=joe EA=14 par1=1".split()))
+ print( mapBipolar( "agnd", "", "qnm t1 t2 t3 QP4 $LDD 220p M=joe par1=1".split()))
+ print( mapBipolar( "agnd", "any", "qnm t1 t2 t3 QP4 $LDD 220p L=4 W=12 M=joe par1=1".split()))
+
+#------------------------------------------------------------------------
+# Main routine to do the conversion from CDL format to SPICE format
+#------------------------------------------------------------------------
+
+def cdl2spice(fnmIn, fnmOut, options):
+
+ err = 0
+ warn = 0
+
+ # Open and read input file
+
+ try:
+ with open(fnmIn, 'r') as inFile:
+ cdltext = inFile.read()
+ # Unwrap continuation lines
+ lines = cdltext.replace('\n+', ' ').splitlines()
+ except:
+ print('cdl2spi.py: failed to open ' + fnmIn + ' for reading.', file=sys.stderr)
+ return 1
+
+ # Loop over original CDL:
+ # record existing instanceNames (in subckt-context), for efficient membership
+ # tests later. Track the subckt-context, instanceNames only need to be unique
+ # within current subckt.
+
+ sub = ""
+ for i in lines:
+ if i == "":
+ continue
+ tok = i.split()
+ tlen = len(tok)
+ if tlen == 0:
+ continue
+ t0 = tok[0].lower()
+ if t0 == '.subckt' and tlen > 1:
+ sub = tok[1].lower()
+ continue
+ if t0 == '.ends':
+ sub = ""
+ continue
+ c0 = tok[0][0].lower()
+ if c0 in '.*':
+ continue
+ # this will ignore primitive-devices (jfet) we don't support.
+ # TODO: flag them somewhere else as an ERROR.
+ if not c0 in primch2:
+ continue
+ # a primitive-device or subckt-instance we care about and support
+ # For subckt-instances record the instanceName MINUS lead x.
+ nm = tok[0]
+ if c0 == 'x':
+ nm = nm[1:]
+ hasInm[ (sub, nm) ] = 1
+
+
+ # loop over original CDL: do conversions.
+ # Track the subckt-context while we go; instanceNames only need to be unique
+ # within current subckt.
+
+ sub = ""
+ tmp = []
+ for i in lines:
+ tok = i.split()
+ tlen = len(tok)
+ # AS-IS: empty line or all (preserved) whitespace
+ if tlen == 0:
+ tmp += [ i ]
+ continue
+
+ # get 1st-token original, as lowercase, and 1st-char of 1st-token lowercase.
+ T0 = tok[0]
+ t0 = T0.lower()
+ c0 = t0[0]
+
+ # AS-IS: comment
+ if c0 == '*':
+ tmp += [i]
+ continue
+
+ # AS-IS: .ends; update subckt-context to outside-of-a-subckt
+ if t0 == '.ends':
+ sub = ""
+ tmp += [i]
+ continue
+
+ # change .param to a comment, output it
+ if t0 == '.param':
+ tmp += ["*"+i]
+ continue
+
+ # track .subckt context; process / in .subckt line, and output it.
+ if t0 == '.subckt':
+ if tlen < 2:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Missing subckt name:"
+ tmp += [ msg, i ]
+ continue
+ T1 = tok[1]
+ sub = T1.lower()
+ tok = mapSubcktDef(tok)
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # subckt instance line. Process /, map instanceName (exclude x), and output it.
+ if c0 == 'x':
+ nm = T0[1:]
+ if nm == "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Missing subckt instance name:"
+ tmp += [ msg, i ]
+ continue
+ inm = mapInm(sub, nm)
+ tok[0] = T0[0] + inm
+ tok = mapSubcktInst(tok)
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # all primitives: need instanceName mapped, including 1st char in name.
+ # all primitives: need M=n copied to an added par1=n
+ # all primitives: Except for $SUB=... $[...] strip $ from $nm=... parameters.
+ # all primitives: Isolate $SUB and $[...] for further processing (in
+ # primitive-specific sections).
+
+ cdlTerm=""
+ cdlModel=""
+ if c0 in primch:
+ nm = T0[1:]
+ if nm == "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Missing primitive instance name:"
+ tmp += [ msg, i ]
+ continue
+ nm = T0
+ nm = mapInm(sub, nm)
+ tok[0] = nm
+ tok = mapMfactor(tok, options)
+ tok = mapCDLparam(tok)
+ [cdlTerm, cdlModel, tok] = mapCDLtermModel(tok)
+
+ # diode formats:
+ # dname t1 t2 model <numericA> <numericP> m=...
+ # l:dname t1 t2 model {<numericA>} {<numericP>} {m=...} {$SUB=...}
+ # out format:
+ # Xdname t1 t2 model area=<numericA> peri=<numericP> m=... par1=...
+ # We flag $SUB=... : because so far (for XFAB) we CHOOSE not to support three
+ # terminal diodes.
+ # CDL-std does not define $[...] as available for diodes, so we silently ignore
+ # it.
+ # Always 2 terminals and a modelName.
+ # We already have peri=... and area=... and have ambiguity with plain numerics.
+ # TODO: generate a warning in case of ambiguity, but prefer plain numerics
+ # (with nm= added).
+
+ if c0 == "d":
+ tlen = len(tok)
+ if tlen < 4:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Diode does not have minimum two terminals and model:"
+ tmp += [ msg, i ]
+ continue
+ if cdlTerm != "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Diode does not support $SUB=...:"
+ tmp += [ msg, i ]
+ continue
+ tok = mapDiode(cdlTerm, cdlModel, tok, options)
+ # add X to tok0.
+ if options['subckt']:
+ tok[0] = "X" + tok[0]
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # mosfet formats:
+ # mname t1 t2 t3 t4 model W=... L=... m=...
+ # l:mname t1 t2 t3 t4 model {W=... L=...} {m=...} {$NONSWAP} {$LDD[type]}
+ # l:mname t1 t2 t3 t4 model <width> <length> {m=...} {$NONSWAP} {$LDD[type]}
+ # output format:
+ # Xmname t1 t2 t3 t4 model W=... L=... m=... par1=...
+ # Fixed 4 terminals and a modelName.
+ # May already have W= L= and ambiguity with plain numerics.
+ # TODO: generate a warning in case of ambiguity, but prefer plain numerics
+ # (with nm= added).
+ if c0 == "m":
+ tlen = len(tok)
+ if tlen < 6:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Mosfet does not have minimum four terminals and model:"
+ tmp += [ msg, i ]
+ continue
+ if cdlTerm != "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Mosfet does not support $SUB=...:"
+ tmp += [ msg, i ]
+ continue
+ tok = mapMos(cdlTerm, cdlModel, tok, options)
+ # add X to tok0.
+ if options['subckt']:
+ tok[0] = "X" + tok[0]
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # cap formats:
+ # cname t1 t2 <numeric0> $[model] $SUB=t3 m=...
+ # cname t1 t2 <numeric0> $[model] m=...
+ #? cname t1 t2 C=<numeric0> $[model] $SUB=t3 m=...
+ #? cname t1 t2 <numeric0> $[model] $SUB=t3 area=<numericA> perimeter=<numericP> m=...
+ #? cname t1 t2 <numeric0> $[model] $SUB=t3 area=<numericA> peri=<numericP> m=...
+ #l:cname t1 t2 {<numeric0>} {$[model]} {$SUB=t3} {m=...}
+ # out formats:
+ # Xcname t1 t2 model area=<numericA> peri=<numericP> m=... par1=...
+ # Xcname t1 t2 t3 model area=<numericA> peri=<numericP> m=... par1=...
+ # We require inm, two terminals. Require $[model]. Optional 3rd-term $SUB=...
+ # If both peri and perimeter, peri overrides.
+ # Both area/peri are optional. The optional [C=]numeric0 is discarded always.
+
+ if c0 == "c":
+ tlen = len(tok)
+ if tlen < 3:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Cap does not have minimum two terminals:"
+ tmp += [ msg, i ]
+ continue
+ if cdlModel == "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Cap missing required $[<model>] directive:"
+ tmp += [ msg, i ]
+ continue
+ tok = mapCap(cdlTerm, cdlModel, tok, options)
+ # add X to tok0.
+ if options['subckt']:
+ tok[0] = "X" + tok[0]
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # res formats:
+ # rname n1 n2 <numeric> $SUB=t3 $[model] $w=... $l=... m=...
+ # c:rname n1 n2 R=<numeric> $[model] w=... l=... m=... $SUB=t3
+ # l:rname n1 n2 {<numeric>} {$SUB=t3} {$[model]} {$w=...} {$l=...} {m=...}
+ # (all after n1,n2 optional)
+ # We require $[model]. And add 3rd term IFF $SUB=.
+ # out format:
+ # Xrname n1 n2 t3 model w=... l=... m=... par1=...
+ if c0 == "r":
+ tlen = len(tok)
+ if tlen < 3:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Res does not have minimum two terminals:"
+ tmp += [ msg, i ]
+ continue
+ if cdlModel == "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Res missing required $[<model>] directive:"
+ tmp += [ msg, i ]
+ continue
+ tok = mapRes(cdlTerm, cdlModel, tok, options)
+ # add X to tok0.
+ if options['subckt']:
+ tok[0] = "X" + tok[0]
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # bipolar formats:
+ # qname n1 n2 n3 model <numeric> M=... $EA=...
+ # qname n1 n2 n3 model $EA=... <numeric> M=...
+ # qname n1 n2 n3 model {$EA=...} {$W=...} {$L=...} {$SUB=...} {M=...}
+ # No: l:qname n1 n2 n3 {nsub} model {$EA=...} {$W=...} {$L=...} {$SUB=...} {M=...}
+ # CDL-std adds {nsub} way to add substrate before model: We don't support it.
+ # Add 3rd term IFF $SUB=. We propagate optional W/L (or derived from $W/$L).
+ # EA is emitterSize; not supported by XFAB: deleted.
+ # We require 3-terminals and model. It is an error to specify $[model].
+ #
+ # out format:
+ # Xqname n1 n2 n3 model M=... par1=...
+ if c0 == "q":
+ tlen = len(tok)
+ if tlen < 5:
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Bipolar does not have minimum three terminals and a model:"
+ tmp += [ msg, i ]
+ continue
+ if cdlModel != "":
+ err+=1
+ msg = "*cdl2spi.py: ERROR: Bipolar does not support $[<model>] directive:"
+ tmp += [ msg, i ]
+ continue
+ tok = mapBipolar(cdlTerm, cdlModel, tok, options)
+ # add X to tok0.
+ if options['subckt']:
+ tok[0] = "X" + tok[0]
+ tmp += [ " ".join(tok) ]
+ continue
+
+ # Anything else. What to do, preserve AS-IS with warning, or
+ # flag them as ERRORs?
+ tmp += [ "*cdl2spi.py: ERROR: unrecognized line:", i ]
+ err+=1
+ # tmp += [ "*cdl2spi.py: WARNING: unrecognized line:", " ".join(tok) ]
+ # tmp += [ "*cdl2spi.py: WARNING: unrecognized line:", i ]
+ # warn+=1
+
+ # Re-wrap continuation lines at 80 characters
+ lines = []
+ for line in tmp:
+ lines.append('\n+ '.join(textwrap.wrap(line, 80)))
+
+ # Write output
+
+ if fnmOut == sys.stdout:
+ for i in lines:
+ print(i)
+ else:
+ try:
+ with open(fnmOut, 'w') as outFile:
+ for i in lines:
+ print(i, file=outFile)
+ except:
+ print('cdl2spi.py: failed to open ' + fnmOut + ' for writing.', file=sys.stderr)
+ return 1
+
+ # exit status: indicates if there were errors.
+ print( "*cdl2spi.py: %d errors, %d warnings" % (err, warn))
+ return err
+
+if __name__ == '__main__':
+
+ options = {}
+
+ # Set option defaults
+ options['debug'] = False
+ options['subckt'] = False
+ options['dscale'] = ''
+ options['addinm'] = []
+ options['ignore'] = []
+
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ thisopt = item.split('=')
+ optname = thisopt[0][1:]
+ optval = '='.join(thisopt[1:])
+ if not optname in options:
+ print('Unknown option -' + optname + '; ignoring.')
+ else:
+ lastoptval = options[optname]
+ if len(thisopt) == 1:
+ options[optname] = True
+ elif lastoptval == '':
+ options[optname] = optval
+ else:
+ options[optname].append(optval)
+ else:
+ arguments.append(item)
+
+ # Supported primitive devices (FET, diode, resistor, capacitor, bipolar)
+ primch = 'mdrcq'
+ primch2 = 'mdrcqx'
+
+ if len(arguments) > 0:
+ fnmIn = arguments[0]
+
+ if len(arguments) > 1:
+ fnmOut = arguments[1]
+ else:
+ fnmOut = sys.stdout
+
+ if options['debug']:
+ test_mapSubcktInst1()
+ test_mapSubcktInst2()
+ test_mapMfactor()
+ test_CDLparam()
+ test_CDLtermModel()
+ test_mapDiscard()
+ test_mapPartAssign()
+ test_mapLookup()
+ test_mapDiode()
+ test_mapMos()
+ test_mapCap()
+ test_mapRes()
+ test_mapBipolar()
+
+ elif len(arguments) > 2 or len(arguments) < 1 :
+ print('Usage: cdl2spi.py <cdlFileName> [<spiFileName>]')
+ print(' Options:' )
+ print(' -debug run debug tests')
+ print(' -dscale=<suffix> rescale lengths with <suffix>')
+ print(' -addinm=<param> add multiplier parameter <param>')
+ print(' -ignore=<param> ignore parameter <param>')
+ print(' -subckt convert primitive devices to subcircuits')
+ sys.exit(1)
+
+ else:
+ if options['debug'] == True:
+ print('Diagnostic: options = ' + str(options))
+ result = cdl2spice(fnmIn, fnmOut, options)
+ sys.exit(result)
+
diff --git a/common/change_gds_date.py b/common/change_gds_date.py
new file mode 100755
index 0000000..0aa0056
--- /dev/null
+++ b/common/change_gds_date.py
@@ -0,0 +1,142 @@
+#!/bin/env python3
+# Script to read a GDS file, modify the timestamp(s), and rewrite the GDS file.
+
+import os
+import sys
+import datetime
+
+def usage():
+ print('change_gds_date.py <create_stamp> <mod_stamp> <path_to_gds_in> [<path_to_gds_out>]')
+
+if __name__ == '__main__':
+ debug = False
+
+ if len(sys.argv) == 1:
+ print("No options given to change_gds_date.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ arguments = []
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ optionlist.append(option)
+ else:
+ arguments.append(option)
+
+ if len(arguments) < 3 or len(arguments) > 4:
+ print("Wrong number of arguments given to change_gds_date.py.")
+ usage()
+ sys.exit(0)
+
+ if '-debug' in optionlist:
+ debug = True
+
+ createstamp = arguments[0]
+ modstamp = arguments[1]
+ source = arguments[2]
+
+ # If modstamp is zero or negative, then set the modification timestamp
+ # to be the same as the creation timestamp.
+ try:
+ if int(modstamp) <= 0:
+ modstamp = createstamp
+ except:
+ pass
+
+ # If only three arguments are provided, then overwrite the source file.
+ if len(arguments) == 4:
+ dest = arguments[3]
+ else:
+ dest = arguments[2]
+
+ sourcedir = os.path.split(source)[0]
+ gdsinfile = os.path.split(source)[1]
+
+ destdir = os.path.split(dest)[0]
+ gdsoutfile = os.path.split(dest)[1]
+
+ with open(source, 'rb') as ifile:
+ gdsdata = ifile.read()
+
+ # Generate 12-byte modification timestamp data from date.
+ try:
+ modtime = datetime.datetime.fromtimestamp(int(modstamp))
+ except:
+ modtime = datetime.datetime.strptime(modstamp, "%m/%d/%Y %H:%M:%S")
+
+ modyear = modtime.year - 1900
+
+ year = modyear.to_bytes(2, byteorder='big')
+ month = modtime.month.to_bytes(2, byteorder='big')
+ day = modtime.day.to_bytes(2, byteorder='big')
+ hour = modtime.hour.to_bytes(2, byteorder='big')
+ minute = modtime.minute.to_bytes(2, byteorder='big')
+ second = modtime.second.to_bytes(2, byteorder='big')
+
+ gdsmodstamp = year + month + day + hour + minute + second
+
+ # Generate 12-byte creation timestamp data from date.
+ try:
+ createtime = datetime.datetime.fromtimestamp(int(createstamp))
+ except:
+ createtime = datetime.datetime.strptime(createstamp, "%m/%d/%Y %H:%M:%S")
+
+ createyear = createtime.year - 1900
+
+ year = createyear.to_bytes(2, byteorder='big')
+ month = createtime.month.to_bytes(2, byteorder='big')
+ day = createtime.day.to_bytes(2, byteorder='big')
+ hour = createtime.hour.to_bytes(2, byteorder='big')
+ minute = createtime.minute.to_bytes(2, byteorder='big')
+ second = createtime.second.to_bytes(2, byteorder='big')
+
+ gdscreatestamp = year + month + day + hour + minute + second
+
+ # To be done: Allow the user to select which datestamps to change
+ # (library or structure). Otherwise, apply the same datestamps to both.
+
+ recordtypes = ['beginstr', 'beginlib']
+ recordfilter = [5, 1]
+
+ datalen = len(gdsdata)
+ dataptr = 0
+ while dataptr < datalen:
+ # Read stream records up to any string, then search for search text.
+ bheader = gdsdata[dataptr:dataptr + 2]
+ reclen = int.from_bytes(bheader, 'big')
+ if reclen == 0:
+ print('Error: found zero-length record at position ' + str(dataptr))
+ break
+
+ rectype = gdsdata[dataptr + 2]
+ datatype = gdsdata[dataptr + 3]
+
+ brectype = rectype.to_bytes(1, byteorder='big')
+ bdatatype = datatype.to_bytes(1, byteorder='big')
+
+ if rectype in recordfilter:
+ # Datatype should be 2
+ if datatype != 2:
+ print('Error: Header data type is not 2-byte integer!')
+ if reclen != 28:
+ print('Error: Header record length is not 28!')
+ if debug:
+ print('Record type = ' + str(rectype) + ' data type = ' + str(datatype) + ' length = ' + str(reclen))
+
+ before = gdsdata[0:dataptr]
+ after = gdsdata[dataptr + reclen:]
+
+ # Assemble the new record
+ newrecord = bheader + brectype + bdatatype + gdscreatestamp + gdsmodstamp
+ # Reassemble the GDS data around the new record
+ gdsdata = before + newrecord + after
+
+ # Advance the pointer past the data
+ dataptr += reclen
+
+ with open(dest, 'wb') as ofile:
+ ofile.write(gdsdata)
+
+ exit(0)
diff --git a/common/change_gds_string.py b/common/change_gds_string.py
new file mode 100755
index 0000000..b8a0321
--- /dev/null
+++ b/common/change_gds_string.py
@@ -0,0 +1,127 @@
+#!/bin/env python3
+# Script to read a GDS file, modify the given string, and rewrite the GDS file.
+# The string may be a substring; the GDS file will be parsed completely for
+# library name, structure name, instance name, and other strings, and the
+# replacement made everywhere it occurs, finding the bounds of the entire
+# string around the search text, and adjusting the record bounds accordingly.
+
+import os
+import sys
+
+def usage():
+ print('change_gds_string.py <old_string> <new_string> <path_to_gds_in> [<path_to_gds_out>]')
+
+if __name__ == '__main__':
+ debug = False
+
+ if len(sys.argv) == 1:
+ print("No options given to change_gds_string.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ arguments = []
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ optionlist.append(option)
+ else:
+ arguments.append(option)
+
+ if len(arguments) < 3 or len(arguments) > 4:
+ print("Wrong number of arguments given to change_gds_string.py.")
+ usage()
+ sys.exit(0)
+
+ if '-debug' in optionlist:
+ debug = True
+
+ oldstring = arguments[0]
+ newstring = arguments[1]
+ source = arguments[2]
+
+ # If only three arguments are provided, then overwrite the source file.
+ if len(arguments) == 4:
+ dest = arguments[3]
+ else:
+ dest = arguments[2]
+
+ sourcedir = os.path.split(source)[0]
+ gdsinfile = os.path.split(source)[1]
+
+ destdir = os.path.split(dest)[0]
+ gdsoutfile = os.path.split(dest)[1]
+
+ with open(source, 'rb') as ifile:
+ gdsdata = ifile.read()
+
+ # To be done: Allow the user to select a specific record type or types
+ # in which to restrict the string substitution. If no restrictions are
+ # specified, then substitue in library name, structure name, and strings.
+
+ recordtypes = ['libname', 'strname', 'sname', 'string']
+ recordfilter = [2, 6, 18, 25]
+ bsearch = bytes(oldstring, 'ascii')
+ brep = bytes(newstring, 'ascii')
+
+ datalen = len(gdsdata)
+ if debug:
+ print('Original data length = ' + str(datalen))
+ dataptr = 0
+ while dataptr < datalen:
+ # Read stream records up to any string, then search for search text.
+ bheader = gdsdata[dataptr:dataptr + 2]
+ reclen = int.from_bytes(bheader, 'big')
+ newlen = reclen
+ if newlen == 0:
+ print('Error: found zero-length record at position ' + str(dataptr))
+ break
+
+ rectype = gdsdata[dataptr + 2]
+ datatype = gdsdata[dataptr + 3]
+
+ if rectype in recordfilter:
+ # Datatype 6 is STRING
+ if datatype == 6:
+ if debug:
+ print('Record type = ' + str(rectype) + ' data type = ' + str(datatype) + ' length = ' + str(reclen))
+
+ bstring = gdsdata[dataptr + 4: dataptr + reclen]
+ repstring = bstring.replace(bsearch, brep)
+ if repstring != bstring:
+ before = gdsdata[0:dataptr]
+ after = gdsdata[dataptr + reclen:]
+ newlen = len(repstring) + 4
+ # Record sizes must be even
+ if newlen % 2 != 0:
+ # Was original string padded with null byte? If so,
+ # remove the null byte and reduce newlen. Otherwise,
+ # add a null byte and increase newlen.
+ if bstring[-1] == 0:
+ repstring = repstring[0:-1]
+ newlen -= 1
+ else:
+ repstring += b'\x00'
+ newlen += 1
+
+ bnewlen = newlen.to_bytes(2, byteorder='big')
+ brectype = rectype.to_bytes(1, byteorder='big')
+ bdatatype = datatype.to_bytes(1, byteorder='big')
+
+ # Assemble the new record
+ newrecord = bnewlen + brectype + bdatatype + repstring
+ # Reassemble the GDS data around the new record
+ gdsdata = before + newrecord[0:newlen] + after
+ # Adjust the data end location
+ datalen += (newlen - reclen)
+
+ if debug:
+ print('Replaced ' + str(bstring) + ' with ' + str(repstring))
+
+ # Advance the pointer past the data
+ dataptr += newlen
+
+ with open(dest, 'wb') as ofile:
+ ofile.write(gdsdata)
+
+ exit(0)
diff --git a/common/changepath.py b/common/changepath.py
new file mode 100755
index 0000000..3ebd38c
--- /dev/null
+++ b/common/changepath.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+#
+# changepath.py: Look up all .mag files in maglef paths from the root
+# PDK directory given as the first argument, and replace them with the
+# path that is given as the second argument.
+#
+# The purpose of this script is to prepare a technology for relocation.
+# This script may be expanded to take care of all relocation issues.
+# For now, only the property "GDS_FILE" in each .mag file is modified.
+#
+# Usage, e.g.:
+#
+# changepath.py /home/tim/projects/efabless/tech/XFAB/EFXH035B/libs.ref/mag/D_CELLS /ef/tech/XFAB/EFXH035B/libs.ref/mag/D_CELLS
+
+import os
+import re
+import sys
+import glob
+
+def usage():
+ print("changepath.py <orig_path_to_dir> <target_path_to_dir>")
+ return 0
+
+if __name__ == '__main__':
+
+ if len(sys.argv) == 1:
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ arguments = []
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ optionlist.append(option)
+ else:
+ arguments.append(option)
+
+ if len(arguments) != 2:
+ print("Wrong number of arguments given to changepath.py.")
+ usage()
+ sys.exit(0)
+
+ source = arguments[0]
+ target = arguments[1]
+
+ gdssource = source.replace('/mag/', '/gds/')
+ gdssource = gdssource.replace('/maglef/', '/gds/')
+ gdstarget = target.replace('/mag/', '/gds/')
+ gdstarget = gdstarget.replace('/maglef/', '/gds/')
+
+ magpath = source + '/*.mag'
+ sourcefiles = glob.glob(magpath)
+
+ if len(sourcefiles) == 0:
+ print("Warning: No files were found in the path " + magpath + ".")
+
+ for file in sourcefiles:
+ # print("Converting file " + file)
+ with open(file, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ proprex = re.compile('string[ \t]+GDS_FILE[ \t]+([^ \t]+)')
+ with open(file, 'w') as ofile:
+ for line in magtext:
+ pmatch = proprex.match(line)
+ if pmatch:
+ filepath = pmatch.group(1)
+ if filepath.startswith(gdssource):
+ print('string GDS_FILE ' + filepath.replace(gdssource, gdstarget), file=ofile)
+ else:
+ print(line, file=ofile)
+ else:
+ print(line, file=ofile)
+
diff --git a/common/changetech.sh b/common/changetech.sh
new file mode 100755
index 0000000..383aac6
--- /dev/null
+++ b/common/changetech.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Example file converts the techname in all magic database files.
+
+for i in `ls *.mag` ; do
+ /ef/efabless/bin/preproc.py -DEFXH035A=EFXH035B $i > tmp.out
+ mv tmp.out $i ;
+done
+
diff --git a/common/compare_dirs.py b/common/compare_dirs.py
new file mode 100755
index 0000000..21f8dc6
--- /dev/null
+++ b/common/compare_dirs.py
@@ -0,0 +1,439 @@
+#!/usr/bin/env python3
+#
+# compare_dirs.py <path>
+#
+#
+# Compare the format subdirectories of <path> and report on which files do not appear
+# in all of them. If a directory has no files in it, then it is ignored.
+#
+# NOTE: This script was not designed for files in the "ef_format" file structure.
+
+import os
+import sys
+
+def compare_dirs(path, styles, formats, debug):
+ do_cdl = True if 'cdl' in formats else False
+ do_gds = True if 'gds' in formats else False
+ do_lef = True if 'lef' in formats else False
+ do_mag = True if 'mag' in formats else False
+ do_maglef = True if 'maglef' in formats else False
+ do_verilog = True if 'verilog' in formats else False
+
+ try:
+ d1 = os.listdir(path + '/cdl')
+ except:
+ d1 = []
+ d1e = list(item for item in d1 if os.path.splitext(item)[1] == '.cdl')
+ d1r = list(os.path.splitext(item)[0] for item in d1e)
+ try:
+ d2 = os.listdir(path + '/gds')
+ except:
+ d2 = []
+ d2e = list(item for item in d2 if os.path.splitext(item)[1] == '.gds')
+ d2r = list(os.path.splitext(item)[0] for item in d2e)
+ try:
+ d3 = os.listdir(path + '/lef')
+ except:
+ d3 = []
+ d3e = list(item for item in d3 if os.path.splitext(item)[1] == '.lef')
+ d3r = list(os.path.splitext(item)[0] for item in d3e)
+ try:
+ d4 = os.listdir(path + '/mag')
+ except:
+ d4 = []
+ d4e = list(item for item in d4 if os.path.splitext(item)[1] == '.mag')
+ d4r = list(os.path.splitext(item)[0] for item in d4e)
+ try:
+ d5 = os.listdir(path + '/maglef')
+ except:
+ d5 = []
+ d5e = list(item for item in d5 if os.path.splitext(item)[1] == '.mag')
+ d5r = list(os.path.splitext(item)[0] for item in d5e)
+ try:
+ d6 = os.listdir(path + '/verilog')
+ except:
+ d6 = []
+ d6e = list(item for item in d6 if os.path.splitext(item)[1] == '.v')
+ d6r = list(os.path.splitext(os.path.splitext(item)[0])[0] for item in d6e)
+
+ d1r.sort()
+ d2r.sort()
+ d3r.sort()
+ d4r.sort()
+ d5r.sort()
+ d6r.sort()
+
+ d1_2 = list(item for item in d1r if item not in d2r)
+ d1_3 = list(item for item in d1r if item not in d3r)
+ d1_4 = list(item for item in d1r if item not in d4r)
+ d1_5 = list(item for item in d1r if item not in d5r)
+ d1_6 = list(item for item in d1r if item not in d6r)
+
+ d2_1 = list(item for item in d2r if item not in d1r)
+ d2_3 = list(item for item in d2r if item not in d3r)
+ d2_4 = list(item for item in d2r if item not in d4r)
+ d2_5 = list(item for item in d2r if item not in d5r)
+ d2_6 = list(item for item in d2r if item not in d6r)
+
+ d3_1 = list(item for item in d3r if item not in d1r)
+ d3_2 = list(item for item in d3r if item not in d2r)
+ d3_4 = list(item for item in d3r if item not in d4r)
+ d3_5 = list(item for item in d3r if item not in d5r)
+ d3_6 = list(item for item in d3r if item not in d6r)
+
+ d4_1 = list(item for item in d4r if item not in d1r)
+ d4_2 = list(item for item in d4r if item not in d2r)
+ d4_3 = list(item for item in d4r if item not in d3r)
+ d4_5 = list(item for item in d4r if item not in d5r)
+ d4_6 = list(item for item in d4r if item not in d6r)
+
+ d5_1 = list(item for item in d5r if item not in d1r)
+ d5_2 = list(item for item in d5r if item not in d2r)
+ d5_3 = list(item for item in d5r if item not in d3r)
+ d5_4 = list(item for item in d5r if item not in d4r)
+ d5_6 = list(item for item in d5r if item not in d6r)
+
+ d6_1 = list(item for item in d6r if item not in d1r)
+ d6_2 = list(item for item in d6r if item not in d2r)
+ d6_3 = list(item for item in d6r if item not in d3r)
+ d6_4 = list(item for item in d6r if item not in d4r)
+ d6_5 = list(item for item in d6r if item not in d5r)
+
+ d_complete = []
+ if do_cdl:
+ d_complete.extend(list(item for item in d1r if item not in d_complete))
+ if do_gds:
+ d_complete.extend(list(item for item in d2r if item not in d_complete))
+ if do_lef:
+ d_complete.extend(list(item for item in d3r if item not in d_complete))
+ if do_mag:
+ d_complete.extend(list(item for item in d4r if item not in d_complete))
+ if do_maglef:
+ d_complete.extend(list(item for item in d5r if item not in d_complete))
+ if do_verilog:
+ d_complete.extend(list(item for item in d6r if item not in d_complete))
+
+ d_all = d_complete
+ if do_cdl:
+ d_all = list(item for item in d_all if item in d1r)
+ if do_gds:
+ d_all = list(item for item in d_all if item in d2r)
+ if do_lef:
+ d_all = list(item for item in d_all if item in d3r)
+ if do_mag:
+ d_all = list(item for item in d_all if item in d4r)
+ if do_maglef:
+ d_all = list(item for item in d_all if item in d5r)
+ if do_verilog:
+ d_all = list(item for item in d_all if item in d6r)
+
+ d_notall = list(item for item in d_complete if item not in d_all)
+
+ d_all.sort()
+ d_complete.sort()
+ d_notall.sort()
+
+ if debug:
+ print('Selected styles option: ' + ','.join(styles))
+ print('Selected formats option: ' + ','.join(formats))
+ print('\nd_complete = ' + ','.join(d_complete))
+ print('\nd_notall = ' + ','.join(d_notall) + '\n')
+
+ print('Library file type cross-correlation:' + '\n')
+
+ if 'allgood' in styles:
+ print('Cells appearing in all libraries:')
+ for cell in d_all.sort():
+ print(cell)
+
+ if 'cross' in styles:
+ # Print which cells appear in one format but not in another, for all format pairs
+ if do_cdl:
+ print('')
+ if do_gds and len(d1_2) > 0:
+ print('Cells appearing in cdl/ but not in gds/:')
+ for cell in d1_2:
+ print(cell)
+ if do_lef and len(d1_3) > 0:
+ print('Cells appearing in cdl/ but not in lef/:')
+ for cell in d1_3:
+ print(cell)
+ if do_mag and len(d1_4) > 0:
+ print('Cells appearing in cdl/ but not in mag/:')
+ for cell in d1_4:
+ print(cell)
+ if do_maglef and len(d1_5) > 0:
+ print('Cells appearing in cdl/ but not in maglef/:')
+ for cell in d1_5:
+ print(cell)
+ if do_verilog and len(d1_6) > 0:
+ print('Cells appearing in cdl/ but not in verilog/:')
+ for cell in d1_6:
+ print(cell)
+
+ if do_gds:
+ print('')
+ if do_cdl and len(d2_1) > 0:
+ print('Cells appearing in gds/ but not in cdl/:')
+ for cell in d2_1:
+ print(cell)
+ if do_lef and len(d2_3) > 0:
+ print('Cells appearing in gds/ but not in lef/:')
+ for cell in d2_3:
+ print(cell)
+ if do_mag and len(d2_4) > 0:
+ print('Cells appearing in gds/ but not in mag/:')
+ for cell in d2_4:
+ print(cell)
+ if do_maglef and len(d2_5) > 0:
+ print('Cells appearing in gds/ but not in maglef/:')
+ for cell in d2_5:
+ print(cell)
+ if do_verilog and len(d2_6) > 0:
+ print('Cells appearing in gds/ but not in verilog/:')
+ for cell in d2_6:
+ print(cell)
+
+ if do_lef:
+ print('')
+ if do_cdl and len(d3_1) > 0:
+ print('Cells appearing in lef/ but not in cdl/:')
+ for cell in d3_1:
+ print(cell)
+ if do_gds and len(d3_2) > 0:
+ print('Cells appearing in lef/ but not in gds/:')
+ for cell in d3_2:
+ print(cell)
+ if do_mag and len(d3_4) > 0:
+ print('Cells appearing in lef/ but not in mag/:')
+ for cell in d3_4:
+ print(cell)
+ if do_maglef and len(d3_5) > 0:
+ print('Cells appearing in lef/ but not in maglef/:')
+ for cell in d3_5:
+ print(cell)
+ if do_verilog and len(d3_6) > 0:
+ print('Cells appearing in lef/ but not in verilog/:')
+ for cell in d3_6:
+ print(cell)
+
+ if do_mag:
+ print('')
+ if do_cdl and len(d4_1) > 0:
+ print('Cells appearing in mag/ but not in cdl/:')
+ for cell in d4_1:
+ print(cell)
+ if do_gds and len(d4_2) > 0:
+ print('Cells appearing in mag/ but not in gds/:')
+ for cell in d4_2:
+ print(cell)
+ if do_lef and len(d4_3) > 0:
+ print('Cells appearing in mag/ but not in lef/:')
+ for cell in d4_3:
+ print(cell)
+ if do_maglef and len(d4_5) > 0:
+ print('Cells appearing in mag/ but not in maglef/:')
+ for cell in d4_5:
+ print(cell)
+ if do_verilog and len(d4_6) > 0:
+ print('Cells appearing in mag/ but not in verilog/:')
+ for cell in d4_6:
+ print(cell)
+
+ if do_maglef:
+ print('')
+ if do_cdl and len(d5_1) > 0:
+ print('Cells appearing in maglef/ but not in cdl/:')
+ for cell in d5_1:
+ print(cell)
+ if do_gds and len(d5_2) > 0:
+ print('Cells appearing in maglef/ but not in gds/:')
+ for cell in d5_2:
+ print(cell)
+ if do_lef and len(d5_3) > 0:
+ print('Cells appearing in maglef/ but not in lef/:')
+ for cell in d5_3:
+ print(cell)
+ if do_mag and len(d5_4) > 0:
+ print('Cells appearing in maglef/ but not in mag/:')
+ for cell in d5_4:
+ print(cell)
+ if do_verilog and len(d5_6) > 0:
+ print('Cells appearing in maglef/ but not in verilog/:')
+ for cell in d5_6:
+ print(cell)
+
+ if do_verilog:
+ print('')
+ if do_cdl and len(d6_1) > 0:
+ print('Cells appearing in verilog/ but not in cdl/:')
+ for cell in d6_1:
+ print(cell)
+ if do_gds and len(d6_2) > 0:
+ print('Cells appearing in verilog/ but not in gds/:')
+ for cell in d6_2:
+ print(cell)
+ if do_lef and len(d6_3) > 0:
+ print('Cells appearing in verilog/ but not in lef/:')
+ for cell in d6_3:
+ print(cell)
+ if do_mag and len(d6_4) > 0:
+ print('Cells appearing in verilog/ but not in mag/:')
+ for cell in d6_4:
+ print(cell)
+ if do_maglef and len(d6_5) > 0:
+ print('Cells appearing in verilog/ but not in maglef/:')
+ for cell in d6_5:
+ print(cell)
+
+ if 'cell' in styles:
+ # Print one cell per row, with list of formats per cell
+ for cell in d_complete:
+ informats = []
+ if do_cdl and cell in d1r:
+ informats.append('CDL')
+ if do_gds and cell in d2r:
+ informats.append('GDS')
+ if do_lef and cell in d3r:
+ informats.append('LEF')
+ if do_mag and cell in d4r:
+ informats.append('mag')
+ if do_maglef and cell in d5r:
+ informats.append('maglef')
+ if do_verilog and cell in d6r:
+ informats.append('verilog')
+ print(cell + ': ' + ','.join(informats))
+
+ if 'notcell' in styles:
+ # Print one cell per row, with list of missing formats per cell
+ for cell in d_complete:
+ informats = []
+ if do_cdl and cell not in d1r:
+ informats.append('CDL')
+ if do_gds and cell not in d2r:
+ informats.append('GDS')
+ if do_lef and cell not in d3r:
+ informats.append('LEF')
+ if do_mag and cell not in d4r:
+ informats.append('mag')
+ if do_maglef and cell not in d5r:
+ informats.append('maglef')
+ if do_verilog and cell not in d6r:
+ informats.append('verilog')
+ print(cell + ': ' + ','.join(informats))
+
+ if 'table' in styles:
+ cellnamelen = 0
+ for cell in d_complete:
+ if len(cell) > cellnamelen:
+ cellnamelen = len(cell)
+
+ # Print one cell per row, with list of formats per cell in tabular form
+ outline = 'cell'
+ outline += ' ' * (cellnamelen - 5)
+ fmtspc = 0
+ if do_cdl:
+ outline += ' CDL'
+ fmtspc += 4
+ if do_gds:
+ outline += ' GDS'
+ fmtspc += 4
+ if do_lef:
+ outline += ' LEF'
+ fmtspc += 4
+ if do_mag:
+ outline += ' mag'
+ fmtspc += 4
+ if do_maglef:
+ outline += ' maglef'
+ fmtspc += 7
+ if do_verilog:
+ outline += ' verilog'
+ fmtspc += 8
+ print(outline)
+ print('-' * (cellnamelen + fmtspc))
+ for cell in d_complete:
+ informats = []
+ outline = cell
+ outline += ' ' * (cellnamelen - len(cell))
+ if do_cdl:
+ if cell in d1r:
+ outline += ' X '
+ else:
+ outline += ' '
+ if do_gds:
+ if cell in d2r:
+ outline += ' X '
+ else:
+ outline += ' '
+ if do_lef:
+ if cell in d3r:
+ outline += ' X '
+ else:
+ outline += ' '
+ if do_mag:
+ if cell in d4r:
+ outline += ' X '
+ else:
+ outline += ' '
+ if do_maglef:
+ if cell in d5r:
+ outline += ' X '
+ else:
+ outline += ' '
+ if do_verilog:
+ if cell in d6r:
+ outline += ' X'
+ else:
+ outline += ' '
+ print(outline)
+ print('-' * (cellnamelen + fmtspc))
+
+def usage():
+ print('compare_dirs.py <path_to_dir> [-styles=<style_list>] [-debug] [-formats=<format_list>|"all"]')
+ print(' <format_list>: Comma-separated list of one or more of the following formats:')
+ print(' cdl, gds, lef, verilog, mag, maglef')
+ print(' <style_list>: Comma-separated list of one or more of the following styles:')
+ print(' allgood, cross, cell, notcell, table')
+ return 0
+
+if __name__ == '__main__':
+
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ if len(arguments) < 1:
+ print("Not enough options given to compare_dirs.py.")
+ usage()
+ sys.exit(0)
+
+ debug = True if '-debug' in options else False
+
+ allformats = ['cdl', 'gds', 'lef', 'mag', 'maglef', 'verilog']
+ allstyles = ['allgood', 'cross', 'cell', 'notcell', 'table']
+
+ formats = allformats
+ styles = ['table']
+
+ for option in options:
+ if '=' in option:
+ optpair = option.split('=')
+ if optpair[0] == '-styles' or optpair[0] == '-style':
+ if optpair[1] == 'all':
+ styles = allstyles
+ else:
+ styles = optpair[1].split(',')
+ elif optpair[0] == '-formats' or optpair[0] == '-format':
+ if optpair[1] == 'all':
+ formats = allformats
+ else:
+ formats = optpair[1].split(',')
+
+ path = arguments[0]
+ compare_dirs(path, styles, formats, debug)
+ sys.exit(0)
diff --git a/common/consoletext.py b/common/consoletext.py
new file mode 100755
index 0000000..03276fb
--- /dev/null
+++ b/common/consoletext.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+#
+#--------------------------------------------------------
+"""
+ consoletext --- extends tkinter class Text
+ with stdout and stderr redirection.
+"""
+#--------------------------------------------------------
+# Written by Tim Edwards
+# efabless, inc.
+# September 11, 2016
+# Version 0.1
+#--------------------------------------------------------
+
+import sys
+import tkinter
+
+class ConsoleText(tkinter.Text):
+ linelimit = 500
+ class IORedirector(object):
+ '''A general class for redirecting I/O to this Text widget.'''
+ def __init__(self,text_area):
+ self.text_area = text_area
+
+ class StdoutRedirector(IORedirector):
+ '''A class for redirecting stdout to this Text widget.'''
+ def write(self,str):
+ self.text_area.write(str,False)
+
+ class StderrRedirector(IORedirector):
+ '''A class for redirecting stderr to this Text widget.'''
+ def write(self,str):
+ self.text_area.write(str,True)
+
+ def __init__(self, master=None, cnf={}, **kw):
+ '''See the __init__ for Tkinter.Text.'''
+
+ tkinter.Text.__init__(self, master, cnf, **kw)
+
+ self.tag_configure('stdout',background='white',foreground='black')
+ self.tag_configure('stderr',background='white',foreground='red')
+ # None of these works! Cannot change selected text background!
+ self.config(selectbackground='blue', selectforeground='white')
+ self.tag_configure('sel',background='blue',foreground='white')
+
+ def write(self, val, is_stderr=False):
+ lines = int(self.index('end-1c').split('.')[0])
+ if lines > self.linelimit:
+ self.delete('1.0', str(lines - self.linelimit) + '.0')
+ self.insert('end',val,'stderr' if is_stderr else 'stdout')
+ self.see('end')
+
+ def limit(self, val):
+ self.linelimit = val
diff --git a/common/fixspice.py b/common/fixspice.py
new file mode 100755
index 0000000..a12ae42
--- /dev/null
+++ b/common/fixspice.py
@@ -0,0 +1,348 @@
+#!/bin/env python3
+#
+# fixspice ---
+#
+# This script fixes problems in SPICE models to make them ngspice-compatible.
+# The methods searched and corrected in this file correspond to ngspice
+# version 30.
+#
+# This script is a filter to be run by setting the name of this script as
+# the value to "filter=" for the model install in the PDK Makefile in
+# open_pdks.
+#
+# This script converted from the bash script by Risto Bell, with improvements.
+#
+# This script is minimally invasive to the original SPICE file, making changes
+# while preserving comments and line continuations. In order to properly parse
+# the file, comments and line continuations are recorded and removed from the
+# file contents, then inserted again before the modified file is written.
+
+import re
+import os
+import sys
+import textwrap
+
+def filter(inname, outname, debug=False):
+ notparsed = []
+
+ # Read input. Note that splitlines() performs the additional fix of
+ # correcting carriage-return linefeed (CRLF) line endings.
+ try:
+ with open(inname, 'r') as inFile:
+ spitext = inFile.read()
+ except:
+ print('fixspice.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
+ return 1
+ else:
+ if debug:
+ print('Fixing ngspice incompatibilities in file ' + inname + '.')
+
+ # Due to the complexity of comment lines embedded within continuation lines,
+ # the result needs to be processed line by line. Blank lines and comment
+ # lines are removed from the text, replaced with tab characters, and collected
+ # in a separate array. Then the continuation lines are unfolded, and each
+ # line processed. Then it is all put back together at the end.
+
+ # First replace all tabs with spaces so we can use tabs as markers.
+ spitext = spitext.replace('\t', ' ')
+
+ # Now do an initial line split
+ spilines = spitext.splitlines()
+
+ # Search lines for comments and blank lines and replace them with tabs
+ # Replace continuation lines with tabs and preserve the position.
+ spitext = ''
+ for line in spilines:
+ if len(line) == 0:
+ notparsed.append('\n')
+ spitext += '\t '
+ elif line[0] == '*':
+ notparsed.append('\n' + line)
+ spitext += '\t '
+ elif line[0] == '+':
+ notparsed.append('\n+')
+ spitext += '\t ' + line[1:]
+ else:
+ spitext += '\n' + line
+
+ # Now split back into an array of lines
+ spilines = spitext.splitlines()
+
+ # Process input with regexp
+
+ fixedlines = []
+ modified = False
+
+ # Regular expression to find 'agauss(a,b,c)' lines and record a, b, and c
+ grex = re.compile('[^{]agauss\(([^,]*),([^,]*),([^)]*)\)', re.IGNORECASE)
+
+ # Regular expression to determine if the line is a .PARAM card
+ paramrex = re.compile('^\.param', re.IGNORECASE)
+ # Regular expression to determine if the line is a .MODEL card
+ modelrex = re.compile('^\.model', re.IGNORECASE)
+ # Regular expression to detect a .SUBCKT card
+ subcktrex = re.compile('^\.subckt', re.IGNORECASE)
+
+ for line in spilines:
+ devtype = line[0].upper() if len(line) > 0 else 0
+
+ # NOTE: All filter functions below take variable fixedline, alter it, then
+ # set fixedline to the altered text for the next filter function.
+
+ fixedline = line
+
+ # Fix: Wrap "agauss(...)" in brackets and remove single quotes around expressions
+ # Example:
+ # before: + SD_DN_CJ=agauss(7.900e-04,'1.580e-05*__LOT__',1) dn_cj=SD_DN_CJ"
+ # after: + SD_DN_CJ={agauss(7.900e-04,1.580e-05*__LOT__,1)} dn_cj=SD_DN_CJ"
+
+ # for gmatch in grex.finditer(fixedline):
+ while True:
+ gmatch = grex.search(fixedline)
+ if gmatch:
+ fixpart1 = gmatch.group(1).strip("'")
+ fixpart2 = gmatch.group(2).strip("'")
+ fixpart3 = gmatch.group(3).strip("'")
+ fixedline = fixedline[0:gmatch.span(0)[0] + 1] + '{agauss(' + fixpart1 + ',' + fixpart2 + ',' + fixpart3 + ')}' + fixedline[gmatch.span(0)[1]:]
+ if debug:
+ print('Fixed agauss() call.')
+ else:
+ break
+
+ # Fix: Check for "dtemp=dtemp" and remove unless in a .param line
+ pmatch = paramrex.search(fixedline)
+ if not pmatch:
+ altered = re.sub(' dtemp=dtemp', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed dtemp=dtemp from instance call')
+
+ # Fixes related to .MODEL cards:
+
+ mmatch = modelrex.search(fixedline)
+ if mmatch:
+
+ modeltype = fixedline.split()[2].lower()
+
+ if modeltype == 'nmos' or modeltype == 'pmos':
+
+ # Fixes related specifically to MOS models:
+
+ # Fix: Look for hspver=98.2 in FET model
+ altered = re.sub(' hspver[ ]*=[ ]*98\.2', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed hspver=98.2 from ' + modeltype + ' model')
+
+ # Fix: Change level 53 FETs to level 49
+ altered = re.sub(' (level[ ]*=[ ]*)53', ' \g<1>49', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Changed level 53 ' + modeltype + ' to level 49')
+
+ # Fix: Look for version=4.3 or 4.5 FETs, change to 4.8.0 per recommendations
+ altered = re.sub(' (version[ ]*=[ ]*)4\.[35]', ' \g<1>4.8.0',
+ fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Changed version 4.3/4.5 ' + modeltype + ' to version 4.8.0')
+
+ # Fix: Look for mulu0= (NOTE: Might be supported for bsim4?)
+ altered = re.sub('mulu0[ ]*=[ ]*[0-9.e+-]*', '', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed mulu0= from ' + modeltype + ' model')
+
+ # Fix: Look for apwarn=
+ altered = re.sub(' apwarn[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed apwarn= from ' + modeltype + ' model')
+
+ # Fix: Look for lmlt=
+ altered = re.sub(' lmlt[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed lmlt= from ' + modeltype + ' model')
+
+ # Fix: Look for nf=
+ altered = re.sub(' nf[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed nf= from ' + modeltype + ' model')
+
+ # Fix: Look for sa/b/c/d/=
+ altered = re.sub(' s[abcd][ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed s[abcd]= from ' + modeltype + ' model')
+
+ # Fix: Look for binflag= in MOS .MODEL
+ altered = re.sub(' binflag[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed binflag= from ' + modeltype + ' model')
+
+ # Fix: Look for wref, lref= in MOS .MODEL (note: could be found in other models?)
+ altered = re.sub(' [wl]ref[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed lref= from MOS .MODEL')
+
+ # TREF is a known issue for (apparently?) all device types
+ # Fix: Look for tref= in .MODEL
+ altered = re.sub(' tref[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed tref= from ' + modeltype + ' model')
+
+ # Fix: Look for double-dot model binning and replace with single dot
+ altered = re.sub('\.\.([0-9]+)', '.\g<1>', fixedline, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Collapsed double-dot model binning.')
+
+ # Various deleted parameters above may appear in instances, so those must be
+ # caught as well. Need to catch expressions and variables in addition to the
+ # usual numeric assignments.
+
+ if devtype == 'M':
+ altered = re.sub(' nf=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
+ altered = re.sub(' nf=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed nf= from MOSFET device instance')
+
+ altered = re.sub(' mulu0=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
+ altered = re.sub(' mulu0=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed mulu0= from MOSFET device instance')
+
+ altered = re.sub(' s[abcd]=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
+ altered = re.sub(' s[abcd]=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed s[abcd]= from MOSFET device instance')
+
+ # Remove tref= from all device type instances
+ altered = re.sub(' tref=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
+ altered = re.sub(' tref=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Removed tref= from device instance')
+
+ # Check for use of ".subckt ... <name>=l" (or <name>=w) with no antecedent
+ # for 'w' or 'l'. It is the responsibility of the technology file for extraction
+ # to produce the correct name to pass to the subcircuit for length or width.
+
+ smatch = subcktrex.match(fixedline)
+ if smatch:
+ altered = fixedline
+ if fixedline.lower().endswith('=l'):
+ if ' l=' not in fixedline.lower():
+ altered=re.sub( '=l$', '=0', fixedline, flags=re.IGNORECASE)
+ elif '=l ' in fixedline.lower():
+ if ' l=' not in fixedline.lower():
+ altered=re.sub( '=l ', '=0 ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Replaced use of "l" with no definition in .subckt line')
+
+ altered = fixedline
+ if fixedline.lower().endswith('=w'):
+ if ' w=' not in fixedline.lower():
+ altered=re.sub( '=w$', '=0', fixedline, flags=re.IGNORECASE)
+ elif '=w ' in fixedline.lower():
+ if ' w=' not in fixedline.lower():
+ altered=re.sub( '=w ', '=0 ', altered, flags=re.IGNORECASE)
+ if altered != fixedline:
+ fixedline = altered
+ if debug:
+ print('Replaced use of "w" with no definition in .subckt line')
+
+ fixedlines.append(fixedline)
+ if fixedline != line:
+ modified = True
+
+ # Reinsert embedded comments and continuation lines
+ if debug:
+ print('Reconstructing output')
+ olines = []
+ for line in fixedlines:
+ while '\t ' in line:
+ line = line.replace('\t ', notparsed.pop(0), 1)
+ olines.append(line)
+
+ fixedlines = '\n'.join(olines).strip()
+ olines = fixedlines.splitlines()
+
+ # Write output
+ if debug:
+ print('Writing output')
+ if outname == None:
+ for line in olines:
+ print(line)
+ else:
+ # If the output is a symbolic link but no modifications have been made,
+ # then leave it alone. If it was modified, then remove the symbolic
+ # link before writing.
+ if os.path.islink(outname):
+ if not modified:
+ return 0
+ else:
+ os.unlink(outname)
+ try:
+ with open(outname, 'w') as outFile:
+ for line in olines:
+ print(line, file=outFile)
+ except:
+ print('fixspice.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
+ return 1
+
+
+if __name__ == '__main__':
+
+ # This script expects to get one or two arguments. One argument is
+ # mandatory and is the input file. The other argument is optional and
+ # is the output file. The output file and input file may be the same
+ # name, in which case the original input is overwritten.
+
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item[1:])
+ else:
+ arguments.append(item)
+
+ if len(arguments) > 0:
+ infilename = arguments[0]
+
+ if len(arguments) > 1:
+ outfilename = arguments[1]
+ else:
+ outfilename = None
+
+ debug = True if 'debug' in options else False
+
+ result = filter(infilename, outfilename, debug)
+ sys.exit(result)
diff --git a/common/foundry_install.py b/common/foundry_install.py
new file mode 100755
index 0000000..2067663
--- /dev/null
+++ b/common/foundry_install.py
@@ -0,0 +1,2376 @@
+#!/usr/bin/env python3
+#
+# foundry_install.py
+#
+# This file generates the local directory structure and populates the
+# directories with foundry vendor data. The local directory (target)
+# should be a staging area, not a place where files are kept permanently.
+#
+# Options:
+# -ef_format Use efabless naming (libs.ref/techLEF),
+# otherwise use generic naming (libs.tech/lef)
+# -clean Clear out and remove target directory before starting
+# -source <path> Path to source data top level directory
+# -target <path> Path to target (staging) top level directory
+#
+# All other options represent paths to vendor files. They may all be
+# wildcarded with "*", or with specific escapes like "%l" for library
+# name or "%v" for version number (see below for a complete list of escape
+# sequences).
+#
+# Note only one of "-spice" or "-cdl" need be specified. Since the
+# open source tools use ngspice, CDL files are converted to ngspice
+# syntax when needed.
+#
+# -techlef <path> Path to technology LEF file
+# -doc <path> Path to technology documentation
+# -lef <path> Path to LEF file
+# -spice <path> Path to SPICE netlists
+# -cdl <path> Path to CDL netlists
+# -models <path> Path to SPICE (primitive device) models
+# -liberty <path> Path to Liberty timing files
+# -gds <path> Path to GDS data
+# -verilog <path> Path to verilog models
+#
+# -library <type> <name> [<target>] See below
+#
+# For the "-library" option, any number of libraries may be supported, and
+# one "-library" option should be provided for each supported library.
+# <type> is one of: "digital", "primitive", or "general". Analog and I/O
+# libraries fall under the category "general", as they are all treated the
+# same way. <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).
+#
+# In special cases using options (see below), path may be "-", indicating
+# that there are no source files, but only to run compilations or conversions
+# on the files in the target directory.
+#
+# All options "-lef", "-spice", etc., can take the additional arguments
+# up <number>
+#
+# to indicate that the source hierarchy should be copied from <number>
+# levels above the files. 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
+# (if "-ef_format" option specified, then: 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
+# (if "-ef_format" option specified, then: libs.ref/<libname>/liberty/PVT_*/*.lib)
+#
+# Please 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.
+#
+# Other library-specific arguments are:
+#
+# nospec : Remove timing specification before installing
+# (used with verilog files; needs to 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.
+# stub : Remove contents of subcircuits from CDL or SPICE
+# netlist files.
+#
+# 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.
+#
+# exclude : Followed by "=" and a comma-separated list of names.
+# exclude these files/modules/subcircuits. Names may
+# also be wildcarded in "glob" format.
+#
+# rename : Followed by "=" and an alternative name. For any
+# file that is a single entry, change the name of
+# the file in the target directory to this (To-do:
+# take regexps for multiple files). When used with
+# "compile" or "compile-only", this refers to the
+# name of the target compiled file.
+#
+# noconvert : Install only; do not attempt to convert to other
+# formats (applies only to GDS, CDL, and LEF).
+#
+# NOTE: This script can be called once for all libraries if all file
+# types (gds, cdl, lef, etc.) happen to all work with the same wildcards.
+# However, it is more likely that it will be called several times for the
+# same PDK, once to install I/O cells, once to install digital, and so
+# forth, as made possible by the wild-carding.
+
+import re
+import os
+import sys
+import glob
+import stat
+import shutil
+import fnmatch
+import subprocess
+
+def usage():
+ print("foundry_install.py [options...]")
+ print(" -copy Copy files from source to target (default)")
+ print(" -ef_format Use efabless naming conventions for local directories")
+ print("")
+ print(" -source <path> Path to top of source directory tree")
+ print(" -target <path> Path to top of target directory tree")
+ print("")
+ print(" -techlef <path> Path to technology LEF file")
+ print(" -doc <path> Path to technology documentation")
+ print(" -lef <path> Path to LEF file")
+ print(" -spice <path> Path to SPICE netlists")
+ print(" -cdl <path> Path to CDL netlists")
+ print(" -models <path> Path to SPICE (primitive device) models")
+ print(" -lib <path> Path to Liberty timing files")
+ print(" -liberty <path> Path to Liberty timing files")
+ print(" -gds <path> Path to GDS data")
+ print(" -verilog <path> Path to verilog models")
+ print(" -library <type> <name> [<target>] See below")
+ print("")
+ print(" All <path> names may be wild-carded with '*' ('glob'-style wild-cards)")
+ print("")
+ print(" All options with <path> other than source and target may take the additional")
+ print(" arguments 'up <number>', where <number> indicates the number of levels of")
+ print(" hierarchy of the source path to include when copying to the target.")
+ print("")
+ print(" Library <type> may be one of:")
+ print(" digital Digital standard cell library")
+ print(" primitive Primitive device library")
+ print(" general All other library types (I/O, analog, etc.)")
+ print("")
+ print(" If <target> is unspecified then <name> is used for the target.")
+
+# Return a list of files after glob-style substituting into pathname. This
+# mostly relies on glob.glob(), but uses the additional substitutions with
+# escape strings:
+#
+# %v : Match a version number in the form "major[.minor[.rev]]"
+# %l : substitute the library name
+# %% : substitute the percent character verbatim
+
+from distutils.version import LooseVersion
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+
+def makeuserwritable(filepath):
+ if os.path.exists(filepath):
+ st = os.stat(filepath)
+ os.chmod(filepath, st.st_mode | stat.S_IWUSR)
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+
+def substitute(pathname, library):
+ if library:
+ # Do %l substitution
+ newpathname = re.sub('%l', library, pathname)
+ else:
+ newpathname = pathname
+
+ if '%v' in newpathname:
+ vglob = re.sub('%v.*', '*', newpathname)
+ vlibs = glob.glob(vglob)
+ try:
+ vstr = vlibs[0][len(vglob)-1:]
+ except IndexError:
+ pass
+ else:
+ for vlib in vlibs[1:]:
+ vtest = vlib[len(vglob)-1:]
+ if LooseVersion(vtest) > LooseVersion(vstr):
+ vstr = vtest
+ newpathname = re.sub('%v', vstr, newpathname)
+
+ if '%%' in newpathname:
+ newpathname = re.sub('%%', '%', newpathname)
+
+ return newpathname
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+
+def get_gds_properties(magfile):
+ proprex = re.compile('^[ \t]*string[ \t]+(GDS_[^ \t]+)[ \t]+([^ \t]+)$')
+ proplines = []
+ if os.path.isfile(magfile):
+ with open(magfile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+ for line in magtext:
+ lmatch = proprex.match(line)
+ if lmatch:
+ propline = lmatch.group(1) + ' ' + lmatch.group(2)
+ proplines.append(propline)
+ return proplines
+
+#----------------------------------------------------------------------------
+# Read subcircuit ports from a CDL file, given a subcircuit name that should
+# appear in the file as a subcircuit entry, and return a dictionary of ports
+# and their indexes in the subcircuit line.
+#----------------------------------------------------------------------------
+
+def get_subckt_ports(cdlfile, subname):
+ portdict = {}
+ pidx = 1
+ portrex = re.compile('^\.subckt[ \t]+([^ \t]+)[ \t]+(.*)$', flags=re.IGNORECASE)
+ with open(cdlfile, 'r') as ifile:
+ cdltext = ifile.read()
+ cdllines = cdltext.replace('\n+', ' ').splitlines()
+ for line in cdllines:
+ lmatch = portrex.match(line)
+ if lmatch:
+ if lmatch.group(1).lower() == subname.lower():
+ ports = lmatch.group(2).split()
+ for port in ports:
+ portdict[port.lower()] = pidx
+ pidx += 1
+ break
+ return portdict
+
+#----------------------------------------------------------------------------
+# Filter a verilog file to remove any backslash continuation lines, which
+# iverilog does not parse. If targetroot is a directory, then find and
+# process all files in the path of targetroot. If any file to be processed
+# is unmodified (has no backslash continuation lines), then ignore it. If
+# any file is a symbolic link and gets modified, then remove the symbolic
+# link before overwriting with the modified file.
+#----------------------------------------------------------------------------
+
+def vfilefilter(vfile):
+ modified = False
+ with open(vfile, 'r') as ifile:
+ vtext = ifile.read()
+
+ # Remove backslash-followed-by-newline and absorb initial whitespace. It
+ # is unclear what initial whitespace means in this context, as the use-
+ # case that has been seen seems to work under the assumption that leading
+ # whitespace is ignored up to the amount used by the last indentation.
+
+ vlines = re.sub('\\\\\n[ \t]*', '', vtext)
+
+ if vlines != vtext:
+ # File contents have been modified, so if this file was a symbolic
+ # link, then remove it. Otherwise, overwrite the file with the
+ # modified contents.
+ if os.path.islink(vfile):
+ os.unlink(vfile)
+ with open(vfile, 'w') as ofile:
+ ofile.write(vlines)
+
+#----------------------------------------------------------------------------
+# Run a filter on verilog files that cleans up known syntax issues.
+# This is embedded in the foundry_install script and is not a custom
+# filter largely because the issue is in the tool, not the PDK.
+#----------------------------------------------------------------------------
+
+def vfilter(targetroot):
+ if os.path.isfile(targetroot):
+ vfilefilter(targetroot)
+ else:
+ vlist = glob.glob(targetroot + '/*')
+ for vfile in vlist:
+ if os.path.isfile(vfile):
+ vfilefilter(vfile)
+
+#----------------------------------------------------------------------------
+# For issues that are PDK-specific, a script can be written and put in
+# the PDK's custom/scripts/ directory, and passed to the foundry_install
+# script using the "filter" option.
+#----------------------------------------------------------------------------
+
+def tfilter(targetroot, filterscript, outfile=[]):
+ filterroot = os.path.split(filterscript)[1]
+ if os.path.isfile(targetroot):
+ print(' Filtering file ' + targetroot + ' with ' + filterroot)
+ sys.stdout.flush()
+ if not outfile:
+ outfile = targetroot
+ else:
+ # Make sure this file is writable (as the original may not be)
+ makeuserwritable(outfile)
+
+ fproc = subprocess.run([filterscript, targetroot, outfile],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+ if fproc.stdout:
+ for line in fproc.stdout.splitlines():
+ print(line)
+ if fproc.stderr:
+ print('Error message output from filter script:')
+ for line in fproc.stderr.splitlines():
+ print(line)
+
+ else:
+ tlist = glob.glob(targetroot + '/*')
+ for tfile in tlist:
+ if os.path.isfile(tfile):
+ print(' Filtering file ' + tfile + ' with ' + filterroot)
+ sys.stdout.flush()
+ fproc = subprocess.run([filterscript, tfile, tfile],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+ if fproc.stdout:
+ for line in fproc.stdout.splitlines():
+ print(line)
+ if fproc.stderr:
+ print('Error message output from filter script:')
+ for line in fproc.stderr.splitlines():
+ print(line)
+
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual verilog files of a number
+# of modules, create a single verilog library file named <alllibname> and place
+# it in the same directory. This is done for the option "compile" if specified
+# for the "-verilog" install.
+#----------------------------------------------------------------------------
+
+def create_verilog_library(destlibdir, destlib, do_compile_only, do_stub, excludelist):
+
+ alllibname = destlibdir + '/' + destlib + '.v'
+ if os.path.isfile(alllibname):
+ os.remove(alllibname)
+
+ print('Diagnostic: Creating consolidated verilog library ' + destlib + '.v')
+ vlist = glob.glob(destlibdir + '/*.v')
+ if alllibname in vlist:
+ vlist.remove(alllibname)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(vlist) > 0:
+ vlistnames = list(os.path.split(item)[1] for item in vlist)
+ notvlist = []
+ for exclude in excludelist:
+ notvlist.extend(fnmatch.filter(vlistnames, exclude))
+
+ # Apply exclude list
+ if len(notvlist) > 0:
+ for file in vlist[:]:
+ if os.path.split(file)[1] in notvlist:
+ vlist.remove(file)
+
+ if len(vlist) > 1:
+ print('New file is: ' + alllibname)
+ with open(alllibname, 'w') as ofile:
+ allmodules = []
+ for vfile in vlist:
+ with open(vfile, 'r') as ifile:
+ # print('Adding ' + vfile + ' to library.')
+ vtext = ifile.read()
+ modules = re.findall(r'[ \t\n]module[ \t]+([^ \t\n\(]+)', vtext)
+ mseen = list(item for item in modules if item in allmodules)
+ allmodules.extend(list(item for item in modules if item not in allmodules))
+ vfilter = remove_redundant_modules(vtext, allmodules, mseen)
+ # NOTE: The following workaround resolves an issue with iverilog,
+ # which does not properly parse specify timing paths that are not in
+ # parentheses. Easy to work around
+ vlines = re.sub(r'\)[ \t]*=[ \t]*([01]:[01]:[01])[ \t]*;', r') = ( \1 ) ;', vfilter)
+ print(vlines, file=ofile)
+ print('\n//--------EOF---------\n', file=ofile)
+
+ if do_compile_only == True:
+ print('Compile-only: Removing individual verilog files')
+ for vfile in vlist:
+ if os.path.isfile(vfile):
+ os.remove(vfile)
+ elif os.path.islink(vfile):
+ os.unlink(vfile)
+ else:
+ print('Only one file (' + str(vlist) + '); ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Remove redundant module entries from a verilog file. "m2list" is a list of
+# module names gleaned from all previously read files using re.findall().
+# "mlist" is a list of all module names including those in "ntext".
+# The reason for doing this is that some verilog files may includes modules used
+# by all the files, and if included more than once, then iverilog complains.
+#----------------------------------------------------------------------------
+
+def remove_redundant_modules(ntext, mlist, m2list):
+ updated = ntext
+ for module in mlist:
+ # Determine the number of times the module appears in the text
+ if module in m2list:
+ # This module seen before outside of ntext, so remove all occurrances in ntext
+ new = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', '\n', updated, flags=re.DOTALL)
+ updated = new
+
+ else:
+ n = len(re.findall(r'[ \t\n]module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', updated, flags=re.DOTALL))
+ # This module defined more than once inside ntext, so remove all but one
+ # Optimization: Just keep original text if n < 2
+ if n < 2:
+ continue
+
+ # Remove all but one
+ updated = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n]+.*[ \t\n]endmodule', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
+ return updated
+
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual LEF files of a number
+# of cells, create a single LEF library file named <alllibname> and place
+# it in the same directory. This is done for the option "compile" if specified
+# for the "-lef" install.
+#----------------------------------------------------------------------------
+
+def create_lef_library(destlibdir, destlib, do_compile_only, excludelist):
+
+ alllibname = destlibdir + '/' + destlib + '.lef'
+ if os.path.isfile(alllibname):
+ os.remove(alllibname)
+
+ print('Diagnostic: Creating consolidated LEF library ' + destlib + '.lef')
+ llist = glob.glob(destlibdir + '/*.lef')
+ if alllibname in llist:
+ llist.remove(alllibname)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(llist) > 0:
+ llistnames = list(os.path.split(item)[1] for item in llist)
+ notllist = []
+ for exclude in excludelist:
+ notllist.extend(fnmatch.filter(llistnames, exclude))
+
+ # Apply exclude list
+ if len(notllist) > 0:
+ for file in llist[:]:
+ if os.path.split(file)[1] in notllist:
+ llist.remove(file)
+
+ if len(llist) > 1:
+ print('New file is: ' + alllibname)
+ with open(alllibname, 'w') as ofile:
+ headerdone = False
+ for lfile in llist:
+ with open(lfile, 'r') as ifile:
+ # print('Adding ' + lfile + ' to library.')
+ ltext = ifile.read()
+ llines = ltext.splitlines()
+ headerseen = False
+ for lline in llines:
+ if headerdone:
+ if not headerseen:
+ if not lline.startswith('MACRO'):
+ continue
+ else:
+ headerseen = True
+ print(lline, file=ofile)
+ headerdone = True
+ print('#--------EOF---------\n', file=ofile)
+
+ if do_compile_only == True:
+ print('Compile-only: Removing individual LEF files')
+ for lfile in llist:
+ if os.path.isfile(lfile):
+ os.remove(lfile)
+ if newname:
+ if os.path.isfile(newname):
+ os.remove(newname)
+ else:
+ print('Only one file (' + str(llist) + '); ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual liberty files of a number
+# of cells, create a single liberty library file named <alllibname> and place
+# it in the same directory. This is done for the option "compile" if specified
+# for the "-lib" install.
+#----------------------------------------------------------------------------
+
+# Warning: This script is unfinished. Needs to parse the library header
+# in each cell and generate a new library header combining the contents of
+# all cell headers. Also: The library name in the header needs to be
+# changed to the full library name. Also: There is no mechanism for
+# collecting all files belonging to a single process corner/temperature/
+# voltage.
+
+def create_lib_library(destlibdir, destlib, do_compile_only, excludelist):
+
+ alllibname = destlibdir + '/' + destlib + '.lib'
+ if os.path.isfile(alllibname):
+ os.remove(alllibname)
+
+ print('Diagnostic: Creating consolidated liberty library ' + destlib + '.lib')
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(llist) > 0:
+ llistnames = list(os.path.split(item)[1] for item in llist)
+ notllist = []
+ for exclude in excludelist:
+ notllist.extend(fnmatch.filter(llistnames, exclude))
+
+ # Apply exclude list
+ if len(notllist) > 0:
+ for file in llist[:]:
+ if os.path.split(file)[1] in notllist:
+ llist.remove(file)
+
+ if len(llist) > 1:
+ print('New file is: ' + alllibname)
+ with open(alllibname, 'w') as ofile:
+ headerdone = False
+ for lfile in llist:
+ with open(lfile, 'r') as ifile:
+ # print('Adding ' + lfile + ' to library.')
+ ltext = ifile.read()
+ llines = ltext.splitlines()
+ headerseen = False
+ for lline in llines:
+ if headerdone:
+ if not headerseen:
+ if not lline.split()[0] == 'cell':
+ continue
+ else:
+ headerseen = True
+ print(lline, file=ofile)
+ headerdone = True
+ print('/*--------EOF---------*/\n', file=ofile)
+
+ if do_compile_only == True:
+ print('Compile-only: Removing individual LEF files')
+ for lfile in llist:
+ if os.path.isfile(lfile):
+ os.remove(lfile)
+ if newname:
+ if os.path.isfile(newname):
+ os.remove(newname)
+ else:
+ print('Only one file (' + str(llist) + '); ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual GDS files of a number
+# of cells, create a single GDL library file named <alllibname> and place
+# it in the same directory. This is done for the option "compile" if specified
+# for the "-gds" install.
+#----------------------------------------------------------------------------
+
+def create_gds_library(destlibdir, destlib, startup_script, do_compile_only, excludelist):
+
+ alllibname = destlibdir + '/' + destlib + '.gds'
+ if os.path.isfile(alllibname):
+ os.remove(alllibname)
+
+ print('Diagnostic: Creating consolidated GDS library ' + destlib + '.gds')
+ glist = glob.glob(destlibdir + '/*.gds')
+ glist.extend(glob.glob(destlibdir + '/*.gdsii'))
+ glist.extend(glob.glob(destlibdir + '/*.gds2'))
+ if alllibname in glist:
+ glist.remove(alllibname)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(glist) > 0:
+ glistnames = list(os.path.split(item)[1] for item in glist)
+ notglist = []
+ for exclude in excludelist:
+ notglist.extend(fnmatch.filter(glistnames, exclude))
+
+ # Apply exclude list
+ if len(notglist) > 0:
+ for file in glist[:]:
+ if os.path.split(file)[1] in notglist:
+ glist.remove(file)
+
+ if len(glist) > 1:
+ print('New file is: ' + alllibname)
+
+ if os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # A GDS library is binary and requires handling in Magic
+ print('Creating magic generation script to generate GDS library.')
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('# Script to generate .gds library from files ', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('drc off', file=ofile)
+ print('gds readonly true', file=ofile)
+ print('gds flatten true', file=ofile)
+ print('gds rescale false', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ for gdsfile in glist:
+ print('gds read ' + gdsfile, file=ofile)
+
+ print('puts stdout "Creating cell ' + destlib + '"', file=ofile)
+ print('load ' + destlib, file=ofile)
+ print('puts stdout "Adding cells to library"', file=ofile)
+ print('box values 0 0 0 0', file=ofile)
+ for gdsfile in glist:
+ gdsroot = os.path.split(gdsfile)[1]
+ gdsname = os.path.splitext(gdsroot)[0]
+ print('getcell ' + gdsname, file=ofile)
+ # Could properly make space for the cell here. . .
+ print('box move e 200', file=ofile)
+
+ print('puts stdout "Writing GDS file ' + destlib + '"', file=ofile)
+ print('gds write ' + destlib, file=ofile)
+ print('puts stdout "Done."', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ # Run magic to read in the individual GDS files and
+ # write out the consolidated GDS library
+
+ print('Running magic to create GDS library.')
+ sys.stdout.flush()
+
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+ destlibdir + '/generate_magic.tcl'],
+ stdin = subprocess.DEVNULL,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+ if do_compile_only == True:
+ print('Compile-only: Removing individual GDS files')
+ for gfile in glist:
+ if os.path.isfile(gfile):
+ os.remove(gfile)
+ if newname:
+ if os.path.isfile(newname):
+ os.remove(newname)
+ else:
+ print('Only one file (' + str(glist) + '); ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Given a destination directory holding individual SPICE netlists of a number
+# of cells, create a single SPICE library file named <alllibname> and place
+# it in the same directory. This is done for the option "compile" if specified
+# for the "-spice" install.
+#----------------------------------------------------------------------------
+
+def create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist):
+
+ fformat = 'CDL' if spiext == '.cdl' else 'SPICE'
+
+ allstubname = destlibdir + '/stub' + spiext
+ alllibname = destlibdir + '/' + destlib + spiext
+ if do_stub:
+ outputname = allstubname
+ else:
+ outputname = alllibname
+
+ print('Diagnostic: Creating consolidated ' + fformat + ' library ' + outputname)
+
+ if os.path.isfile(outputname):
+ os.remove(outputname)
+
+ if fformat == 'CDL':
+ slist = glob.glob(destlibdir + '/*.cdl')
+ else:
+ # Sadly, there is no consensus on what a SPICE file extension should be.
+ slist = glob.glob(destlibdir + '/*.spc')
+ slist.extend(glob.glob(destlibdir + '/*.spice'))
+ slist.extend(glob.glob(destlibdir + '/*.spi'))
+ slist.extend(glob.glob(destlibdir + '/*.ckt'))
+
+ if alllibname in slist:
+ slist.remove(alllibname)
+
+ if allstubname in slist:
+ slist.remove(allstubname)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(slist) > 0:
+ slistnames = list(os.path.split(item)[1] for item in slist)
+ notslist = []
+ for exclude in excludelist:
+ notslist.extend(fnmatch.filter(slistnames, exclude))
+
+ # Apply exclude list
+ if len(notslist) > 0:
+ for file in slist[:]:
+ if os.path.split(file)[1] in notslist:
+ slist.remove(file)
+
+ if len(slist) > 1:
+ with open(outputname, 'w') as ofile:
+ allsubckts = []
+ for sfile in slist:
+ with open(sfile, 'r') as ifile:
+ # print('Adding ' + sfile + ' to library.')
+ stext = ifile.read()
+ subckts = re.findall(r'\.subckt[ \t]+([^ \t\n]+)', stext, flags=re.IGNORECASE)
+ sseen = list(item for item in subckts if item in allsubckts)
+ allsubckts.extend(list(item for item in subckts if item not in allsubckts))
+ sfilter = remove_redundant_subckts(stext, allsubckts, sseen)
+ print(sfilter, file=ofile)
+ print('\n******* EOF\n', file=ofile)
+
+ if do_compile_only == True:
+ print('Compile-only: Removing individual SPICE files')
+ for sfile in slist:
+ if os.path.isfile(sfile):
+ os.remove(sfile)
+ elif os.path.islink(sfile):
+ os.unlink(sfile)
+ else:
+ print('Only one file (' + str(slist) + '); ignoring "compile" option.')
+
+#----------------------------------------------------------------------------
+# Remove redundant subcircuit entries from a SPICE or CDL netlist file. "sseen"
+# is a list of subcircuit names gleaned from all previously read files using
+# re.findall(). "slist" is a list of subcircuits including those in "ntext".
+# If a subcircuit is defined outside of "ntext", then remove all occurrences in
+# "ntext". Otherwise, if a subcircuit is defined more than once in "ntext",
+# remove all but one copy. The reason for doing this is that some netlists will
+# include primitive device definitions used by all the standard cell subcircuits.
+#
+# It may be necessary to remove redundant .include statements and redundant .model
+# and/or .option statements as well.
+#----------------------------------------------------------------------------
+
+def remove_redundant_subckts(ntext, slist, sseen):
+ updated = ntext
+ for subckt in slist:
+ if subckt in sseen:
+ # Remove all occurrences of subckt
+ updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', updated, flags=re.IGNORECASE | re.DOTALL)
+
+ else:
+ # Determine the number of times the subcircuit appears in the text
+ n = len(re.findall(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', updated, flags=re.IGNORECASE | re.DOTALL))
+ # Optimization: Just keep original text if n < 2
+ if n < 2:
+ continue
+
+ # Remove all but one
+ updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
+ return updated
+
+#----------------------------------------------------------------------------
+# This is the main entry point for the foundry install script.
+#----------------------------------------------------------------------------
+
+if __name__ == '__main__':
+
+ if len(sys.argv) == 1:
+ print("No options given to foundry_install.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ newopt = []
+
+ sourcedir = None
+ targetdir = None
+
+ ef_format = False
+ do_clean = False
+
+ have_lef = False
+ have_techlef = False
+ have_lefanno = False
+ have_gds = False
+ have_spice = False
+ have_cdl = False
+ have_verilog = False
+ have_lib = False
+
+ # Break arguments into groups where the first word begins with "-".
+ # All following words not beginning with "-" are appended to the
+ # same list (optionlist). Then each optionlist is processed.
+ # Note that the first entry in optionlist has the '-' removed.
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ if newopt != []:
+ optionlist.append(newopt)
+ newopt = []
+ newopt.append(option[1:])
+ else:
+ newopt.append(option)
+
+ if newopt != []:
+ optionlist.append(newopt)
+
+ # Pull library names from optionlist
+ libraries = []
+ for option in optionlist[:]:
+ if option[0] == 'library':
+ optionlist.remove(option)
+ libraries.append(option[1:])
+
+ # Check for option "ef_format" or "std_format" or "clean"
+ for option in optionlist[:]:
+ if option[0] == 'ef_naming' or option[0] == 'ef_names' or option[0] == 'ef_format':
+ optionlist.remove(option)
+ ef_format = True
+ elif option[0] == 'std_naming' or option[0] == 'std_names' or option[0] == 'std_format':
+ optionlist.remove(option)
+ ef_format = False
+ elif option[0] == 'clean':
+ do_clean = True
+
+ # Check for options "source" and "target"
+ for option in optionlist[:]:
+ if option[0] == 'source':
+ optionlist.remove(option)
+ sourcedir = option[1]
+ elif option[0] == 'target':
+ optionlist.remove(option)
+ targetdir = option[1]
+
+ if not targetdir:
+ print("No target directory specified. Exiting.")
+ sys.exit(1)
+
+ # Take the target PDK name from the target path last component
+ pdkname = os.path.split(targetdir)[1]
+
+ # If targetdir (the staging area) exists, make sure it's empty.
+
+ if os.path.isdir(targetdir):
+ # Error if targetdir exists but is not writeable
+ if not os.access(targetdir, os.W_OK):
+ print("Target installation directory " + targetdir + " is not writable.")
+ sys.exit(1)
+
+ # Clear out the staging directory if specified
+ if do_clean:
+ shutil.rmtree(targetdir)
+ elif os.path.exists(targetdir):
+ print("Target installation directory " + targetdir + " is not a directory.")
+ sys.exit(1)
+
+ # Error if no source or dest specified unless "-clean" was specified
+ if not sourcedir:
+ if do_clean:
+ print("Done removing staging area.")
+ sys.exit(0)
+ else:
+ print("No source directory specified. Exiting.")
+ sys.exit(1)
+
+ # Create the target directory
+ os.makedirs(targetdir, exist_ok=True)
+
+ #----------------------------------------------------------------
+ # Installation part 1: Install files into the staging directory
+ #----------------------------------------------------------------
+
+ # Diagnostic
+ print("Installing in target (staging) directory " + targetdir)
+
+ # Create the top-level directories
+
+ os.makedirs(targetdir + '/libs.tech', exist_ok=True)
+ os.makedirs(targetdir + '/libs.ref', exist_ok=True)
+
+ # Path to magic techfile depends on ef_format
+
+ if ef_format == True:
+ mag_current = '/libs.tech/magic/current/'
+ else:
+ mag_current = '/libs.tech/magic/'
+
+ # Check for magic version and set flag if it does not exist or if
+ # it has the wrong version.
+ have_mag_8_2 = False
+ try:
+ mproc = subprocess.run(['magic', '--version'],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE,
+ universal_newlines = True)
+ if mproc.stdout:
+ mag_version = mproc.stdout.splitlines()[0]
+ mag_version_info = mag_version.split('.')
+ try:
+ if int(mag_version_info[0]) > 8:
+ have_mag_8_2 = True
+ elif int(mag_version_info[0]) == 8:
+ if int(mag_version_info[1]) >= 2:
+ have_mag_8_2 = True
+ print('Magic version 8.2 available on the system.')
+ except ValueError:
+ print('Error: "magic --version" did not return valid version number.')
+ except FileNotFoundError:
+ print('Error: Failed to find executable for magic in standard search path.')
+
+ if not have_mag_8_2:
+ print('WARNING: Magic version 8.2 cannot be executed from the standard executable search path.')
+ print('Please install or correct the search path.')
+ print('Magic database files will not be created, and other missing file formats may not be generated.')
+
+ # Populate any targets that do not specify a library, or where the library is
+ # specified as "primitive".
+
+ # Populate the techLEF and SPICE models, if specified. Also, this section can add
+ # to any directory in libs.tech/ as given by the option; e.g., "-ngspice" will
+ # install into libs.tech/ngspice/.
+
+ if libraries == [] or 'primitive' in libraries[0]:
+
+ for option in optionlist[:]:
+
+ # Legacy behavior is to put libs.tech models and techLEF files in
+ # the same grouping as files for the primdev library (which go in
+ # libs.ref). Current behavior is to put all libs.tech files in
+ # a grouping with no library, with unrestricted ability to write
+ # into any subdirectory of libs.tech/. Therefore, need to restrict
+ # legacy use to just 'techlef' and 'models'.
+
+ if len(libraries) > 0 and 'primitive' in libraries[0]:
+ if option[0] != 'techlef' and option[0] != 'techLEF' and option[0] != 'models':
+ continue
+
+ # Normally technology LEF files are associated with IP libraries.
+ # However, if no library is specified or the library is 'primitive'
+ # (legacy behavior), then put in the techLEF directory with no subdirectory.
+
+ filter_scripts = []
+ if option[0] == 'techlef' or option[0] == 'techLEF':
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_scripts.append(item.split('=')[1])
+ break
+
+ if ef_format:
+ techlefdir = targetdir + '/libs.ref/' + 'techLEF'
+ else:
+ techlefdir = targetdir + '/libs.tech/lef'
+
+ os.makedirs(techlefdir, exist_ok=True)
+ # All techlef files should be copied, so use "glob" on the wildcards
+ techlist = glob.glob(substitute(sourcedir + '/' + option[1], None))
+
+ for lefname in techlist:
+ leffile = os.path.split(lefname)[1]
+ targname = techlefdir + '/' + leffile
+
+ if os.path.isfile(lefname):
+ shutil.copy(lefname, targname)
+ else:
+ shutil.copytree(lefname, targname)
+
+ for filter_script in filter_scripts:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ optionlist.remove(option)
+
+ # All remaining options will refer to specific tools (e.g., -ngspice, -magic)
+ # although generic names (.e.g, -models) are acceptable if the tools know
+ # where to find the files. Currently, most tools have their own formats
+ # and standards for setup, and so generally each install directory will be
+ # unique to one EDA tool.
+
+ else:
+ filter_scripts = []
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_scripts.append(item.split('=')[1])
+ break
+
+ print('Diagnostic: installing ' + option[0] + '.')
+ tooldir = targetdir + '/libs.tech/' + option[0]
+ os.makedirs(tooldir, exist_ok=True)
+
+ # All files should be linked or copied, so use "glob" on
+ # the wildcards. Copy each file and recursively copy each
+ # directory.
+ toollist = glob.glob(substitute(sourcedir + '/' + option[1], None))
+
+ for toolname in toollist:
+ toolfile = os.path.split(toolname)[1]
+ targname = tooldir + '/' + toolfile
+
+ if os.path.isdir(toolname):
+ # Remove any existing directory, and its contents
+ if os.path.isdir(targname):
+ shutil.rmtree(targname)
+ os.makedirs(targname)
+
+ # Recursively find and copy or link the whole directory
+ # tree from this point.
+
+ alltoollist = glob.glob(toolname + '/**', recursive=True)
+ commonpart = os.path.commonpath(alltoollist)
+ for subtoolname in alltoollist:
+ if os.path.isdir(subtoolname):
+ continue
+ # Get the path part that is not common between toollist and
+ # alltoollist.
+ subpart = os.path.relpath(subtoolname, commonpart)
+ subtargname = targname + '/' + subpart
+ os.makedirs(os.path.split(subtargname)[0], exist_ok=True)
+
+ if os.path.isfile(subtoolname):
+ shutil.copy(subtoolname, subtargname)
+ else:
+ shutil.copytree(subtoolname, subtargname)
+
+ for filter_script in filter_scripts:
+ # Apply filter script to all files in the target directory
+ tfilter(subtargname, filter_script)
+
+ else:
+ # Remove any existing file
+ if os.path.isfile(targname):
+ os.remove(targname)
+ elif os.path.isdir(targname):
+ shutil.rmtree(targname)
+
+ if os.path.isfile(toolname):
+ shutil.copy(toolname, targname)
+ else:
+ shutil.copytree(toolname, targname)
+
+ for filter_script in filter_scripts:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ optionlist.remove(option)
+
+ # Do an initial pass through all of the options and determine what is being
+ # installed, so that we know in advance which file formats are missing and
+ # need to be generated.
+
+ for option in optionlist[:]:
+ if option[0] == 'lef':
+ have_lef = True
+ if option[0] == 'techlef' or option[0] == 'techLEF':
+ have_techlef = True
+ elif option[0] == 'gds':
+ have_gds = True
+ elif option[0] == 'spice' or option[0] == 'spi':
+ have_spice = True
+ elif option[0] == 'cdl':
+ have_cdl = True
+ elif option[0] == 'verilog':
+ have_verilog = True
+ elif option[0] == 'lib' or option[0] == 'liberty':
+ have_lib = True
+
+ # The remaining options in optionlist should all be types like 'lef' or 'liberty'
+ # and there should be a corresponding library list specified by '-library'
+
+ for option in optionlist[:]:
+
+ # Ignore if no library list---should have been taken care of above.
+ if libraries == []:
+ break
+
+ # Diagnostic
+ print("Install option: " + str(option[0]))
+
+ # For ef_format: always make techlef -> techLEF and spice -> spi
+
+ if ef_format:
+ if option[0] == 'techlef':
+ option[0] = 'techLEF'
+ elif option[0] == 'spice':
+ option[0] = 'spi'
+
+ destdir = targetdir + '/libs.ref/' + option[0]
+ os.makedirs(destdir, exist_ok=True)
+
+ # If the option is followed by the keyword "up" and a number, then
+ # the source should be copied (or linked) from <number> levels up
+ # in the hierarchy (see below).
+
+ if 'up' in option:
+ uparg = option.index('up')
+ try:
+ hier_up = int(option[uparg + 1])
+ except:
+ print("Non-numeric option to 'up': " + option[uparg + 1])
+ print("Ignoring 'up' option.")
+ hier_up = 0
+ else:
+ hier_up = 0
+
+ filter_scripts = []
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_scripts.append(item.split('=')[1])
+ break
+
+ # Option 'stub' applies to netlists ('cdl' or 'spice') and generates
+ # a file with only stub entries.
+ do_stub = 'stub' in option
+
+ # Option 'compile' is a standalone keyword ('comp' may be used).
+ do_compile = 'compile' in option or 'comp' in option
+ do_compile_only = 'compile-only' in option or 'comp-only' in option
+
+ # Option 'nospecify' is a standalone keyword ('nospec' may be used).
+ do_remove_spec = 'nospecify' in option or 'nospec' in option
+
+ # Option 'exclude' has an argument
+ try:
+ excludelist = list(item.split('=')[1].split(',') for item in option if item.startswith('excl'))[0]
+ except IndexError:
+ excludelist = []
+ else:
+ print('Excluding files: ' + (',').join(excludelist))
+
+ # Option 'rename' has an argument
+ try:
+ newname = list(item.split('=')[1] for item in option if item.startswith('rename'))[0]
+ except IndexError:
+ newname = None
+ else:
+ print('Renaming file to: ' + newname)
+
+ # 'anno' may be specified for LEF, in which case the LEF is used only
+ # to annotate GDS and is not itself installed; this allows LEF to
+ # be generated from Magic and avoids quirky use of obstruction layers.
+ have_lefanno = True if 'annotate' in option or 'anno' in option else False
+ if have_lefanno:
+ if option[0] != 'lef':
+ print("Warning: 'annotate' option specified outside of -lef. Ignoring.")
+ else:
+ # Mark as NOT having LEF since we want to use it only for annotation.
+ have_lef = False
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ destlibdir = destdir + '/' + destlib
+ else:
+ destdir = targetdir + '/libs.ref/' + destlib + '/' + option[0]
+ destlibdir = destdir
+
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Populate the library subdirectory
+ # Parse the option and replace each '/*/' with the library name,
+ # and check if it is a valid directory name. Then glob the
+ # resulting option name. Warning: This assumes that all
+ # occurences of the text '/*/' match a library name. It should
+ # be possible to wild-card the directory name in such a way that
+ # this is always true.
+
+ testpath = substitute(sourcedir + '/' + option[1], library[1])
+ liblist = glob.glob(testpath)
+
+ # Create a file "sources.txt" (or append to it if it exists)
+ # and add the source directory name so that the staging install
+ # script can know where the files came from.
+
+ with open(destlibdir + '/sources.txt', 'a') as ofile:
+ print(testpath, file=ofile)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(liblist) > 0:
+ liblistnames = list(os.path.split(item)[1] for item in liblist)
+ notliblist = []
+ for exclude in excludelist:
+ notliblist.extend(fnmatch.filter(liblistnames, exclude))
+
+ # Apply exclude list
+ if len(notliblist) > 0:
+ for file in liblist[:]:
+ if os.path.split(file)[1] in notliblist:
+ liblist.remove(file)
+
+ if len(excludelist) > 0 and len(notliblist) == 0:
+ print('Warning: Nothing from the exclude list found in sources.')
+ print('excludelist = ' + str(excludelist))
+ print('destlibdir = ' + destlibdir)
+
+ # Diagnostic
+ print('Collecting files from ' + testpath)
+ print('Files to install:')
+ if len(liblist) < 10:
+ for item in liblist:
+ print(' ' + item)
+ else:
+ for item in liblist[0:4]:
+ print(' ' + item)
+ print(' .')
+ print(' .')
+ print(' .')
+ for item in liblist[-6:-1]:
+ print(' ' + item)
+ print('(' + str(len(liblist)) + ' files total)')
+
+ for libname in liblist:
+ # Note that there may be a hierarchy to the files in option[1],
+ # say for liberty timing files under different conditions, so
+ # make sure directories have been created as needed.
+
+ libfile = os.path.split(libname)[1]
+ libfilepath = os.path.split(libname)[0]
+ destpathcomp = []
+ for i in range(hier_up):
+ destpathcomp.append('/' + os.path.split(libfilepath)[1])
+ libfilepath = os.path.split(libfilepath)[0]
+ destpathcomp.reverse()
+ destpath = ''.join(destpathcomp)
+
+ if newname:
+ if len(liblist) == 1:
+ destfile = newname
+ else:
+ if not do_compile and not do_compile_only:
+ print('Error: rename specified but more than one file found!')
+ destfile = libfile
+ else:
+ destfile = libfile
+
+ targname = destlibdir + destpath + '/' + destfile
+
+ # NOTE: When using "up" with link_from, could just make
+ # destpath itself a symbolic link; this way is more flexible
+ # but adds one symbolic link per file.
+
+ if destpath != '':
+ if not os.path.isdir(destlibdir + destpath):
+ os.makedirs(destlibdir + destpath, exist_ok=True)
+
+ # Remove any existing file
+ if os.path.isfile(targname):
+ os.remove(targname)
+ elif os.path.isdir(targname):
+ shutil.rmtree(targname)
+
+ # NOTE: Diagnostic, probably much too much output.
+ print(' Install:' + libname + ' to ' + targname)
+ if os.path.isfile(libname):
+ shutil.copy(libname, targname)
+ else:
+ shutil.copytree(libname, targname)
+
+ # File filtering options: Two options 'stub' and 'nospec' are
+ # handled by scripts in ../common/. Custom filters can also be
+ # specified.
+
+ local_filter_scripts = filter_scripts[:]
+
+ if option[0] == 'verilog':
+ # Internally handle syntactical issues with verilog and iverilog
+ vfilter(targname)
+
+ if do_remove_spec:
+ scriptdir = os.path.split(os.getcwd())[0] + '/common'
+ local_filter_scripts.append(scriptdir + '/remove_specify.py')
+
+ elif option[0] == 'cdl' or option[0] == 'spi' or option[0] == 'spice':
+ if do_stub:
+ scriptdir = os.path.split(os.getcwd())[0] + '/common'
+ local_filter_scripts.append(scriptdir + '/makestub.py')
+
+ for filter_script in local_filter_scripts:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ if do_compile == True or do_compile_only == True:
+ # NOTE: The purpose of "rename" is to put a destlib-named
+ # library elsewhere so that it can be merged with another
+ # library into a compiled <destlib>.<ext>
+
+ compname = destlib
+
+ # To do: Make this compatible with linking from another PDK.
+
+ if option[0] == 'verilog':
+ # If there is not a single file with all verilog cells in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ create_verilog_library(destlibdir, compname, do_compile_only, do_stub, excludelist)
+
+ elif option[0] == 'gds' and have_mag_8_2:
+ # If there is not a single file with all GDS cells in it,
+ # then compile one.
+
+ # Link to the PDK magic startup file from the target directory
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+ create_gds_library(destlibdir, compname, startup_script, do_compile_only, excludelist)
+
+ elif option[0] == 'liberty' or option[0] == 'lib':
+ # If there is not a single file with all liberty cells in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ create_lib_library(destlibdir, compname, do_compile_only, excludelist)
+
+ elif option[0] == 'spice' or option[0] == 'spi':
+ # If there is not a single file with all SPICE subcircuits in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ spiext = '.spice' if not ef_format else '.spi'
+ create_spice_library(destlibdir, compname, spiext, do_compile_only, do_stub, excludelist)
+ if do_compile_only == True:
+ if newname:
+ if os.path.isfile(newname):
+ os.remove(newname)
+
+ elif option[0] == 'cdl':
+ # If there is not a single file with all CDL subcircuits in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ create_spice_library(destlibdir, compname, '.cdl', do_compile_only, do_stub, excludelist)
+ if do_compile_only == True:
+ if newname:
+ if os.path.isfile(newname):
+ os.remove(newname)
+
+ elif option[0] == 'lef':
+ # If there is not a single file with all LEF cells in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ create_lef_library(destlibdir, compname, do_compile_only, excludelist)
+
+ # Find any libraries/options marked as "privileged" (or "private") and
+ # move the files from libs.tech or libs.ref to libs.priv, leaving a
+ # symbolic link in the original location. Do this during the initial
+ # install so that options following in the list can add files to the
+ # non-privileged equivalent directory path.
+
+ if 'priv' in option or 'privileged' in option or 'private' in option:
+
+ # Diagnostic
+ print("Install option: " + str(option[0]))
+
+ if ef_format == True:
+ os.makedirs(targetdir + '/libs.priv', exist_ok=True)
+
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ srclibdir = targetdir + '/libs.ref/' + option[0] + '/' + destlib
+ destlibdir = targetdir + '/libs.priv/' + option[0] + '/' + destlib
+ else:
+ srclibdir = targetdir + '/libs.ref/' + destlib + '/' + option[0]
+ destlibdir = targetdir + '/libs.priv/' + destlib + '/' + option[0]
+
+ if not os.path.exists(destlibdir):
+ os.makedirs(destlibdir)
+
+ print('Moving files in ' + srclibdir + ' to privileged space.')
+ filelist = os.listdir(srclibdir)
+ for file in filelist:
+ srcfile = srclibdir + '/' + file
+ destfile = destlibdir + '/' + file
+ if os.path.isfile(destfile):
+ os.remove(destfile)
+ elif os.path.isdir(destfile):
+ shutil.rmtree(destfile)
+
+ if os.path.isfile(srcfile):
+ shutil.copy(srcfile, destfile)
+ os.remove(srcfile)
+ else:
+ shutil.copytree(srcfile, destfile)
+ shutil.rmtree(srcfile)
+
+ print("Completed installation of vendor files.")
+
+ #----------------------------------------------------------------
+ # Installation part 2: Generate derived file formats
+ #----------------------------------------------------------------
+
+ # Now for the harder part. If GDS and/or LEF databases were specified,
+ # then migrate them to magic (.mag files in layout/ or abstract/).
+
+ ignorelist = []
+ do_cdl_scaleu = False
+ no_cdl_convert = False
+ no_gds_convert = False
+ no_lef_convert = False
+ cdl_compile_only = False
+
+ cdl_exclude = []
+ lef_exclude = []
+ gds_exclude = []
+ spice_exclude = []
+ verilog_exclude = []
+
+ cdl_reflib = '/libs.ref/'
+ gds_reflib = '/libs.ref/'
+ lef_reflib = '/libs.ref/'
+
+ for option in optionlist[:]:
+ if option[0] == 'cdl':
+ # Option 'scaleu' is a standalone keyword
+ do_cdl_scaleu = 'scaleu' in option
+
+ # Option 'ignore' has arguments after '='
+ for item in option:
+ if item.split('=')[0] == 'ignore':
+ ignorelist = item.split('=')[1].split(',')
+
+ # Option 'noconvert' is a standalone keyword.
+ if 'noconvert' in option:
+ if option[0] == 'cdl':
+ no_cdl_convert = True
+ elif option[0] == 'gds':
+ no_gds_convert = True
+ elif option[0] == 'lef':
+ no_lef_convert = True
+
+ # Option 'privileged' is a standalone keyword.
+ if 'priv' in option or 'privileged' in option or 'private' in option:
+ if option[0] == 'cdl':
+ cdl_reflib = '/libs.priv/'
+ elif option[0] == 'gds':
+ gds_reflib = '/libs.priv/'
+ elif option[0] == 'lef':
+ lef_reflib = '/libs.priv/'
+
+ # If CDL is marked 'compile-only' then CDL should only convert the
+ # compiled file to SPICE if conversion is needed.
+ if 'compile-only' in option:
+ if option[0] == 'cdl':
+ cdl_compile_only = True
+
+ # Find exclude list for any option
+ for item in option:
+ if item.split('=')[0] == 'exclude':
+ exclude_list = item.split('=')[1].split(',')
+ if option[0] == 'cdl':
+ cdl_exclude = exclude_list
+ elif option[0] == 'lef':
+ lef_exclude = exclude_list
+ elif option[0] == 'gds':
+ gds_exclude = exclude_list
+ elif option[0] == 'spi' or option[0] == 'spice':
+ spice_exclude = exclude_list
+ elif option[0] == 'verilog':
+ verilog_exclude = exclude_list
+
+ devlist = []
+ pdklibrary = None
+
+ if have_gds and not no_gds_convert:
+ print("Migrating GDS files to layout.")
+
+ if ef_format:
+ destdir = targetdir + gds_reflib + 'mag'
+ srcdir = targetdir + gds_reflib + 'gds'
+ vdir = targetdir + '/libs.ref/' + 'verilog'
+ cdir = targetdir + cdl_reflib + 'cdl'
+ sdir = targetdir + cdl_reflib + 'spi'
+
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ vlibdir = vdir + '/' + destlib
+ clibdir = cdir + '/' + destlib
+ slibdir = sdir + '/' + destlib
+ else:
+ destdir = targetdir + gds_reflib + destlib + '/mag'
+ srcdir = targetdir + gds_reflib + destlib + '/gds'
+ vdir = targetdir + '/libs.ref/' + destlib + '/verilog'
+ cdir = targetdir + cdl_reflib + destlib + '/cdl'
+ sdir = targetdir + cdl_reflib + destlib + '/spice'
+ destlibdir = destdir
+ srclibdir = srcdir
+ vlibdir = vdir
+ clibdir = cdir
+ slibdir = sdir
+
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # For primitive devices, check the PDK script and find the name
+ # of the library and get a list of supported devices.
+
+ if library[0] == 'primitive':
+ pdkscript = targetdir + mag_current + pdkname + '.tcl'
+ print('Searching for supported devices in PDK script ' + pdkscript + '.')
+
+ if os.path.isfile(pdkscript):
+ librex = re.compile('^[ \t]*set[ \t]+PDKNAMESPACE[ \t]+([^ \t]+)$')
+ devrex = re.compile('^[ \t]*proc[ \t]+([^ :\t]+)::([^ \t_]+)_defaults')
+ fixrex = re.compile('^[ \t]*return[ \t]+\[([^ :\t]+)::fixed_draw[ \t]+([^ \t]+)[ \t]+')
+ devlist = []
+ fixedlist = []
+ with open(pdkscript, 'r') as ifile:
+ scripttext = ifile.read().splitlines()
+ for line in scripttext:
+ lmatch = librex.match(line)
+ if lmatch:
+ pdklibrary = lmatch.group(1)
+ dmatch = devrex.match(line)
+ if dmatch:
+ if dmatch.group(1) == pdklibrary:
+ devlist.append(dmatch.group(2))
+ fmatch = fixrex.match(line)
+ if fmatch:
+ if fmatch.group(1) == pdklibrary:
+ fixedlist.append(fmatch.group(2))
+
+ # Diagnostic
+ print("PDK library is " + str(pdklibrary))
+
+ # Link to the PDK magic startup file from the target directory
+ # If there is no -F version then look for one without -F (open source PDK)
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+
+ if have_mag_8_2 and os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # Find GDS file names in the source
+ print('Getting GDS file list from ' + srclibdir + '.')
+ gdsfilesraw = os.listdir(srclibdir)
+ gdsfiles = []
+ for gdsfile in gdsfilesraw:
+ gdsext = os.path.splitext(gdsfile)[1].lower()
+ if gdsext == '.gds' or gdsext == '.gdsii' or gdsext == '.gds2':
+ gdsfiles.append(gdsfile)
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(gdsfiles) > 0:
+ gdsnames = list(os.path.split(item)[1] for item in gdsfiles)
+ notgdsnames = []
+ for exclude in gds_exclude:
+ notgdsnames.extend(fnmatch.filter(gdsnames, exclude))
+
+ # Apply exclude list
+ if len(notgdsnames) > 0:
+ for file in gdsfiles[:]:
+ if os.path.split(file)[1] in notgdsnames:
+ gdsfiles.remove(file)
+
+ # Generate a script called "generate_magic.tcl" and leave it in
+ # the target directory. Use it as input to magic to create the
+ # .mag files from the database.
+
+ print('Creating magic generation script to generate magic database files.')
+
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('# Script to generate .mag files from .gds ', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('gds readonly true', file=ofile)
+ print('gds flatten true', file=ofile)
+ print('gds rescale false', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ for gdsfile in gdsfiles:
+ # Note: DO NOT use a relative path here.
+ print('gds read ' + srclibdir + '/' + gdsfile, file=ofile)
+
+ # Make sure properties include the Tcl generated cell
+ # information from the PDK script
+
+ if pdklibrary:
+ tclfixedlist = '{' + ' '.join(fixedlist) + '}'
+ print('set devlist ' + tclfixedlist, file=ofile)
+ print('set topcell [lindex [cellname list top] 0]',
+ file=ofile)
+
+ print('foreach cellname $devlist {', file=ofile)
+ print(' load $cellname', file=ofile)
+ print(' property gencell $cellname', file=ofile)
+ print(' property parameter m=1', file=ofile)
+ print(' property library ' + pdklibrary, file=ofile)
+ print('}', file=ofile)
+ print('load $topcell', file=ofile)
+
+ print('cellname delete \(UNNAMED\)', file=ofile)
+ print('writeall force', file=ofile)
+
+ leffiles = []
+ lefmacros = []
+ if have_lefanno:
+ # Find LEF file names in the source
+ if ef_format:
+ lefsrcdir = targetdir + lef_reflib + 'lefanno'
+ lefsrclibdir = lefsrcdir + '/' + destlib
+ else:
+ lefsrcdir = targetdir + lef_reflib + destlib + '/lefanno'
+ lefsrclibdir = lefsrcdir
+
+ leffiles = os.listdir(lefsrclibdir)
+ leffiles = list(item for item in leffiles if os.path.splitext(item)[1] == '.lef')
+ # Get list of abstract views to make from LEF macros
+ for leffile in leffiles:
+ with open(leffile, 'r') as ifile:
+ ltext = ifile.read()
+ llines = ltext.splitlines()
+ for lline in llines:
+ ltok = re.split(' |\t|\(', lline)
+ if ltok[0] == 'MACRO':
+ lefmacros.append(ltok[1])
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(lefmacros) > 0:
+ lefnames = list(os.path.split(item)[1] for item in lefmacros)
+ notlefnames = []
+ for exclude in lef_exclude:
+ notlefnames.extend(fnmatch.filter(lefnames, exclude))
+
+ # Apply exclude list
+ if len(notlefnames) > 0:
+ for file in lefmacros[:]:
+ if os.path.split(file)[1] in notlefnames:
+ lefmacros.remove(file)
+
+ elif have_verilog and os.path.isdir(vlibdir):
+ # Get list of abstract views to make from verilog modules
+ vfiles = os.listdir(vlibdir)
+ vfiles = list(item for item in vfiles if os.path.splitext(item)[1] == '.v')
+ for vfile in vfiles:
+ with open(vlibdir + '/' + vfile, 'r') as ifile:
+ vtext = ifile.read()
+ vlines = vtext.splitlines()
+ for vline in vlines:
+ vtok = re.split(' |\t|\(', vline)
+ try:
+ if vtok[0] == 'module':
+ if vtok[1] not in lefmacros:
+ lefmacros.append(vtok[1])
+ except:
+ pass
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(lefmacros) > 0:
+ lefnames = list(os.path.split(item)[1] for item in lefmacros)
+ notlefnames = []
+ for exclude in verilog_exclude:
+ notlefnames.extend(fnmatch.filter(lefnames, exclude))
+
+ # Apply exclude list
+ if len(notlefnames) > 0:
+ for file in lefmacros[:]:
+ if os.path.split(file)[1] in notlefnames:
+ lefmacros.remove(file)
+
+ elif have_cdl and os.path.isdir(clibdir):
+ # Get list of abstract views to make from CDL subcircuits
+ cfiles = os.listdir(clibdir)
+ cfiles = list(item for item in cfiles if os.path.splitext(item)[1] == '.cdl')
+ for cfile in cfiles:
+ with open(clibdir + '/' + cfile, 'r') as ifile:
+ ctext = ifile.read()
+ clines = ctext.splitlines()
+ for cline in clines:
+ ctok = cline.split()
+ try:
+ if ctok[0].lower() == '.subckt':
+ if ctok[1] not in lefmacros:
+ lefmacros.append(ctok[1])
+ except:
+ pass
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(lefmacros) > 0:
+ lefnames = list(os.path.split(item)[1] for item in lefmacros)
+ notlefnames = []
+ for exclude in cdl_exclude:
+ notlefnames.extend(fnmatch.filter(lefnames, exclude))
+
+ # Apply exclude list
+ if len(notlefnames) > 0:
+ for file in lefmacros[:]:
+ if os.path.split(file)[1] in notlefnames:
+ lefmacros.remove(file)
+
+ elif have_spice and os.path.isdir(slibdir):
+ # Get list of abstract views to make from SPICE subcircuits
+ sfiles = os.listdir(slibdir)
+ sfiles = list(item for item in sfiles)
+ for sfile in sfiles:
+ with open(slibdir + '/' + sfile, 'r') as ifile:
+ stext = ifile.read()
+ slines = stext.splitlines()
+ for sline in slines:
+ stok = sline.split()
+ try:
+ if stok[0].lower() == '.subckt':
+ if stok[1] not in lefmacros:
+ lefmacros.append(stok[1])
+ except:
+ pass
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(lefmacros) > 0:
+ lefnames = list(os.path.split(item)[1] for item in lefmacros)
+ notlefnames = []
+ for exclude in spice_exclude:
+ notlefnames.extend(fnmatch.filter(lefnames, exclude))
+
+ # Apply exclude list
+ if len(notlefnames) > 0:
+ for file in lefmacros[:]:
+ if os.path.split(file)[1] in notlefnames:
+ lefmacros.remove(file)
+
+ if not lefmacros:
+ print('No source for abstract views: Abstract views not made.')
+ elif not have_lef:
+ # This library has a GDS database but no LEF database. Use
+ # magic to create abstract views of the GDS cells. If
+ # option "annotate" is given, then read the LEF file after
+ # loading the database file to annotate the cell with
+ # information from the LEF file. This usually indicates
+ # that the LEF file has some weird definition of obstruction
+ # layers and we want to normalize them by using magic's LEF
+ # write procedure, but we still need the pin use and class
+ # information from the LEF file, and maybe the bounding box.
+
+ for leffile in leffiles:
+ if have_lefanno:
+ print('lef read ' + lefsrclibdir + '/' + leffile, file=ofile)
+ for lefmacro in lefmacros:
+ print('if {[cellname list exists ' + lefmacro + '] != 0} {', file=ofile)
+ print(' load ' + lefmacro, file=ofile)
+ print(' lef write ' + lefmacro + ' -hide', file=ofile)
+ print('}', file=ofile)
+ print('puts stdout "Done."', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ print('Running magic to create magic database files.')
+ sys.stdout.flush()
+
+ # Run magic to read in the GDS file and write out magic databases.
+ with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole'],
+ stdin = ifile, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+ if not have_lef:
+ print('No LEF file install; need to generate LEF.')
+ # Remove the lefanno/ target and its contents.
+ if have_lefanno:
+ if ef_format:
+ lefannosrcdir = targetdir + lef_reflib + 'lefanno'
+ else:
+ lefannosrcdir = targetdir + lef_reflib + destlib + '/lefanno'
+ if os.path.isdir(lefannosrcdir):
+ shutil.rmtree(lefannosrcdir)
+
+ if ef_format:
+ destlefdir = targetdir + lef_reflib + 'lef'
+ destleflibdir = destlefdir + '/' + destlib
+ else:
+ destlefdir = targetdir + lef_reflib + destlib + '/lef'
+ destleflibdir = destlefdir
+
+ os.makedirs(destleflibdir, exist_ok=True)
+ leflist = os.listdir(destlibdir)
+ leflist = list(item for item in leflist if os.path.splitext(item)[1] == '.lef')
+
+ # All macros will go into one file
+ destleflib = destleflibdir + '/' + destlib + '.lef'
+ # Remove any existing library file from the target directory
+ if os.path.isfile(destleflib):
+ print('Removing existing library ' + destleflib)
+ os.remove(destleflib)
+
+ first = True
+ with open(destleflib, 'w') as ofile:
+ for leffile in leflist:
+ # Remove any existing single file from the target directory
+ if os.path.isfile(destleflibdir + '/' + leffile):
+ print('Removing ' + destleflibdir + '/' + leffile)
+ os.remove(destleflibdir + '/' + leffile)
+
+ # Append contents
+ sourcelef = destlibdir + '/' + leffile
+ with open(sourcelef, 'r') as ifile:
+ leflines = ifile.read().splitlines()
+ if not first:
+ # Remove header from all but the first file
+ leflines = leflines[8:]
+ else:
+ first = False
+
+ for line in leflines:
+ print(line, file=ofile)
+
+ # Remove file from the source directory
+ print('Removing source file ' + sourcelef)
+ os.remove(sourcelef)
+
+ # Set have_lef now that LEF files were made, so they
+ # can be used to generate the maglef/ databases.
+ have_lef = True
+
+ elif not have_mag_8_2:
+ print('The installer is not able to run magic.')
+ else:
+ print("Master PDK magic startup file not found. Did you install")
+ print("PDK tech files before PDK vendor files?")
+
+ if have_lef and not no_lef_convert:
+ print("Migrating LEF files to layout.")
+ if ef_format:
+ destdir = targetdir + '/libs.ref/' + 'maglef'
+ srcdir = targetdir + lef_reflib + 'lef'
+ magdir = targetdir + gds_reflib + 'mag'
+ cdldir = targetdir + cdl_reflib + 'cdl'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ maglibdir = magdir + '/' + destlib
+ cdllibdir = cdldir + '/' + destlib
+ else:
+ destdir = targetdir + '/libs.ref/' + destlib + '/maglef'
+ srcdir = targetdir + lef_reflib + destlib + '/lef'
+ magdir = targetdir + gds_reflib + destlib + '/mag'
+ cdldir = targetdir + cdl_reflib + destlib + '/cdl'
+
+ destlibdir = destdir
+ srclibdir = srcdir
+ maglibdir = magdir
+ cdllibdir = cdldir
+
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Link to the PDK magic startup file from the target directory
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+
+ if have_mag_8_2 and os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # Find LEF file names in the source
+ leffiles = os.listdir(srclibdir)
+ leffiles = list(item for item in leffiles if os.path.splitext(item)[1].lower() == '.lef')
+
+ # Get list of abstract views to make from LEF macros
+ lefmacros = []
+ err_no_macros = False
+ for leffile in leffiles:
+ with open(srclibdir + '/' + leffile, 'r') as ifile:
+ ltext = ifile.read()
+ llines = ltext.splitlines()
+ for lline in llines:
+ ltok = re.split(' |\t|\(', lline)
+ if ltok[0] == 'MACRO':
+ lefmacros.append(ltok[1])
+
+ # Create exclude list with glob-style matching using fnmatch
+ if len(lefmacros) > 0:
+ lefnames = list(os.path.split(item)[1] for item in lefmacros)
+ notlefnames = []
+ for exclude in lef_exclude:
+ notlefnames.extend(fnmatch.filter(lefnames, exclude))
+
+ # Apply exclude list
+ if len(notlefnames) > 0:
+ for file in lefmacros[:]:
+ if os.path.split(file)[1] in notlefnames:
+ lefmacros.remove(file)
+
+ if len(leffiles) == 0:
+ print('Warning: No LEF files found in ' + srclibdir)
+ continue
+
+ print('Generating conversion script to create magic databases from LEF')
+
+ # Generate a script called "generate_magic.tcl" and leave it in
+ # the target directory. Use it as input to magic to create the
+ # .mag files from the database.
+
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('# Script to generate .mag files from .lef ', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ # If there are devices in the LEF file that come from the
+ # PDK library, then copy this list into the script.
+
+ if pdklibrary:
+ shortdevlist = []
+ for macro in lefmacros:
+ if macro in devlist:
+ shortdevlist.append(macro)
+
+ tcldevlist = '{' + ' '.join(shortdevlist) + '}'
+ print('set devlist ' + tcldevlist, file=ofile)
+
+ for leffile in leffiles:
+ print('lef read ' + srclibdir + '/' + leffile, file=ofile)
+
+ for lefmacro in lefmacros:
+
+ # To be completed: Parse SPICE file for port order, make
+ # sure ports are present and ordered.
+
+ if pdklibrary and lefmacro in shortdevlist:
+ print('set cellname ' + lefmacro, file=ofile)
+ print('if {[lsearch $devlist $cellname] >= 0} {',
+ file=ofile)
+ print(' load $cellname', file=ofile)
+ print(' property gencell $cellname', file=ofile)
+ print(' property parameter m=1', file=ofile)
+ print(' property library ' + pdklibrary, file=ofile)
+ print('}', file=ofile)
+
+ # Load one of the LEF files so that the default (UNNAMED) cell
+ # is not loaded, then delete (UNNAMED) so it doesn't generate
+ # an error message.
+ if len(lefmacros) > 0:
+ print('load ' + lefmacros[0], file=ofile)
+ print('cellname delete \(UNNAMED\)', file=ofile)
+ else:
+ err_no_macros = True
+ print('writeall force', file=ofile)
+ print('puts stdout "Done."', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ if err_no_macros == True:
+ print('Warning: No LEF macros were defined.')
+
+ print('Running magic to create magic databases from LEF')
+ sys.stdout.flush()
+
+ # Run magic to read in the LEF file and write out magic databases.
+ with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole'],
+ stdin = ifile, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+
+ # Now list all the .mag files generated, and for each, read the
+ # corresponding file from the mag/ directory, pull the GDS file
+ # properties, and add those properties to the maglef view. Also
+ # read the CDL (or SPICE) netlist, read the ports, and rewrite
+ # the port order in the mag and maglef file accordingly.
+
+ # Diagnostic
+ print('Annotating files in ' + destlibdir)
+ sys.stdout.flush()
+ magfiles = os.listdir(destlibdir)
+ magfiles = list(item for item in magfiles if os.path.splitext(item)[1] == '.mag')
+ for magroot in magfiles:
+ magname = os.path.splitext(magroot)[0]
+ magfile = maglibdir + '/' + magroot
+ magleffile = destlibdir + '/' + magroot
+ prop_lines = get_gds_properties(magfile)
+
+ # Make sure properties include the Tcl generated cell
+ # information from the PDK script
+
+ prop_gencell = []
+ if pdklibrary:
+ if magname in fixedlist:
+ prop_gencell.append('gencell ' + magname)
+ prop_gencell.append('library ' + pdklibrary)
+ prop_gencell.append('parameter m=1')
+
+ nprops = len(prop_lines) + len(prop_gencell)
+
+ cdlfile = cdllibdir + '/' + magname + '.cdl'
+ if os.path.exists(cdlfile):
+ cdlfiles = [cdlfile]
+ else:
+ # Assume there is at least one file with all cell subcircuits
+ # in it.
+ try:
+ cdlfiles = glob.glob(cdllibdir + '/*.cdl')
+ except:
+ pass
+ if len(cdlfiles) > 0:
+ for cdlfile in cdlfiles:
+ port_dict = get_subckt_ports(cdlfile, magname)
+ if port_dict != {}:
+ break
+ else:
+ port_dict = {}
+
+ if port_dict == {}:
+ print('No CDL file contains ' + destlib + ' device ' + magname)
+ cdlfile = None
+ # To be done: If destlib is 'primitive', then look in
+ # SPICE models for port order.
+ if destlib == 'primitive':
+ print('Fix me: Need to look in SPICE models!')
+
+ proprex = re.compile('<< properties >>')
+ endrex = re.compile('<< end >>')
+ rlabrex = re.compile('rlabel[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)')
+ flabrex = re.compile('flabel[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)')
+ portrex = re.compile('port[ \t]+([^ \t]+)[ \t]+(.*)')
+ gcellrex = re.compile('string gencell')
+ portnum = -1
+
+ with open(magleffile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ with open(magleffile, 'w') as ofile:
+ has_props = False
+ is_gencell = False
+ for line in magtext:
+ tmatch = portrex.match(line)
+ if tmatch:
+ if portnum >= 0:
+ line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
+ else:
+ line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
+ ematch = endrex.match(line)
+ if ematch and nprops > 0:
+ if not has_props:
+ print('<< properties >>', file=ofile)
+ if not is_gencell:
+ for prop in prop_gencell:
+ print('string ' + prop, file=ofile)
+ for prop in prop_lines:
+ print('string ' + prop, file=ofile)
+
+ print(line, file=ofile)
+ pmatch = proprex.match(line)
+ if pmatch:
+ has_props = True
+
+ gmatch = gcellrex.match(line)
+ if gmatch:
+ is_gencell = True
+
+ lmatch = flabrex.match(line)
+ if not lmatch:
+ lmatch = rlabrex.match(line)
+ if lmatch:
+ labname = lmatch.group(1).lower()
+ try:
+ portnum = port_dict[labname]
+ except:
+ portnum = -1
+
+ if os.path.exists(magfile):
+ with open(magfile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ with open(magfile, 'w') as ofile:
+ for line in magtext:
+ tmatch = portrex.match(line)
+ if tmatch:
+ if portnum >= 0:
+ line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
+ else:
+ line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
+ ematch = endrex.match(line)
+ print(line, file=ofile)
+ lmatch = flabrex.match(line)
+ if not lmatch:
+ lmatch = rlabrex.match(line)
+ if lmatch:
+ labname = lmatch.group(1).lower()
+ try:
+ portnum = port_dict[labname]
+ except:
+ portnum = -1
+ elif os.path.splitext(magfile)[1] == '.mag':
+ # NOTE: Possibly this means the GDS cell has a different name.
+ print('Error: No file ' + magfile + '. Why is it in maglef???')
+
+ elif not have_mag_8_2:
+ print('The installer is not able to run magic.')
+ else:
+ print("Master PDK magic startup file not found. Did you install")
+ print("PDK tech files before PDK vendor files?")
+
+ # If SPICE or CDL databases were specified, then convert them to
+ # a form that can be used by ngspice, using the cdl2spi.py script
+
+ if have_spice:
+ if ef_format:
+ if not os.path.isdir(targetdir + cdl_reflib + 'spi'):
+ os.makedirs(targetdir + cdl_reflib + 'spi', exist_ok=True)
+
+ elif have_cdl and not no_cdl_convert:
+ if ef_format:
+ if not os.path.isdir(targetdir + cdl_reflib + 'spi'):
+ os.makedirs(targetdir + cdl_reflib + 'spi', exist_ok=True)
+
+ print("Migrating CDL netlists to SPICE.")
+ sys.stdout.flush()
+
+ if ef_format:
+ destdir = targetdir + cdl_reflib + 'spi'
+ srcdir = targetdir + cdl_reflib + 'cdl'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ else:
+ destdir = targetdir + cdl_reflib + destlib + '/spice'
+ srcdir = targetdir + cdl_reflib + destlib + '/cdl'
+
+ destlibdir = destdir
+ srclibdir = srcdir
+
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Find CDL file names in the source
+ # If CDL is marked compile-only then ONLY convert <distdir>.cdl
+ if cdl_compile_only:
+ alllibname = destlibdir + '/' + destlib + '.cdl'
+ if not os.path.exists(alllibname):
+ cdl_compile_only = False
+ else:
+ cdlfiles = [alllibname]
+
+ if not cdl_compile_only:
+ cdlfiles = os.listdir(srclibdir)
+ cdlfiles = list(item for item in cdlfiles if os.path.splitext(item)[1].lower() == '.cdl')
+
+ # The directory with scripts should be in ../common with respect
+ # to the Makefile that determines the cwd.
+ scriptdir = os.path.split(os.getcwd())[0] + '/common'
+
+ # Run cdl2spi.py script to read in the CDL file and write out SPICE
+ for cdlfile in cdlfiles:
+ if ef_format:
+ spiname = os.path.splitext(cdlfile)[0] + '.spi'
+ else:
+ spiname = os.path.splitext(cdlfile)[0] + '.spice'
+ procopts = [scriptdir + '/cdl2spi.py', srclibdir + '/' + cdlfile, destlibdir + '/' + spiname]
+ if do_cdl_scaleu:
+ procopts.append('-dscale=u')
+ for item in ignorelist:
+ procopts.append('-ignore=' + item)
+
+ print('Running (in ' + destlibdir + '): ' + ' '.join(procopts))
+ pproc = subprocess.run(procopts,
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+ if pproc.stdout:
+ for line in pproc.stdout.splitlines():
+ print(line)
+ if pproc.stderr:
+ print('Error message output from cdl2spi.py:')
+ for line in pproc.stderr.splitlines():
+ print(line)
+
+ elif have_gds and not no_gds_convert:
+ # If neither SPICE nor CDL formats is available in the source, then
+ # read GDS; if the result has no ports, then read the corresponding
+ # LEF library to get port information. Then write out a SPICE netlist
+ # for the whole library. NOTE: If there is no CDL or SPICE source,
+ # then the port numbering is arbitrary, and becomes whatever the
+ # output of this script makes it.
+
+ if ef_format:
+ destdir = targetdir + cdl_reflib + 'spi'
+ srcdir = targetdir + gds_reflib + 'gds'
+ lefdir = targetdir + lef_reflib + 'lef'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+
+ if ef_format:
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ leflibdir = lefdir + '/' + destlib
+ else:
+ destdir = targetdir + cdl_reflib + destlib + '/spice'
+ srcdir = targetdir + gds_reflib + destlib + '/gds'
+ lefdir = targetdir + lef_reflib + destlib + '/lef'
+
+ destlibdir = destdir
+ srclibdir = srcdir
+ leflibdir = lefdir
+
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Link to the PDK magic startup file from the target directory
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+ if os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # Get the consolidated GDS library file, or a list of all GDS files
+ # if there is no single consolidated library
+
+ allgdslibname = srclibdir + '/' + destlib + '.gds'
+ if not os.path.isfile(allgdslibname):
+ glist = glob.glob(srclibdir + '/*.gds')
+ glist.extend(glob.glob(srclibdir + '/*.gdsii'))
+ glist.extend(glob.glob(srclibdir + '/*.gds2'))
+
+ allleflibname = leflibdir + '/' + destlib + '.lef'
+ if not os.path.isfile(allleflibname):
+ llist = glob.glob(leflibdir + '/*.lef')
+
+ print('Creating magic generation script to generate SPICE library.')
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#---------------------------------------------', file=ofile)
+ print('# Script to generate SPICE library from GDS ', file=ofile)
+ print('#---------------------------------------------', file=ofile)
+ print('drc off', file=ofile)
+ print('gds readonly true', file=ofile)
+ print('gds flatten true', file=ofile)
+ print('gds rescale false', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ if not os.path.isfile(allgdslibname):
+ for gdsfile in glist:
+ print('gds read ' + gdsfile, file=ofile)
+ else:
+ print('gds read ' + allgdslibname, file=ofile)
+
+ if not os.path.isfile(allleflibname):
+ # Annotate the cells with information from the LEF files
+ for leffile in llist:
+ print('lef read ' + leffile, file=ofile)
+ else:
+ print('lef read ' + allleflibname, file=ofile)
+
+ # Load first file and remove the (UNNAMED) cell
+ if not os.path.isfile(allgdslibname):
+ print('load ' + os.path.splitext(glist[0])[0], file=ofile)
+ else:
+ gdslibroot = os.path.split(allgdslibname)[1]
+ print('load ' + os.path.splitext(gdslibroot)[0], file=ofile)
+ print('cellname delete \(UNNAMED\)', file=ofile)
+
+ print('ext2spice lvs', file=ofile)
+
+ # NOTE: Leaving "subcircuit top" as "auto" (default) can cause
+ # cells like decap that have no I/O to be output without a subcircuit
+ # wrapper. Also note that if this happens, it is an indication that
+ # power supplies have not been labeled as ports, which is harder to
+ # handle and should be fixed in the source.
+ print('ext2spice subcircuit top on', file=ofile)
+
+ print('ext2spice cthresh 0.1', file=ofile)
+
+ if os.path.isfile(allgdslibname):
+ print('select top cell', file=ofile)
+ print('set glist [cellname list children]', file=ofile)
+ print('foreach cell $glist {', file=ofile)
+ else:
+ print('foreach cell [cellname list top] {', file=ofile)
+
+ print(' load $cell', file=ofile)
+ print(' puts stdout "Extracting cell $cell"', file=ofile)
+ print(' extract all', file=ofile)
+ print(' ext2spice', file=ofile)
+ print('}', file=ofile)
+ print('puts stdout "Done."', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ # Run magic to read in the individual GDS files and
+ # write out the consolidated GDS library
+
+ print('Running magic to create GDS library.')
+ sys.stdout.flush()
+
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+ destlibdir + '/generate_magic.tcl'],
+ stdin = subprocess.DEVNULL,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+ # Remove intermediate extraction files
+ extfiles = glob.glob(destlibdir + '/*.ext')
+ for extfile in extfiles:
+ os.remove(extfile)
+
+ # If the GDS file was a consolidated file of all cells, then
+ # create a similar SPICE library of all cells.
+
+ if os.path.isfile(allgdslibname):
+ spiext = '.spice' if not ef_format else '.spi'
+ create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist)
+
+ sys.exit(0)
diff --git a/common/insert_property.py b/common/insert_property.py
new file mode 100755
index 0000000..1ee5687
--- /dev/null
+++ b/common/insert_property.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+#
+# insert_property.py: For the given install path, library name, and cellname,
+# find the Magic layout of the cell, and add the specified property string.
+# If the property exists and is the same as specified, then it remains the
+# same. If the property exists but has a different value, it is replaced.
+# The property is added to the layout in both the mag/ (full) and maglef/
+# (abstract) directories. Option "-maglef" or "-mag" will restrict the
+# use to only the view indicated by the option.
+#
+# e.g.:
+#
+# insert_property.py /home/tim/projects/efabless/tech/SkyWater/EFS8A \
+# s8iom0 s8iom0s8_top_gpio "FIXED_BBOX 0 607 15000 40200"
+
+import os
+import re
+import sys
+
+def addprop(filename, propstring, noupdate):
+ with open(filename, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ propname = propstring.split()[0]
+ proprex = re.compile('<< properties >>')
+ endrex = re.compile('<< end >>')
+
+ in_props = False
+ printed = False
+ done = False
+
+ with open(filename, 'w') as ofile:
+ for line in magtext:
+ pmatch = proprex.match(line)
+ if pmatch:
+ in_props = True
+ elif in_props:
+ linetok = line.split()
+ if linetok[0] == 'string':
+ testname = linetok[1]
+ testval = linetok[2]
+ if testname == propname:
+ if noupdate == False:
+ print('string ' + propstring, file=ofile)
+ printed = True
+ done = True
+
+ ematch = endrex.match(line)
+ if ematch:
+ if in_props == False:
+ print('<< properties >>', file=ofile)
+ if done == False:
+ print('string ' + propstring, file=ofile)
+
+ if not printed:
+ print(line, file=ofile)
+ printed = False
+
+def usage():
+ print("insert_property.py <path_to_pdk> <libname> <cellname> <prop_string> [option]")
+ print(" options:")
+ print(" -mag do only for the view in the mag/ directory")
+ print(" -maglef do only for the view in the maglef/ directory")
+ print(" -noupdate do not replace the property if it already exists in the file")
+ return 0
+
+if __name__ == '__main__':
+
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ if len(arguments) < 4:
+ print("Not enough options given to insert_property.py.")
+ usage()
+ sys.exit(0)
+
+ source = arguments[0]
+ libname = arguments[1]
+ cellname = arguments[2]
+ propstring = arguments[3]
+
+ noupdate = True if '-noupdate' in options else False
+ fail = 0
+
+ efformat = True if '-ef_format' in options else False
+
+ domag = True
+ domaglef = True
+ if '-mag' in options and '-maglef' not in options:
+ domaglef = False
+ if '-maglef' in options and '-mag' not in options:
+ domag = False
+
+ if domag:
+ if efformat:
+ filename = source + '/libs.ref/mag/' + libname + '/' + cellname + '.mag'
+ else:
+ filename = source + '/libs.ref/' + libname + '/mag/' + cellname + '.mag'
+
+ if os.path.isfile(filename):
+ addprop(filename, propstring, noupdate)
+ else:
+ fail += 1
+ else:
+ fail += 1
+
+ if domaglef:
+ if efformat:
+ filename = source + '/libs.ref/maglef/' + libname + '/' + cellname + '.mag'
+ else:
+ filename = source + '/libs.ref/' + libname + '/maglef/' + cellname + '.mag'
+
+ if os.path.isfile(filename):
+ addprop(filename, propstring, noupdate)
+ else:
+ fail += 1
+ else:
+ fail += 1
+
+ if fail == 2:
+ print('Error: No layout file in either mag/ or maglef/', file=sys.stderr)
+ if efformat:
+ print('(' + source + '/libs.ref/mag[lef]/' + libname +
+ '/' + cellname + '.mag)', file=sys.stderr)
+ else:
+ print('(' + source + '/libs.ref/' + libname + '/mag[lef]/'
+ + cellname + '.mag)', file=sys.stderr)
+
diff --git a/common/makestub.py b/common/makestub.py
new file mode 100755
index 0000000..a5334d7
--- /dev/null
+++ b/common/makestub.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+#
+#-------------------------------------------------------------------
+# makestub.py
+#
+# Read a CDL or SPICE netlist and remove all contents from subcircuits,
+# leaving only the .SUBCKT ... .ENDS wrapper. Used as a filter, so it
+# replaces the original file with the modified one. If the original
+# file is a symbolic link, then it is first unlinked and replaced with
+# the new contents.
+#
+# Use:
+#
+# makestub.py <path_to_netlist_file>
+#
+#-------------------------------------------------------------------
+
+import os
+import re
+import sys
+import stat
+import textwrap
+
+def makeuserwritable(filepath):
+ if os.path.exists(filepath):
+ st = os.stat(filepath)
+ os.chmod(filepath, st.st_mode | stat.S_IWUSR)
+
+def generate_stubs(netlist_path, output_path):
+ netlist_dir = os.path.split(netlist_path)[0]
+ netlist_filename = os.path.split(netlist_path)[1]
+ netlist_root = os.path.splitext(netlist_filename)[0]
+ netlist_ext = os.path.splitext(netlist_filename)[1]
+
+ if not os.path.exists(netlist_path):
+ print('Error: Specified file "' + netlist_path + '" does not exist!')
+ return
+
+ if output_path == None:
+ output_path = netlist_path
+
+ with open(netlist_path, 'r') as ifile:
+ spicetext = ifile.read().splitlines()
+
+ # Remove blank lines and comment lines
+ spicelines = []
+ for line in spicetext:
+ if len(line) > 0:
+ if line[0] != '*':
+ spicelines.append(line)
+
+ # Remove line extensions
+ spicetext = '\n'.join(spicelines)
+ spicelines = spicetext.replace('\n+', ' ').splitlines()
+
+ # SPICE subcircuit definition:
+ subcrex = re.compile(r'[ \t]*\.subckt[ \t]+([^ \t]+)[ \t]+(.*)$', re.IGNORECASE)
+ endsrex = re.compile(r'[ \t]*\.ends[ \t]*', re.IGNORECASE)
+
+ spiceoutlines = []
+
+ insub = False
+ for line in spicelines:
+ if insub:
+ ematch = endsrex.match(line)
+ if ematch:
+ insub = False
+ spiceoutlines.append(line)
+ else:
+ smatch = subcrex.match(line)
+ if smatch:
+ insub = True
+ spiceoutlines.append('')
+ spiceoutlines.append('*----------------------------------------------')
+ spiceoutlines.append('* SPICE stub entry for ' + smatch.group(1) + '.')
+ spiceoutlines.append('*----------------------------------------------')
+ spiceoutlines.append('')
+ spiceoutlines.append(line)
+
+ if output_path == netlist_path:
+ if os.path.islink(netlist_path):
+ os.unlink(netlist_path)
+
+ # Re-wrap continuation lines at 100 characters
+ wrappedlines = []
+ for line in spiceoutlines:
+ wrappedlines.append('\n+ '.join(textwrap.wrap(line, 100)))
+
+ # Just in case the file in the source repo is not user-writable
+ if os.path.exists(output_path):
+ makeuserwritable(output_path)
+
+ with open(output_path, 'w') as ofile:
+ for line in wrappedlines:
+ print(line, file=ofile)
+
+# If called as main, run generate_stubs
+
+if __name__ == '__main__':
+
+ # Divide up command line into options and arguments
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ # Need one argument: path to CDL or SPICE netlist
+ # If two arguments, then 2nd argument is the output file.
+
+ if len(arguments) == 2:
+ netlist_path = arguments[0]
+ output_path = arguments[1]
+ generate_stubs(netlist_path, output_path)
+ elif len(arguments) != 1:
+ print("Usage: makestub.py <file_path> [<output_path>]")
+ elif len(arguments) == 1:
+ netlist_path = arguments[0]
+ generate_stubs(netlist_path, None)
+
diff --git a/common/orig/foundry_install.py b/common/orig/foundry_install.py
new file mode 100755
index 0000000..96caf14
--- /dev/null
+++ b/common/orig/foundry_install.py
@@ -0,0 +1,1175 @@
+#!/usr/bin/env python3
+#
+# foundry_install.py
+#
+# This file generates the local directory structure and populates the
+# directories with foundry vendor data.
+#
+# 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)
+# -ef_names Use efabless naming (libs.ref/techLEF),
+# otherwise use generic naming (libs.tech/lef)
+#
+# -source <path> Path to source data top level directory
+# -target <path> Path to target top level directory
+#
+#
+# All other options represent paths to vendor files. They may all be
+# wildcarded with "*" to represent, e.g., version number directories,
+# or names of supported libraries. Where wildcards exist, if there is
+# more than one directory in the path, the value represented by "*"
+# will first be checked against library names. If no library name is
+# found, then the wildcard value will be assumed to be numeric and
+# separated by either "." or "_" to represent major/minor/sub/...
+# revision numbers (alphanumeric).
+#
+# Note only one of "-spice" or "-cdl" need be specified. Since the
+# open source tools use ngspice, CDL files are converted to ngspice
+# syntax when needed.
+#
+# -techlef <path> Path to technology LEF file
+# -doc <path> Path to technology documentation
+# -lef <path> Path to LEF file
+# -lefanno <path> Path to LEF file (for annotation only)
+# -spice <path> Path to SPICE netlists
+# -cdl <path> Path to CDL netlists
+# -models <path> Path to SPICE (primitive device) models
+# -liberty <path> Path to Liberty timing files
+# -gds <path> Path to GDS data
+# -verilog <path> Path to verilog models
+#
+# -library <type> <name> [<target>] See below
+#
+# For the "-library" option, any number of libraries may be supported, and
+# one "-library" option should be provided for each supported library.
+# <type> is one of: "digital", "primitive", or "general". Analog and I/O
+# libraries fall under the category "general", as they are all treated the
+# same way. <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).
+#
+# All options "-lef", "-spice", etc., can take the additional arguments
+# up <number>
+#
+# to indicate that the source hierarchy should be copied from <number>
+# levels above the files. 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/lef/<libname>/*.lib
+# while
+#
+# -liberty x/y/z/PVT_*/*.lib up 1
+#
+# would install all .lib files into libs.ref/lef/PVT_*/<libname>/*.lib
+#
+# Other library-specific arguments are:
+#
+# nospec : Remove timing specification before installing
+# (used with verilog files; needs to 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.
+#
+# NOTE: This script can be called once for all libraries if all file
+# types (gds, cdl, lef, etc.) happen to all work with the same wildcards.
+# However, it is more likely that it will be called several times for the
+# same PDK, once to install I/O cells, once to install digital, and so
+# forth, as made possible by the wild-carding.
+
+import re
+import os
+import sys
+import glob
+import shutil
+import subprocess
+
+def usage():
+ print("foundry_install.py [options...]")
+ print(" -link_from <name> Make symbolic links from target to <name>")
+ print(" where <name> can be 'source' or a PDK name.")
+ print(" Default behavior is to copy all files.")
+ print(" -copy Copy files from source to target (default)")
+ print(" -ef_names Use efabless naming conventions for local directories")
+ print("")
+ print(" -source <path> Path to top of source directory tree")
+ print(" -target <path> Path to top of target directory tree")
+ print("")
+ print(" -techlef <path> Path to technology LEF file")
+ print(" -doc <path> Path to technology documentation")
+ print(" -lef <path> Path to LEF file")
+ print(" -lefanno <path> Path to LEF file (for annotation only)")
+ print(" -spice <path> Path to SPICE netlists")
+ print(" -cdl <path> Path to CDL netlists")
+ print(" -models <path> Path to SPICE (primitive device) models")
+ print(" -lib <path> Path to Liberty timing files")
+ print(" -liberty <path> Path to Liberty timing files")
+ print(" -gds <path> Path to GDS data")
+ print(" -verilog <path> Path to verilog models")
+ print(" -library <type> <name> [<target>] See below")
+ print("")
+ print(" All <path> names may be wild-carded with '*' ('glob'-style wild-cards)")
+ print("")
+ print(" All options with <path> other than source and target may take the additional")
+ print(" arguments 'up <number>', where <number> indicates the number of levels of")
+ print(" hierarchy of the source path to include when copying to the target.")
+ print("")
+ print(" Library <type> may be one of:")
+ print(" digital Digital standard cell library")
+ print(" primitive Primitive device library")
+ print(" general All other library types (I/O, analog, etc.)")
+ print("")
+ print(" If <target> is unspecified then <name> is used for the target.")
+
+def get_gds_properties(magfile):
+ proprex = re.compile('^[ \t]*string[ \t]+(GDS_[^ \t]+)[ \t]+([^ \t]+)$')
+ proplines = []
+ if os.path.isfile(magfile):
+ with open(magfile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+ for line in magtext:
+ lmatch = proprex.match(line)
+ if lmatch:
+ propline = lmatch.group(1) + ' ' + lmatch.group(2)
+ proplines.append(propline)
+ return proplines
+
+# Read subcircuit ports from a CDL file, given a subcircuit name that should
+# appear in the file as a subcircuit entry, and return a dictionary of ports
+# and their indexes in the subcircuit line.
+
+def get_subckt_ports(cdlfile, subname):
+ portdict = {}
+ pidx = 1
+ portrex = re.compile('^\.subckt[ \t]+([^ \t]+)[ \t]+(.*)$', re.IGNORECASE)
+ with open(cdlfile, 'r') as ifile:
+ cdltext = ifile.read()
+ cdllines = cdltext.replace('\n+', ' ').splitlines()
+ for line in cdllines:
+ lmatch = portrex.match(line)
+ if lmatch:
+ if lmatch.group(1).lower() == subname.lower():
+ ports = lmatch.group(2).split()
+ for port in ports:
+ portdict[port.lower()] = pidx
+ pidx += 1
+ break
+ return portdict
+
+# Filter a verilog file to remove any backslash continuation lines, which
+# iverilog does not parse. If targetroot is a directory, then find and
+# process all files in the path of targetroot. If any file to be processed
+# is unmodified (has no backslash continuation lines), then ignore it. If
+# any file is a symbolic link and gets modified, then remove the symbolic
+# link before overwriting with the modified file.
+#
+# If 'do_remove_spec' is True, then remove timing information from the file,
+# which is everything between the keywords "specify" and "endspecify".
+
+def vfilefilter(vfile, do_remove_spec):
+ modified = False
+ with open(vfile, 'r') as ifile:
+ vtext = ifile.read()
+
+ # Remove backslash-followed-by-newline and absorb initial whitespace. It
+ # is unclear what initial whitespace means in this context, as the use-
+ # case that has been seen seems to work under the assumption that leading
+ # whitespace is ignored up to the amount used by the last indentation.
+
+ vlines = re.sub('\\\\\n[ \t]*', '', vtext)
+
+ if do_remove_spec:
+ specrex = re.compile('\n[ \t]*specify[ \t\n]+')
+ endspecrex = re.compile('\n[ \t]*endspecify')
+ smatch = specrex.search(vlines)
+ while smatch:
+ specstart = smatch.start()
+ specpos = smatch.end()
+ ematch = endspecrex.search(vlines[specpos:])
+ specend = ematch.end()
+ vtemp = vlines[0:specstart + 1] + vlines[specpos + specend + 1:]
+ vlines = vtemp
+ smatch = specrex.search(vlines)
+
+ if vlines != vtext:
+ # File contents have been modified, so if this file was a symbolic
+ # link, then remove it. Otherwise, overwrite the file with the
+ # modified contents.
+ if os.path.islink(vfile):
+ os.unlink(vfile)
+ with open(vfile, 'w') as ofile:
+ ofile.write(vlines)
+
+# Run a filter on verilog files that cleans up known syntax issues.
+# This is embedded in the foundry_install script and is not a custom
+# filter largely because the issues are in the tool, not the PDK.
+
+def vfilter(targetroot, do_remove_spec):
+ if os.path.isfile(targetroot):
+ vfilefilter(targetroot, do_remove_spec)
+ else:
+ vlist = glob.glob(targetroot + '/*')
+ for vfile in vlist:
+ if os.path.isfile(vfile):
+ vfilefilter(vfile, do_remove_spec)
+
+# For issues that are PDK-specific, a script can be written and put in
+# the PDK's custom/scripts/ directory, and passed to the foundry_install
+# script using the "filter" option.
+
+def tfilter(targetroot, filterscript):
+ if os.path.isfile(targetroot):
+ print(' Filtering file ' + targetroot)
+ subprocess.run([filterscript, targetroot, targetroot],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+ else:
+ tlist = glob.glob(targetroot + '/*')
+ for tfile in tlist:
+ if os.path.isfile(tfile):
+ print(' Filtering file ' + tfile)
+ subprocess.run([filterscript, tfile, tfile],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+
+# This is the main entry point for the foundry install script.
+
+if __name__ == '__main__':
+
+ if len(sys.argv) == 1:
+ print("No options given to foundry_install.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ newopt = []
+
+ sourcedir = None
+ targetdir = None
+ link_from = None
+
+ ef_names = False
+
+ have_lef = False
+ have_lefanno = False
+ have_gds = False
+ have_spice = False
+ have_cdl = False
+ ignorelist = []
+
+ do_install = True
+
+ # Break arguments into groups where the first word begins with "-".
+ # All following words not beginning with "-" are appended to the
+ # same list (optionlist). Then each optionlist is processed.
+ # Note that the first entry in optionlist has the '-' removed.
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ if newopt != []:
+ optionlist.append(newopt)
+ newopt = []
+ newopt.append(option[1:])
+ else:
+ newopt.append(option)
+
+ if newopt != []:
+ optionlist.append(newopt)
+
+ # Pull library names from optionlist
+ libraries = []
+ for option in optionlist[:]:
+ if option[0] == 'library':
+ optionlist.remove(option)
+ libraries.append(option[1:])
+
+ # Check for option "ef_names" or "std_names"
+ for option in optionlist[:]:
+ if option[0] == 'ef_naming' or option[0] == 'ef_names':
+ optionlist.remove(option)
+ ef_names = True
+ elif option[0] == 'std_naming' or option[0] == 'std_names':
+ optionlist.remove(option)
+ ef_names = False
+ elif option[0] == 'uninstall':
+ optionlist.remove(option)
+ do_install = False
+
+ # Check for options "link_from", "source", and "target"
+ link_name = None
+ for option in optionlist[:]:
+ if option[0] == 'link_from':
+ optionlist.remove(option)
+ if option[1].lower() == 'none':
+ link_from = None
+ elif option[1].lower() == 'source':
+ link_from = 'source'
+ else:
+ link_from = option[1]
+ link_name = os.path.split(link_from)[1]
+ elif option[0] == 'source':
+ optionlist.remove(option)
+ sourcedir = option[1]
+ elif option[0] == 'target':
+ optionlist.remove(option)
+ targetdir = option[1]
+
+ # Error if no source or dest specified
+ if not sourcedir:
+ print("No source directory specified. Exiting.")
+ sys.exit(1)
+
+ if not targetdir:
+ print("No target directory specified. Exiting.")
+ sys.exit(1)
+
+ # If link source is a PDK name, if it has no path, then pull the
+ # path from the target name.
+
+ if link_from:
+ if link_from != 'source':
+ if link_from.find('/', 0) < 0:
+ target_root = os.path.split(targetdir)[0]
+ link_from = target_root + '/' + link_from
+ link_name = link_from
+ else:
+ # If linking from source, convert the source path to an
+ # absolute pathname.
+ sourcedir = os.path.abspath(sourcedir)
+
+ # Take the target PDK name from the target path last component
+ pdkname = os.path.split(targetdir)[1]
+
+ # checkdir is the DIST target directory for the PDK pointed
+ # to by link_name. Files must be found there before creating
+ # symbolic links to the (not yet existing) final install location.
+
+ if link_name:
+ checkdir = os.path.split(targetdir)[0] + '/' + link_name
+ else:
+ checkdir = ''
+
+ # Diagnostic
+ if do_install:
+ print("Installing in target directory " + targetdir)
+
+ # Create the top-level directories
+
+ os.makedirs(targetdir, exist_ok=True)
+ os.makedirs(targetdir + '/libs.ref', exist_ok=True)
+ os.makedirs(targetdir + '/libs.tech', exist_ok=True)
+
+ # Path to magic techfile depends on ef_names
+
+ if ef_names == True:
+ mag_current = '/libs.tech/magic/current/'
+ else:
+ mag_current = '/libs.tech/magic/'
+
+ # Populate the techLEF and SPICE models, if specified.
+
+ for option in optionlist[:]:
+ if option[0] == 'techlef':
+ filter_script = None
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_script = item.split('=')[1]
+ break
+
+ if ef_names == True:
+ techlefdir = targetdir + '/libs.ref/techLEF'
+ checklefdir = checkdir + '/libs.ref/techLEF'
+ if link_from:
+ linklefdir = link_from + '/libs.ref/techLEF'
+ else:
+ linklefdir = ''
+ else:
+ techlefdir = targetdir + '/libs.tech/lef'
+ checklefdir = checkdir + '/libs.tech/lef'
+ if link_from:
+ linklefdir = link_from + '/libs.tech/lef'
+ else:
+ linklefdir = ''
+ os.makedirs(techlefdir, exist_ok=True)
+ # All techlef files should be linked or copied, so use "glob"
+ # on the wildcards
+ techlist = glob.glob(sourcedir + '/' + option[1])
+
+ for lefname in techlist:
+ leffile = os.path.split(lefname)[1]
+ targname = techlefdir + '/' + leffile
+ checklefname = checklefdir + '/' + leffile
+ linklefname = linklefdir + '/' + leffile
+ # Remove any existing file(s)
+ if os.path.isfile(targname):
+ os.remove(targname)
+ elif os.path.islink(targname):
+ os.unlink(targname)
+ elif os.path.isdir(targname):
+ shutil.rmtree(targname)
+
+ if do_install:
+ if not link_from:
+ if os.path.isfile(lefname):
+ shutil.copy(lefname, targname)
+ else:
+ shutil.copytree(lefname, targname)
+ elif link_from == 'source':
+ os.symlink(lefname, targname)
+ else:
+ if os.path.exists(checklefname):
+ os.symlink(linklefname, targname)
+ elif os.path.isfile(lefname):
+ shutil.copy(lefname, targname)
+ else:
+ shutil.copytree(lefname, targname)
+
+ if filter_script:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+ optionlist.remove(option)
+
+ elif option[0] == 'models':
+ filter_script = None
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_script = item.split('=')[1]
+ break
+
+ print('Diagnostic: installing models.')
+ modelsdir = targetdir + '/libs.tech/models'
+ checkmoddir = checkdir + '/libs.tech/models'
+ if link_from:
+ linkmoddir = link_from + '/libs.tech/models'
+ else:
+ linkmoddir = ''
+
+ os.makedirs(modelsdir, exist_ok=True)
+
+ # All model files should be linked or copied, so use "glob"
+ # on the wildcards. Copy each file and recursively copy each
+ # directory.
+ modellist = glob.glob(sourcedir + '/' + option[1])
+
+ for modname in modellist:
+ modfile = os.path.split(modname)[1]
+ targname = modelsdir + '/' + modfile
+ checkmodname = checkmoddir + '/' + modfile
+ linkmodname = linkmoddir + '/' + modfile
+
+ if os.path.isdir(modname):
+ # Remove any existing directory, and its contents
+ if os.path.isdir(targname):
+ shutil.rmtree(targname)
+ os.makedirs(targname)
+
+ # Recursively find and copy or link the whole directory
+ # tree from this point.
+
+ allmodlist = glob.glob(modname + '/**', recursive=True)
+ commonpart = os.path.commonpath(allmodlist)
+ for submodname in allmodlist:
+ if os.path.isdir(submodname):
+ continue
+ # Get the path part that is not common between modlist and
+ # allmodlist.
+ subpart = os.path.relpath(submodname, commonpart)
+ subtargname = targname + '/' + subpart
+ os.makedirs(os.path.split(subtargname)[0], exist_ok=True)
+ if do_install:
+ if not link_from:
+ if os.path.isfile(submodname):
+ shutil.copy(submodname, subtargname)
+ else:
+ shutil.copytree(submodname, subtargname)
+ elif link_from == 'source':
+ os.symlink(submodname, subtargname)
+ else:
+ if os.path.exists(checkmodname):
+ os.symlink(linkmodname, subtargname)
+ elif os.path.isfile(submodname):
+ shutil.copy(submodname, subtargname)
+ else:
+ shutil.copytree(submodname, subtargname)
+
+ if filter_script:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ else:
+ # Remove any existing file
+ if os.path.isfile(targname):
+ os.remove(targname)
+ elif os.path.islink(targname):
+ os.unlink(targname)
+ elif os.path.isdir(targname):
+ shutil.rmtree(targname)
+
+ if do_install:
+ if not link_from:
+ if os.path.isfile(modname):
+ shutil.copy(modname, targname)
+ else:
+ shutil.copytree(modname, targname)
+ elif link_from == 'source':
+ os.symlink(modname, targname)
+ else:
+ if os.path.isfile(checkmodname):
+ os.symlink(linkmodname, targname)
+ elif os.path.isfile(modname):
+ shutil.copy(modname, targname)
+ else:
+ shutil.copytree(modname, targname)
+
+ if filter_script:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ optionlist.remove(option)
+
+ # The remaining options in optionlist should all be types like 'lef' or 'liberty'
+ for option in optionlist[:]:
+ # Diagnostic
+ if do_install:
+ print("Installing option: " + str(option[0]))
+ destdir = targetdir + '/libs.ref/' + option[0]
+ checklibdir = checkdir + '/libs.ref/' + option[0]
+ if link_from:
+ destlinkdir = link_from + '/libs.ref/' + option[0]
+ else:
+ destlinkdir = ''
+ os.makedirs(destdir, exist_ok=True)
+
+ # If the option is followed by the keyword "up" and a number, then
+ # the source should be copied (or linked) from <number> levels up
+ # in the hierarchy (see below).
+
+ if 'up' in option:
+ uparg = option.index('up')
+ try:
+ hier_up = int(option[uparg + 1])
+ except:
+ print("Non-numeric option to 'up': " + option[uparg + 1])
+ print("Ignoring 'up' option.")
+ hier_up = 0
+ else:
+ hier_up = 0
+
+ filter_script = None
+ for item in option:
+ if item.split('=')[0] == 'filter':
+ filter_script = item.split('=')[1]
+ break
+
+ # Option 'compile' is a standalone keyword ('comp' may be used).
+ do_compile = 'compile' in option or 'comp' in option
+
+ # Option 'nospecify' is a standalone keyword ('nospec' may be used).
+ do_remove_spec = 'nospecify' in option or 'nospec' in option
+
+ # Check off things we need to do migration to magic database and
+ # abstact files.
+ if option[0] == 'lef':
+ have_lef = True
+ elif option[0] == 'gds':
+ have_gds = True
+ elif option[0] == 'lefanno':
+ have_lefanno = True
+ elif option[0] == 'spice':
+ have_spice = True
+ elif option[0] == 'cdl':
+ have_cdl = True
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+ destlibdir = destdir + '/' + destlib
+ destlinklibdir = destlinkdir + '/' + destlib
+ checksrclibdir = checklibdir + '/' + destlib
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Populate the library subdirectory
+ # Parse the option and replace each '/*/' with the library name,
+ # and check if it is a valid directory name. Then glob the
+ # resulting option name. Warning: This assumes that all
+ # occurences of the text '/*/' match a library name. It should
+ # be possible to wild-card the directory name in such a way that
+ # this is always true.
+
+ testopt = re.sub('\/\*\/', '/' + library[1] + '/', option[1])
+
+ liblist = glob.glob(sourcedir + '/' + testopt)
+
+ # Diagnostic
+ print('Collecting files from ' + str(sourcedir + '/' + testopt))
+ print('Files to install:')
+ if len(liblist) < 10:
+ for item in liblist:
+ print(' ' + item)
+ else:
+ for item in liblist[0:4]:
+ print(' ' + item)
+ print(' .')
+ print(' .')
+ print(' .')
+ for item in liblist[-6:-1]:
+ print(' ' + item)
+ print('(' + str(len(liblist)) + ' files total)')
+
+ for libname in liblist:
+ # Note that there may be a hierarchy to the files in option[1],
+ # say for liberty timing files under different conditions, so
+ # make sure directories have been created as needed.
+
+ libfile = os.path.split(libname)[1]
+ libfilepath = os.path.split(libname)[0]
+ destpathcomp = []
+ for i in range(hier_up):
+ destpathcomp.append('/' + os.path.split(libfilepath)[1])
+ libfilepath = os.path.split(libfilepath)[0]
+ destpathcomp.reverse()
+ destpath = ''.join(destpathcomp)
+
+ targname = destlibdir + destpath + '/' + libfile
+
+ # NOTE: When using "up" with link_from, could just make
+ # destpath itself a symbolic link; this way is more flexible
+ # but adds one symbolic link per file.
+
+ if destpath != '':
+ if not os.path.isdir(destlibdir + destpath):
+ os.makedirs(destlibdir + destpath, exist_ok=True)
+
+ # Both linklibname and checklibname need to contain any hierarchy
+ # implied by the "up" option.
+
+ linklibname = destlinklibdir + destpath + '/' + libfile
+ checklibname = checksrclibdir + destpath + '/' + libfile
+
+ # Remove any existing file
+ if os.path.isfile(targname):
+ os.remove(targname)
+ elif os.path.islink(targname):
+ os.unlink(targname)
+ elif os.path.isdir(targname):
+ shutil.rmtree(targname)
+
+ if do_install:
+ if not link_from:
+ if os.path.isfile(libname):
+ shutil.copy(libname, targname)
+ else:
+ shutil.copytree(libname, targname)
+ elif link_from == 'source':
+ os.symlink(libname, targname)
+ else:
+ if os.path.exists(checklibname):
+ os.symlink(linklibname, targname)
+ elif os.path.isfile(libname):
+ shutil.copy(libname, targname)
+ else:
+ shutil.copytree(libname, targname)
+
+ if option[0] == 'verilog':
+ # Special handling of verilog files to make them
+ # syntactically acceptable to iverilog.
+ # NOTE: Perhaps this should be recast as a custom filter?
+ vfilter(targname, do_remove_spec)
+
+ if filter_script:
+ # Apply filter script to all files in the target directory
+ tfilter(targname, filter_script)
+
+ if do_compile == True:
+ # To do: Extend this option to include formats other than verilog.
+ # Also to do: Make this compatible with linking from another PDK.
+
+ if option[0] == 'verilog':
+ # If there is not a single file with all verilog cells in it,
+ # then compile one, because one does not want to have to have
+ # an include line for every single cell used in a design.
+
+ alllibname = destlibdir + '/' + destlib + '.v'
+
+ print('Diagnostic: Creating consolidated verilog library ' + destlib + '.v')
+ vlist = glob.glob(destlibdir + '/*.v')
+ if alllibname in vlist:
+ vlist.remove(alllibname)
+
+ if len(vlist) > 1:
+ print('New file is: ' + alllibname)
+ with open(alllibname, 'w') as ofile:
+ for vfile in vlist:
+ with open(vfile, 'r') as ifile:
+ # print('Adding ' + vfile + ' to library.')
+ vtext = ifile.read()
+ # NOTE: The following workaround resolves an
+ # issue with iverilog, which does not properly
+ # parse specify timing paths that are not in
+ # parentheses. Easy to work around
+ vlines = re.sub(r'\)[ \t]*=[ \t]*([01]:[01]:[01])[ \t]*;', r') = ( \1 ) ;', vtext)
+ print(vlines, file=ofile)
+ print('\n//--------EOF---------\n', file=ofile)
+ else:
+ print('Only one file (' + str(vlist) + '); ignoring "compile" option.')
+
+ print("Completed installation of vendor files.")
+
+ # Now for the harder part. If GDS and/or LEF databases were specified,
+ # then migrate them to magic (.mag files in layout/ or abstract/).
+
+ ignore = []
+ do_cdl_scaleu = False
+ for option in optionlist[:]:
+ if option[0] == 'cdl':
+ # Option 'scaleu' is a standalone keyword
+ do_cdl_scaleu = 'scaleu' in option
+
+ # Option 'ignore' has arguments after '='
+ for item in option:
+ if item.split('=')[0] == 'ignore':
+ ignorelist = item.split('=')[1].split(',')
+
+ devlist = []
+ pdklibrary = None
+
+ if have_gds:
+ print("Migrating GDS files to layout.")
+ destdir = targetdir + '/libs.ref/mag'
+ srcdir = targetdir + '/libs.ref/gds'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # For primitive devices, check the PDK script and find the name
+ # of the library and get a list of supported devices.
+
+ if library[0] == 'primitive':
+ pdkscript = targetdir + mag_current + pdkname + '.tcl'
+ print('Searching for supported devices in PDK script ' + pdkscript + '.')
+
+ if os.path.isfile(pdkscript):
+ librex = re.compile('^[ \t]*set[ \t]+PDKNAMESPACE[ \t]+([^ \t]+)$')
+ devrex = re.compile('^[ \t]*proc[ \t]+([^ :\t]+)::([^ \t_]+)_defaults')
+ fixrex = re.compile('^[ \t]*return[ \t]+\[([^ :\t]+)::fixed_draw[ \t]+([^ \t]+)[ \t]+')
+ devlist = []
+ fixedlist = []
+ with open(pdkscript, 'r') as ifile:
+ scripttext = ifile.read().splitlines()
+ for line in scripttext:
+ lmatch = librex.match(line)
+ if lmatch:
+ pdklibrary = lmatch.group(1)
+ dmatch = devrex.match(line)
+ if dmatch:
+ if dmatch.group(1) == pdklibrary:
+ devlist.append(dmatch.group(2))
+ fmatch = fixrex.match(line)
+ if fmatch:
+ if fmatch.group(1) == pdklibrary:
+ fixedlist.append(fmatch.group(2))
+
+ # Diagnostic
+ print("PDK library is " + str(pdklibrary))
+
+ # Link to the PDK magic startup file from the target directory
+ # If there is no -F version then look for one without -F (open source PDK)
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+
+ if os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # Find GDS file names in the source
+ print('Getting GDS file list from ' + srclibdir + '.')
+ gdsfiles = os.listdir(srclibdir)
+
+ # Generate a script called "generate_magic.tcl" and leave it in
+ # the target directory. Use it as input to magic to create the
+ # .mag files from the database.
+
+ print('Creating magic generation script.')
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('# Script to generate .mag files from .gds ', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('gds readonly true', file=ofile)
+ print('gds flatten true', file=ofile)
+ # print('gds rescale false', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ for gdsfile in gdsfiles:
+ # Note: DO NOT use a relative path here.
+ # print('gds read ../../gds/' + destlib + '/' + gdsfile, file=ofile)
+ print('gds read ' + srclibdir + '/' + gdsfile, file=ofile)
+
+ # Make sure properties include the Tcl generated cell
+ # information from the PDK script
+
+ if pdklibrary:
+ tclfixedlist = '{' + ' '.join(fixedlist) + '}'
+ print('set devlist ' + tclfixedlist, file=ofile)
+ print('set topcell [lindex [cellname list top] 0]',
+ file=ofile)
+
+ print('foreach cellname $devlist {', file=ofile)
+ print(' load $cellname', file=ofile)
+ print(' property gencell $cellname', file=ofile)
+ print(' property parameter m=1', file=ofile)
+ print(' property library ' + pdklibrary, file=ofile)
+ print('}', file=ofile)
+ print('load $topcell', file=ofile)
+
+ print('writeall force', file=ofile)
+
+ if have_lefanno:
+ # Find LEF file names in the source
+ lefsrcdir = targetdir + '/libs.ref/lefanno'
+ lefsrclibdir = lefsrcdir + '/' + destlib
+ leffiles = list(item for item in os.listdir(lefsrclibdir) if os.path.splitext(item)[1] == '.lef')
+
+ if not have_lef:
+ # This library has a GDS database but no LEF database. Use
+ # magic to create abstract views of the GDS cells. If
+ # option "-lefanno" is given, then read the LEF file after
+ # loading the database file to annotate the cell with
+ # information from the LEF file. This usually indicates
+ # that the LEF file has some weird definition of obstruction
+ # layers and we want to normalize them by using magic's LEF
+ # write procedure, but we still need the pin use and class
+ # information from the LEF file, and maybe the bounding box.
+
+ print('set maglist [glob *.mag]', file=ofile)
+ print('foreach name $maglist {', file=ofile)
+ print(' load [file root $name]', file=ofile)
+ if have_lefanno:
+ print('}', file=ofile)
+ for leffile in leffiles:
+ print('lef read ' + lefsrclibdir + '/' + leffile, file=ofile)
+ print('foreach name $maglist {', file=ofile)
+ print(' load [file root $name]', file=ofile)
+ print(' lef write [file root $name]', file=ofile)
+ print('}', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ # Run magic to read in the GDS file and write out magic databases.
+ with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
+ subprocess.run(['magic', '-dnull', '-noconsole'],
+ stdin = ifile, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+
+ if not have_lef:
+ # Remove the lefanno/ target and its contents.
+ if have_lefanno:
+ lefannosrcdir = targetdir + '/libs.ref/lefanno'
+ if os.path.isdir(lefannosrcdir):
+ shutil.rmtree(lefannosrcdir)
+
+ destlefdir = targetdir + '/libs.ref/lef'
+ destleflibdir = destlefdir + '/' + destlib
+ os.makedirs(destleflibdir, exist_ok=True)
+ leflist = list(item for item in os.listdir(destlibdir) if os.path.splitext(item)[1] == '.lef')
+
+ # All macros will go into one file
+ destleflib = destleflibdir + '/' + destlib + '.lef'
+ # Remove any existing library file from the target directory
+ if os.path.isfile(destleflib):
+ os.remove(destleflib)
+
+ first = True
+ with open(destleflib, 'w') as ofile:
+ for leffile in leflist:
+ # Remove any existing single file from the target directory
+ if os.path.isfile(destleflibdir + '/' + leffile):
+ os.remove(destleflibdir + '/' + leffile)
+
+ # Append contents
+ sourcelef = destlibdir + '/' + leffile
+ with open(sourcelef, 'r') as ifile:
+ leflines = ifile.read().splitlines()
+ if not first:
+ # Remove header from all but the first file
+ leflines = leflines[8:]
+ else:
+ first = False
+
+ for line in leflines:
+ print(line, file=ofile)
+
+ # Remove file from the source directory
+ os.remove(sourcelef)
+
+ have_lef = True
+
+ # Remove the startup script and generation script
+ os.remove(destlibdir + '/.magicrc')
+ os.remove(destlibdir + '/generate_magic.tcl')
+ else:
+ print("Master PDK magic startup file not found. Did you install")
+ print("PDK tech files before PDK vendor files?")
+
+ if have_lef:
+ print("Migrating LEF files to layout.")
+ destdir = targetdir + '/libs.ref/maglef'
+ srcdir = targetdir + '/libs.ref/lef'
+ magdir = targetdir + '/libs.ref/mag'
+ cdldir = targetdir + '/libs.ref/cdl'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ maglibdir = magdir + '/' + destlib
+ cdllibdir = cdldir + '/' + destlib
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Link to the PDK magic startup file from the target directory
+ startup_script = targetdir + mag_current + pdkname + '-F.magicrc'
+ if not os.path.isfile(startup_script):
+ startup_script = targetdir + mag_current + pdkname + '.magicrc'
+
+ if os.path.isfile(startup_script):
+ # If the symbolic link exists, remove it.
+ if os.path.isfile(destlibdir + '/.magicrc'):
+ os.remove(destlibdir + '/.magicrc')
+ os.symlink(startup_script, destlibdir + '/.magicrc')
+
+ # Find LEF file names in the source
+ leffiles = os.listdir(srclibdir)
+
+ # Generate a script called "generate_magic.tcl" and leave it in
+ # the target directory. Use it as input to magic to create the
+ # .mag files from the database.
+
+ with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
+ print('#!/usr/bin/env wish', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('# Script to generate .mag files from .lef ', file=ofile)
+ print('#--------------------------------------------', file=ofile)
+ print('tech unlock *', file=ofile)
+
+ if pdklibrary:
+ tcldevlist = '{' + ' '.join(devlist) + '}'
+ print('set devlist ' + tcldevlist, file=ofile)
+
+ for leffile in leffiles:
+
+ # Okay to use a relative path here.
+ # print('lef read ' + srclibdir + '/' + leffile', file=ofile)
+ print('lef read ../../lef/' + destlib + '/' + leffile, file=ofile)
+
+ # To be completed: Parse SPICE file for port order, make
+ # sure ports are present and ordered.
+
+ if pdklibrary:
+ print('set cellname [file root ' + leffile + ']', file=ofile)
+ print('if {[lsearch $devlist $cellname] >= 0} {',
+ file=ofile)
+ print(' load $cellname', file=ofile)
+ print(' property gencell $cellname', file=ofile)
+ print(' property parameter m=1', file=ofile)
+ print(' property library ' + pdklibrary, file=ofile)
+ print('}', file=ofile)
+
+ print('writeall force', file=ofile)
+ print('quit -noprompt', file=ofile)
+
+ # Run magic to read in the LEF file and write out magic databases.
+ with open(destlibdir + '/generate_magic.tcl', 'r') as ifile:
+ subprocess.run(['magic', '-dnull', '-noconsole'],
+ stdin = ifile, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+
+ # Now list all the .mag files generated, and for each, read the
+ # corresponding file from the mag/ directory, pull the GDS file
+ # properties, and add those properties to the maglef view. Also
+ # read the CDL (or SPICE) netlist, read the ports, and rewrite
+ # the port order in the mag and maglef file accordingly.
+
+ # Diagnostic
+ print('Annotating files in ' + destlibdir)
+ magfiles = os.listdir(destlibdir)
+ for magroot in magfiles:
+ magname = os.path.splitext(magroot)[0]
+ magfile = maglibdir + '/' + magroot
+ magleffile = destlibdir + '/' + magroot
+ prop_lines = get_gds_properties(magfile)
+
+ # Make sure properties include the Tcl generated cell
+ # information from the PDK script
+
+ if pdklibrary:
+ if magname in fixedlist:
+ prop_lines.append('string gencell ' + magname)
+ prop_lines.append('string library ' + pdklibrary)
+ prop_lines.append('string parameter m=1')
+
+ cdlfile = cdllibdir + '/' + magname + '.cdl'
+ if not os.path.exists(cdlfile):
+ # Assume there is one file with all cell subcircuits in it.
+ try:
+ cdlfile = glob.glob(cdllibdir + '/*.cdl')[0]
+ except:
+ print('No CDL file for ' + destlib + ' device ' + magname)
+ cdlfile = None
+ # To be done: If destlib is 'primitive', then look in
+ # SPICE models for port order.
+ if destlib == 'primitive':
+ print('Fix me: Need to look in SPICE models!')
+ if cdlfile:
+ port_dict = get_subckt_ports(cdlfile, magname)
+ else:
+ port_dict = {}
+
+ proprex = re.compile('<< properties >>')
+ endrex = re.compile('<< end >>')
+ rlabrex = re.compile('rlabel[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)')
+ flabrex = re.compile('flabel[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)')
+ portrex = re.compile('port[ \t]+([^ \t])+[ \t]+(.*)')
+ portnum = -1
+
+ with open(magleffile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ with open(magleffile, 'w') as ofile:
+ for line in magtext:
+ tmatch = portrex.match(line)
+ if tmatch:
+ if portnum >= 0:
+ line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
+ else:
+ line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
+ ematch = endrex.match(line)
+ if ematch and len(prop_lines) > 0:
+ print('<< properties >>', file=ofile)
+ for prop in prop_lines:
+ print('string ' + prop, file=ofile)
+
+ print(line, file=ofile)
+ pmatch = proprex.match(line)
+ if pmatch:
+ for prop in prop_lines:
+ print('string ' + prop, file=ofile)
+ prop_lines = []
+
+ lmatch = flabrex.match(line)
+ if not lmatch:
+ lmatch = rlabrex.match(line)
+ if lmatch:
+ labname = lmatch.group(1).lower()
+ try:
+ portnum = port_dict[labname]
+ except:
+ portnum = -1
+
+ if os.path.exists(magfile):
+ with open(magfile, 'r') as ifile:
+ magtext = ifile.read().splitlines()
+
+ with open(magfile, 'w') as ofile:
+ for line in magtext:
+ tmatch = portrex.match(line)
+ if tmatch:
+ if portnum >= 0:
+ line = 'port ' + str(portnum) + ' ' + tmatch.group(2)
+ else:
+ line = 'port ' + tmatch.group(1) + ' ' + tmatch.group(2)
+ ematch = endrex.match(line)
+ print(line, file=ofile)
+ lmatch = flabrex.match(line)
+ if not lmatch:
+ lmatch = rlabrex.match(line)
+ if lmatch:
+ labname = lmatch.group(1).lower()
+ try:
+ portnum = port_dict[labname]
+ except:
+ portnum = -1
+ elif os.path.splitext(magfile)[1] == '.mag':
+ # NOTE: Probably this means the GDS cell has a different name.
+ print('Error: No file ' + magfile + '. Why is it in maglef???')
+
+ # Remove the startup script and generation script
+ os.remove(destlibdir + '/.magicrc')
+ os.remove(destlibdir + '/generate_magic.tcl')
+ else:
+ print("Master PDK magic startup file not found. Did you install")
+ print("PDK tech files before PDK vendor files?")
+
+ # If SPICE or CDL databases were specified, then convert them to
+ # a form that can be used by ngspice, using the cdl2spi.py script
+
+ if have_spice:
+ if not os.path.isdir(targetdir + '/libs.ref/spi'):
+ os.makedirs(targetdir + '/libs.ref/spi', exist_ok=True)
+
+ elif have_cdl:
+ if not os.path.isdir(targetdir + '/libs.ref/spi'):
+ os.makedirs(targetdir + '/libs.ref/spi', exist_ok=True)
+
+ print("Migrating CDL netlists to SPICE.")
+ destdir = targetdir + '/libs.ref/spi'
+ srcdir = targetdir + '/libs.ref/cdl'
+ os.makedirs(destdir, exist_ok=True)
+
+ # For each library, create the library subdirectory
+ for library in libraries:
+ if len(library) == 3:
+ destlib = library[2]
+ else:
+ destlib = library[1]
+ destlibdir = destdir + '/' + destlib
+ srclibdir = srcdir + '/' + destlib
+ os.makedirs(destlibdir, exist_ok=True)
+
+ # Find CDL file names in the source
+ cdlfiles = os.listdir(srclibdir)
+
+ # The directory with scripts should be in ../common with respect
+ # to the Makefile that determines the cwd.
+ scriptdir = os.path.split(os.getcwd())[0] + '/common/'
+
+ # Run cdl2spi.py script to read in the CDL file and write out SPICE
+ for cdlfile in cdlfiles:
+ spiname = os.path.splitext(cdlfile)[0] + '.spi'
+ procopts = [scriptdir + 'cdl2spi.py', srclibdir + '/' + cdlfile, destlibdir + '/' + spiname]
+ if do_cdl_scaleu:
+ procopts.append('-dscale=u')
+ for item in ignorelist:
+ procopts.append('-ignore=' + item)
+ print('Running (in ' + destlibdir + '): ' + ' '.join(procopts))
+ subprocess.run(procopts,
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destlibdir,
+ universal_newlines = True)
+
+ sys.exit(0)
diff --git a/common/padframe_generator.py b/common/padframe_generator.py
new file mode 120000
index 0000000..c87a0c5
--- /dev/null
+++ b/common/padframe_generator.py
@@ -0,0 +1 @@
+soc_floorplanner.py
\ No newline at end of file
diff --git a/common/pdk.bindkeys b/common/pdk.bindkeys
new file mode 100644
index 0000000..1b502db
--- /dev/null
+++ b/common/pdk.bindkeys
@@ -0,0 +1,186 @@
+#
+# Cadence-compatibility bindings except where marked.
+#
+macro f "view" ;# zoom to fit window
+macro ^z "zoom 0.5" ;# zoom in
+macro Z "zoom 2" ;# zoom out
+macro B "popstack" ;# up hierarchy
+macro X {pushstack [cellname list self]} ;# down hierarchy
+macro x "edit" ;# down hierarchy, edit-in-place
+macro b "select top cell ; edit" ;# up hierarchy from edit-in-place
+macro p "tool wire; magic::trackwire %W pick" ;# path
+macro ^r "redraw"
+macro ^f "unexpand"
+macro F "expand"
+macro ^a "select area"
+macro ^d "select clear"
+macro k "magic::measure"
+macro K "magic::unmeasure"
+macro i "magic::promptload getcell"
+macro l "magic::update_texthelper ; wm deiconify .texthelper ; raise .texthelper"
+macro O "magic::clock"
+macro <del> "magic::delete"
+
+# Toolkit parameter dialog
+macro q "magic::gencell {} ; raise .params"
+#
+# The following should be already implemented as existing Magic bindings
+#
+macro u "undo"
+macro U "redo"
+macro m "move"
+macro c "copy"
+#
+# Compatibility with Electric; Cadence bindings are on function keys and
+# do not work through the VNC.
+macro ^s "magic::promptsave magic" ;# save dialog menu
+
+#
+# Bertrand's bindings follow except where marked.
+#
+macro < sideways
+macro ^ upsidedown
+#
+# Set grid at 1 micron
+#
+macro 0 "grid on ; grid 1l" ;# Grid at 0.5um (1 lambda)
+# macro ^f "feedback clear" ;# conflicts with Cadence binding
+#
+# Paint/Erase macros
+#
+macro 1 "paint m1"
+macro ! "erase m1"
+macro 2 "paint m2"
+macro @ "erase m2"
+macro 3 "paint m3"
+macro # "erase m3"
+#ifdef METAL4
+macro 4 "paint mtp"
+macro $ "erase mtp"
+#endif
+#ifdef METAL5
+macro 4 "paint m4"
+macro $ "erase m4"
+macro 5 "paint mtp"
+macro % "erase mtp"
+#endif
+#ifdef METAL6
+macro 4 "paint m4"
+macro $ "erase m4"
+macro 5 "paint m5"
+macro % "erase m5"
+macro 6 "paint mtp"
+macro ^ "erase mtp"
+#endif
+
+macro 7 "paint poly"
+# macro & "erase poly"
+# macro p "paint pdiff"
+macro n "paint ndiff"
+# macro l "erase labels"
+macro P "erase pdiff"
+macro N "erase ndiff"
+macro y "drc check; drc why"
+macro ? "select area; what"
+
+macro / "expand toggle"
+macro ^w "writeall force"
+macro ^e "edit"
+# macro ^x "quit"
+
+macro z "findbox zoom"
+# "f" conflicts with Cadence "full view", so use control-i to select cells.
+# macro f "select cell"
+macro ^i "select cell"
+
+# Leave keypad bindings as-is, further down. However, keypad
+# keys generally don't translate through the VNC session, so
+# use the following arrow key bindings:
+#
+# no shift shift
+# arrows only -> Pan 10% 100%
+# with alt -> Move 1 lambda 1 grid
+# with ctrl -> Stretch 1 lambda 1 grid
+#
+# Pan 10 percent of the window size with arrows
+# macro XK_Left "scroll l .1 w"
+# macro XK_Up "scroll u .1 w"
+# macro XK_Right "scroll r .1 w"
+# macro XK_Down "scroll d .1 w"
+
+# Pan 100 percent of the window size with arrows
+# macro Shift_XK_Left "scroll l 1 w"
+# macro Shift_XK_Up "scroll u 1 w"
+# macro Shift_XK_Right "scroll r 1 w"
+# macro Shift_XK_Down "scroll d 1 w"
+
+# move 0.05um with arrows
+# macro Alt_XK_Left "move l 1l"
+# macro Alt_XK_Right "move r 1l"
+# macro Alt_XK_Up "move u 1l"
+# macro Alt_XK_Down "move d 1l"
+
+# move 1 grid unit with arrows
+# macro Alt_Shift_XK_Left "move l 1g"
+# macro Alt_Shift_XK_Right "move r 1g"
+# macro Alt_Shift_XK_Up "move u 1g"
+# macro Alt_Shift_XK_Down "move d 1g"
+
+# stretch 0.05um with arrows
+# macro Control_XK_Left "stretch l 1l"
+# macro Control_XK_Right "stretch r 1l"
+# macro Control_XK_Up "stretch u 1l"
+# macro Control_XK_Down "stretch d 1l"
+
+# stretch 1 grid unit with arrows
+# macro Control_Shift_XK_Left "stretch l 1g"
+# macro Control_Shift_XK_Right "stretch r 1g"
+# macro Control_Shift_XK_Up "stretch u 1g"
+# macro Control_Shift_XK_Down "stretch d 1g"
+
+# shift mouse wheel bindings for right-left shift
+macro Shift_XK_Pointer_Button4 "scroll r .05 w"
+macro Shift_XK_Pointer_Button5 "scroll l .05 w"
+
+# control mouse wheel bindings for zoom in/out
+macro Control_XK_Pointer_Button4 "zoom 0.70711"
+macro Control_XK_Pointer_Button5 "zoom 1.41421"
+
+# Bertrand's original arrow macros
+# move 1 grid unit with arrows
+macro XK_Left "move l 1g"
+macro XK_Right "move r 1g"
+macro XK_Up "move u 1g"
+macro XK_Down "move d 1g"
+
+# move 0.05um with arrows
+macro Control_XK_Left "move l 1l"
+macro Control_XK_Right "move r 1l"
+macro Control_XK_Up "move u 1l"
+macro Control_XK_Down "move d 1l"
+
+# stretch 1 grid unit with arrows
+macro Shift_XK_Left "stretch l 1g"
+macro Shift_XK_Right "stretch r 1g"
+macro Shift_XK_Up "stretch u 1g"
+macro Shift_XK_Down "stretch d 1g"
+
+# stretch 0.05um with arrows
+macro Control_Shift_XK_Left "stretch l 1l"
+macro Control_Shift_XK_Right "stretch r 1l"
+macro Control_Shift_XK_Up "stretch u 1l"
+macro Control_Shift_XK_Down "stretch d 1l"
+
+# Restore pan function on Alt-key
+# Pan 10 percent of the window size with arrows
+macro Alt_XK_Left "scroll l .1 w"
+macro Alt_XK_Up "scroll u .1 w"
+macro Alt_XK_Right "scroll r .1 w"
+macro Alt_XK_Down "scroll d .1 w"
+
+# Pan 100 percent of the window size with arrows
+macro Alt_Shift_XK_Left "scroll l 1 w"
+macro Alt_Shift_XK_Up "scroll u 1 w"
+macro Alt_Shift_XK_Right "scroll r 1 w"
+macro Alt_Shift_XK_Down "scroll d 1 w"
+
diff --git a/common/pdk.prm b/common/pdk.prm
new file mode 100644
index 0000000..719eb74
--- /dev/null
+++ b/common/pdk.prm
@@ -0,0 +1,26 @@
+; TODO: make changes to this file for TECHNAME?
+; configuration file for TECHNAME (left same as osu035, 0.35um process)
+; Note that these values are totally bogus!
+;
+
+lambda 0.01 ; length scaling, microns (1 lambda = 1 centimicron)
+
+capga .0115 ; gate capacitance, pF/micron^2
+
+capda 0.0012
+capdp 0.0013
+cappda 0.00260
+cappdp 0.00090
+
+lowthresh 0.5 ; logic low threshold as a normalized voltage
+highthresh 0.5 ; logic high threshold as a normalized voltage
+
+cntpullup 0 ; irrelevant, cmos technology; no depletion transistors
+diffperim 0 ; don't include diffusion perimeters for sidewall cap.
+subparea 0 ; poly over transistor won't count as part pf bulk-poly cap.
+diffext 0 ; diffusion extension for each transistor
+
+resistance n-channel dynamic-low 2 0.4 1844.70
+resistance p-channel dynamic-high 6.2 0.4 1489.10
+resistance n-channel static 2 0.4 2203.94
+resistance p-channel static 6.2 0.4 1693.37
diff --git a/common/pdk.tcl b/common/pdk.tcl
new file mode 100644
index 0000000..04f32a6
--- /dev/null
+++ b/common/pdk.tcl
@@ -0,0 +1,274 @@
+#-------------------------------------------------------------------
+# General-purpose routines for the PDK script in all technologies
+#-------------------------------------------------------------------
+#
+#----------------------------------------
+# Number Conversion Functions
+#----------------------------------------
+
+#---------------------
+# Microns to Lambda
+#---------------------
+proc magic::u2l {micron} {
+ set techlambda [magic::tech lambda]
+ set tech1 [lindex $techlambda 1]
+ set tech0 [lindex $techlambda 0]
+ set tscale [expr {$tech1 / $tech0}]
+ set lambdaout [expr {((int([magic::cif scale output] * 10000)) / 10000.0)}]
+ return [expr $micron / ($lambdaout*$tscale) ]
+}
+
+#---------------------
+# Lambda to Microns
+#---------------------
+proc magic::l2u {lambda} {
+ set techlambda [magic::tech lambda]
+ set tech1 [lindex $techlambda 1] ; set tech0 [lindex $techlambda 0]
+ set tscale [expr {$tech1 / $tech0}]
+ set lambdaout [expr {((int([magic::cif scale output] * 10000)) / 10000.0)}]
+ return [expr $lambda * $lambdaout * $tscale ]
+}
+
+#---------------------
+# Internal to Microns
+#---------------------
+proc magic::i2u { value } {
+ return [expr {((int([magic::cif scale output] * 10000)) / 10000.0) * $value}]
+}
+
+#---------------------
+# Microns to Internal
+#---------------------
+proc magic::u2i {value} {
+ return [expr {$value / ((int([magic::cif scale output] * 10000)) / 10000.0)}]
+}
+
+#---------------------
+# Float to Spice
+#---------------------
+proc magic::float2spice {value} {
+ if {$value >= 1.0e+6} {
+ set exponent 1e+6
+ set unit "meg"
+ } elseif {$value >= 1.0e+3} {
+ set exponent 1e+3
+ set unit "k"
+ } elseif { $value >= 1} {
+ set exponent 1
+ set unit ""
+ } elseif {$value >= 1.0e-3} {
+ set exponent 1e-3
+ set unit "m"
+ } elseif {$value >= 1.0e-6} {
+ set exponent 1e-6
+ set unit "u"
+ } elseif {$value >= 1.0e-9} {
+ set exponent 1e-9
+ set unit "n"
+ } elseif {$value >= 1.0e-12} {
+ set exponent 1e-12
+ set unit "p"
+ } elseif {$value >= 1.0e-15} {
+ set exponent 1e-15
+ set unit "f"
+ } else {
+ set exponent 1e-18
+ set unit "a"
+ }
+ set val [expr $value / $exponent]
+ set val [expr int($val * 1000) / 1000.0]
+ if {$val == 0} {set unit ""}
+ return $val$unit
+}
+
+#---------------------
+# Spice to Float
+#---------------------
+proc magic::spice2float {value {faultval 0.0}} {
+ # Remove trailing units, at least for some common combinations
+ set value [string tolower $value]
+ set value [string map {um u nm n uF n nF n pF p aF a} $value]
+ set value [string map {meg "* 1.0e6" k "* 1.0e3" m "* 1.0e-3" u "* 1.0e-6" \
+ n "* 1.0 e-9" p "* 1.0e-12" f "* 1.0e-15" a "* 1.0e-15"} $value]
+ if {[catch {set rval [expr $value]}]} {
+ puts stderr "Value is not numeric!"
+ set rval $faultval
+ }
+ return $rval
+}
+
+#---------------------
+# Numeric Precision
+#---------------------
+proc magic::3digitpastdecimal {value} {
+ set new [expr int([expr $value * 1000 + 0.5 ]) / 1000.0]
+ return $new
+}
+
+#-------------------------------------------------------------------
+# File Access Functions
+#-------------------------------------------------------------------
+
+#-------------------------------------------------------------------
+# Ensures that a cell name does not already exist, either in
+# memory or on disk. Modifies the name until it does.
+#-------------------------------------------------------------------
+proc magic:cellnameunique {cellname} {
+ set i 0
+ set newname $cellname
+ while {[cellname list exists $newname] != 0 || [magic::searchcellondisk $newname] != 0} {
+ incr i
+ set newname ${cellname}_$i
+ }
+ return $newname
+}
+
+#-------------------------------------------------------------------
+# Looks to see if a cell exists on disk
+#-------------------------------------------------------------------
+proc magic::searchcellondisk {name} {
+ set rlist {}
+ foreach dir [path search] {
+ set ftry [file join $dir ${name}.mag]
+ if [file exists $ftry] {
+ return 1
+ }
+ }
+ return 0
+}
+
+#-------------------------------------------------------------------
+# Checks to see if a cell already exists on disk or in memory
+#-------------------------------------------------------------------
+proc magic::iscellnameunique {cellname} {
+ if {[cellname list exists $cellname] == 0 && [magic::searchcellondisk $cellname] == 0} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+#--------------------------------------------------------------
+# Procedure that checks the user's "ip" subdirectory on startup
+# and adds each one's maglef subdirectory to the path.
+#--------------------------------------------------------------
+
+proc magic::query_mylib_ip {} {
+ global TECHPATH
+ global env
+ if [catch {set home $env(SUDO_USER)}] {
+ set home $env(USER)
+ }
+ set homedir /home/${home}
+ set ip_dirs [glob -directory ${homedir}/design/ip *]
+ set proj_dir [pwd]
+ set config_dir .config
+ set info_dir ${proj_dir}/${config_dir}
+ if {![file exists ${info_dir}]} {
+ set config_dir .ef-config
+ set info_dir ${proj_dir}/${config_dir}
+ }
+
+ set info_file ${info_dir}/info
+ set depends [dict create]
+ if {![catch {open $info_file r} ifd]} {
+ set depsec false
+ while {[gets $ifd line] >= 0} {
+ if {[string first dependencies: $line] >= 0} {
+ set depsec true
+ }
+ if {$depsec} {
+ if {[string first version: $line] >= 0} {
+ if {$ipname != ""} {
+ set ipvers [string trim [lindex [split $line] 1] ']
+ dict set depends $ipname $ipvers
+ set ipname ""
+ } else {
+ puts stderr "Badly formatted info file in ${config_dir}!"
+ }
+ } else {
+ set ipname [string trim $line :]
+ }
+ }
+ }
+ }
+
+ foreach dir $ip_dirs {
+ # Version handling: version dependencies are found in
+ # ${config_dir}/info. For all other IP, use the most recent
+ # version number.
+ set ipname [lindex [file split $dir] end]
+ if {![catch {set version [dict get $depends $ipname]}]} {
+ if {[file isdirectory ${dir}/${version}/maglef]} {
+ addpath ${dir}/${version}/maglef
+ continue
+ } else {
+ puts stderr "ERROR: Dependency ${ipname} version ${version} does not exist"
+ }
+ }
+
+ # Secondary directory is the version number. Use the highest
+ # version available.
+
+ set sub_dirs {}
+ catch {set sub_dirs [glob -directory $dir *]}
+ set maxver 0.0
+ foreach subdir $sub_dirs {
+ set vidx [string last / $subdir]
+ incr vidx
+ set version [string range $subdir $vidx end]
+ if {$version > $maxver} {
+ set maxver $version
+ }
+ }
+ if {[file exists ${dir}/${maxver}/maglef]} {
+ # Compatibility rule: foundry name must match.
+ # Get foundry name from ${config_dir}/techdir symbolic link reference
+ if {[file exists ${dir}/${maxver}/${config_dir}/techdir]} {
+ set technodedir [file link ${dir}/${maxver}/${config_dir}/techdir]
+ set nidx [string last / $technodedir]
+ set techdir [string range $technodedir 0 $nidx-1]
+ if {$techdir == $TECHPATH} {
+ addpath ${dir}/${maxver}/maglef
+ }
+ }
+ }
+ }
+}
+
+#--------------------------------------------------------------
+# Procedure that checks the user's design directory on startup
+# and adds each one's mag subdirectory to the path.
+#--------------------------------------------------------------
+
+proc magic::query_my_projects {} {
+ global TECHPATH
+ global env
+ if [catch {set home $env(SUDO_USER)}] {
+ set home $env(USER)
+ }
+ set homedir /home/${home}
+ set proj_dirs [glob -directory ${homedir}/design *]
+ foreach dir $proj_dirs {
+ # Compatibility rule: foundry name must match.
+ # Get foundry name from ${config_dir}/techdir symbolic link reference
+ if {[file exists ${dir}/mag]} {
+ set config_dir .config
+ set tech_dir ${dir}/${config_dir}
+ if {![file exists ${tech_dir}]} {
+ set config_dir .ef-config
+ set tech_dir ${dir}/${config_dir}
+ }
+ if {[file exists ${dir}/${config_dir}/techdir]} {
+ set technodedir [file link ${dir}/${config_dir}/techdir]
+ set nidx [string last / $technodedir]
+ set techdir [string range $technodedir 0 $nidx-1]
+ if {$techdir == $TECHPATH} {
+ addpath ${dir}/mag
+ }
+ }
+ }
+ }
+}
+
+#----------------------------------------------------------------
diff --git a/common/preproc.py b/common/preproc.py
new file mode 100755
index 0000000..1fca5be
--- /dev/null
+++ b/common/preproc.py
@@ -0,0 +1,576 @@
+#!/usr/bin/env python3
+#--------------------------------------------------------------------
+#
+# preproc.py
+#
+# General purpose macro preprocessor
+#
+#--------------------------------------------------------------------
+# 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> [...]
+# #define <variable>(<parameters>) [...]
+# #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
+#--------------------------------------------------------------------
+
+import re
+import sys
+
+def solve_statement(condition):
+
+ defrex = re.compile('defined[ \t]*\(([^\)]+)\)')
+ orrex = re.compile('(.+)\|\|(.+)')
+ andrex = re.compile('(.+)&&(.+)')
+ notrex = re.compile('!([^&\|]+)')
+ parenrex = re.compile('\(([^\)]+)\)')
+ leadspacerex = re.compile('^[ \t]+(.*)')
+ endspacerex = re.compile('(.*)[ \t]+$')
+
+ matchfound = True
+ while matchfound:
+ matchfound = False
+
+ # Search for defined(K) (K must be a single keyword)
+ # If the keyword was defined, then it should have been replaced by 1
+ lmatch = defrex.search(condition)
+ if lmatch:
+ key = lmatch.group(1)
+ if key == 1 or key == '1' or key == True:
+ repl = 1
+ else:
+ repl = 0
+
+ condition = defrex.sub(str(repl), condition)
+ matchfound = True
+
+ # Search for (X) recursively
+ lmatch = parenrex.search(condition)
+ if lmatch:
+ repl = solve_statement(lmatch.group(1))
+ condition = parenrex.sub(str(repl), condition)
+ matchfound = True
+
+ # Search for !X recursively
+ lmatch = notrex.search(condition)
+ if lmatch:
+ only = solve_statement(lmatch.group(1))
+ if only == '1':
+ repl = '0'
+ else:
+ repl = '1'
+ condition = notrex.sub(str(repl), condition)
+ matchfound = True
+
+ # Search for A&&B recursively
+ lmatch = andrex.search(condition)
+ if lmatch:
+ first = solve_statement(lmatch.group(1))
+ second = solve_statement(lmatch.group(2))
+ if first == '1' and second == '1':
+ repl = '1'
+ else:
+ repl = '0'
+ condition = andrex.sub(str(repl), condition)
+ matchfound = True
+
+ # Search for A||B recursively
+ lmatch = orrex.search(condition)
+ if lmatch:
+ first = solve_statement(lmatch.group(1))
+ second = solve_statement(lmatch.group(2))
+ if first == '1' or second == '1':
+ repl = '1'
+ else:
+ repl = '0'
+ condition = orrex.sub(str(repl), condition)
+ matchfound = True
+
+ # Remove whitespace
+ lmatch = leadspacerex.match(condition)
+ if lmatch:
+ condition = lmatch.group(1)
+ lmatch = endspacerex.match(condition)
+ if lmatch:
+ condition = lmatch.group(1)
+
+ return condition
+
+def solve_condition(condition, keys, defines, keyrex):
+ # Do definition replacement on the conditional
+ for keyword in keys:
+ condition = keyrex[keyword].sub(defines[keyword], condition)
+
+ value = solve_statement(condition)
+ if value == '1':
+ return 1
+ else:
+ return 0
+
+def sortkeys(keys):
+ newkeys = []
+ for i in range(0, len(keys)):
+ keyword = keys[i]
+ found = False
+ for j in range(0, len(newkeys)):
+ inword = newkeys[j]
+ if inword in keyword:
+ # Insert keyword before inword
+ newkeys.insert(j, keyword)
+ found = True
+ break
+ if not found:
+ newkeys.append(keyword)
+ return newkeys
+
+def runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile):
+
+ includerex = re.compile('^[ \t]*#include[ \t]+"*([^ \t\n\r"]+)')
+ definerex = re.compile('^[ \t]*#define[ \t]+([^ \t]+)[ \t]+(.+)')
+ paramrex = re.compile('^([^\(]+)\(([^\)]+)\)')
+ defrex = re.compile('^[ \t]*#define[ \t]+([^ \t\n\r]+)')
+ undefrex = re.compile('^[ \t]*#undef[ \t]+([^ \t\n\r]+)')
+ ifdefrex = re.compile('^[ \t]*#ifdef[ \t]+(.+)')
+ ifndefrex = re.compile('^[ \t]*#ifndef[ \t]+(.+)')
+ ifrex = re.compile('^[ \t]*#if[ \t]+(.+)')
+ elseifrex = re.compile('^[ \t]*#elseif[ \t]+(.+)')
+ elserex = re.compile('^[ \t]*#else')
+ endifrex = re.compile('^[ \t]*#endif')
+ commentrex = re.compile('^###[^#]*$')
+ ccstartrex = re.compile('/\*') # C-style comment start
+ ccendrex = re.compile('\*/') # C-style comment end
+ contrex = re.compile('.*\\\\$') # Backslash continuation line
+
+ badifrex = re.compile('^[ \t]*#if[ \t]*.*')
+ badelserex = re.compile('^[ \t]*#else[ \t]*.*')
+
+ # This code is not designed to operate on huge files. Neither is it designed to be
+ # efficient.
+
+ # ifblock state:
+ # -1 : not in an if/else block
+ # 0 : no condition satisfied yet
+ # 1 : condition satisfied
+ # 2 : condition was handled, waiting for endif
+
+ ifile = False
+ try:
+ ifile = open(inputfile, 'r')
+ except FileNotFoundError:
+ for dir in incdirs:
+ try:
+ ifile = open(dir + '/' + inputfile, 'r')
+ except FileNotFoundError:
+ pass
+ else:
+ break
+
+ if not ifile:
+ print("Error: Cannot open file " + inputfile + " for reading.\n", file=sys.stderr)
+ return
+
+ ccblock = -1
+ ifblock = -1
+ ifstack = []
+ lineno = 0
+
+ filetext = ifile.readlines()
+ lastline = []
+
+ for line in filetext:
+ lineno += 1
+
+ # C-style comments override everything else
+ if ccomm:
+ if ccblock == -1:
+ pmatch = ccstartrex.search(line)
+ if pmatch:
+ ematch = ccendrex.search(line[pmatch.end(0):])
+ if ematch:
+ line = line[0:pmatch.start(0)] + line[pmatch.end(0) + ematch.end(0):]
+ else:
+ line = line[0:pmatch.start(0)]
+ ccblock = 1
+ elif ccblock == 1:
+ ematch = ccendrex.search(line)
+ if ematch:
+ line = line[ematch.end(0)+2:]
+ ccblock = -1
+ else:
+ continue
+
+ # Handle continuation detected in previous line
+ if lastline:
+ # Note: Apparently there is a character retained after the backslash,
+ # so strip the last two characters from the line.
+ line = lastline[0:-2] + line
+ lastline = []
+
+ # Continuation lines have the next highest priority. However, this
+ # script will attempt to keep continuation lines in the body of the
+ # text and only collapse lines where continuation lines occur in
+ # a preprocessor statement.
+
+ cmatch = contrex.match(line)
+
+ # Ignore lines beginning with "###"
+ pmatch = commentrex.match(line)
+ if pmatch:
+ continue
+
+ # Handle ifdef
+ pmatch = ifdefrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock != -1:
+ ifstack.append(ifblock)
+
+ if ifblock == 1 or ifblock == -1:
+ condition = pmatch.group(1)
+ ifblock = solve_condition(condition, keys, defines, keyrex)
+ else:
+ ifblock = 2
+ continue
+
+ # Handle ifndef
+ pmatch = ifndefrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock != -1:
+ ifstack.append(ifblock)
+
+ if ifblock == 1 or ifblock == -1:
+ condition = pmatch.group(1)
+ ifblock = solve_condition(condition, keys, defines, keyrex)
+ ifblock = 1 if ifblock == 0 else 0
+ else:
+ ifblock = 2
+ continue
+
+ # Handle if
+ pmatch = ifrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock != -1:
+ ifstack.append(ifblock)
+
+ if ifblock == 1 or ifblock == -1:
+ condition = pmatch.group(1)
+ ifblock = solve_condition(condition, keys, defines, keyrex)
+ else:
+ ifblock = 2
+ continue
+
+ # Handle elseif
+ pmatch = elseifrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock == -1:
+ print("Error: #elseif without preceding #if at line " + str(lineno) + ".", file=sys.stderr)
+ ifblock = 0
+
+ if ifblock == 1:
+ ifblock = 2
+ elif ifblock != 2:
+ condition = pmatch.group(1)
+ ifblock = solve_condition(condition, keys, defines, keyrex)
+ continue
+
+ # Handle else
+ pmatch = elserex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock == -1:
+ print("Error: #else without preceding #if at line " + str(lineno) + ".", file=sys.stderr)
+ ifblock = 0
+
+ if ifblock == 1:
+ ifblock = 2
+ elif ifblock == 0:
+ ifblock = 1
+ continue
+
+ # Handle endif
+ pmatch = endifrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ if ifblock == -1:
+ print("Error: #endif outside of #if block at line " + str(lineno) + " (ignored)", file=sys.stderr)
+ elif ifstack:
+ ifblock = ifstack.pop()
+ else:
+ ifblock = -1
+ continue
+
+ # Check for 'if' or 'else' that were not properly formed
+ pmatch = badifrex.match(line)
+ if pmatch:
+ print("Error: Badly formed #if statement at line " + str(lineno) + " (ignored)", file=sys.stderr)
+ if ifblock != -1:
+ ifstack.append(ifblock)
+
+ if ifblock == 1 or ifblock == -1:
+ ifblock = 0
+ else:
+ ifblock = 2
+ continue
+
+ pmatch = badelserex.match(line)
+ if pmatch:
+ print("Error: Badly formed #else statement at line " + str(lineno) + " (ignored)", file=sys.stderr)
+ ifblock = 2
+ continue
+
+ # Ignore all lines that are not satisfied by a conditional
+ if ifblock == 0 or ifblock == 2:
+ continue
+
+ # Handle include. Note that this code does not expect or
+ # handle 'if' blocks that cross file boundaries.
+ pmatch = includerex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ inclfile = pmatch.group(1)
+ runpp(keys, keyrex, defines, ccomm, incdirs, inclfile, ofile)
+ continue
+
+ # Handle define (with value)
+ pmatch = definerex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ condition = pmatch.group(1)
+
+ # Additional handling of definition w/parameters: #define X(a,b,c) ..."
+ rmatch = paramrex.match(condition)
+ if rmatch:
+ # 'condition' as a key into keyrex only needs to be unique.
+ # Use the definition word without everything in parentheses
+ condition = rmatch.group(1)
+
+ # 'pcondition' is the actual search regexp and must capture all
+ # the parameters individually for substitution
+
+ parameters = rmatch.group(2).split(',')
+
+ # Generate the regexp string to match comma-separate values
+ # Note that this is based on the cpp preprocessor, which
+ # apparently allows commas in arguments if surrounded by
+ # parentheses; e.g., "def(a, b, (c1,c2))". This is NOT
+ # handled.
+
+ pcondition = condition + '\('
+ for param in parameters[0:-1]:
+ pcondition += '(.*),'
+ pcondition += '(.*)\)'
+
+ # Generate the substitution string with group substitutions
+ pvalue = pmatch.group(2)
+ idx = 1
+ for param in parameters:
+ pvalue = pvalue.replace(param, '\g<' + str(idx) + '>')
+ idx = idx + 1
+
+ defines[condition] = pvalue
+ keyrex[condition] = re.compile(pcondition)
+ else:
+ parameters = []
+ value = pmatch.group(2)
+ # Note: Need to check for infinite recursion here, but it's tricky.
+ defines[condition] = value
+ keyrex[condition] = re.compile(condition)
+
+ if condition not in keys:
+ # Parameterized keys go to the front of the list
+ if parameters:
+ keys.insert(0, condition)
+ else:
+ keys.append(condition)
+ keys = sortkeys(keys)
+ continue
+
+ # Handle define (simple case, no value)
+ pmatch = defrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ condition = pmatch.group(1)
+ defines[condition] = '1'
+ keyrex[condition] = re.compile(condition)
+ if condition not in keys:
+ keys.append(condition)
+ keys = sortkeys(keys)
+ continue
+
+ # Handle undef
+ pmatch = undefrex.match(line)
+ if pmatch:
+ if cmatch:
+ lastline = line
+ continue
+ condition = pmatch.group(1)
+ if condition in keys:
+ defines.pop(condition)
+ keyrex.pop(condition)
+ keys.remove(condition)
+ continue
+
+ # Now do definition replacement on what's left (if anything)
+ # This must be done repeatedly from the top until there are no
+ # more substitutions to make.
+
+ while True:
+ origline = line
+ for keyword in keys:
+ newline = keyrex[keyword].sub(defines[keyword], line)
+ if newline != line:
+ line = newline
+ break
+
+ if line == origline:
+ break
+
+ # Output the line
+ print(line, file=ofile, end='')
+
+ if ifblock != -1 or ifstack != []:
+ print("Error: input file ended with an unterminated #if block.", file=sys.stderr)
+
+ if ifile != sys.stdin:
+ ifile.close()
+ return
+
+def printusage(progname):
+ print('Usage: ' + progname + ' input_file [output_file] [-options]')
+ print(' Options are:')
+ print(' -help Print this help text.')
+ print(' -ccomm Remove C comments in /* ... */ delimiters.')
+ print(' -D<def> Define word <def> and set its value to 1.')
+ print(' -D<def>=<val> Define word <def> and set its value to <val>.')
+ print(' -I<dir> Add <dir> to search path for input files.')
+ return
+
+if __name__ == '__main__':
+
+ # Parse command line for options and arguments
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ if len(arguments) > 0:
+ inputfile = arguments[0]
+ if len(arguments) > 1:
+ outputfile = arguments[1]
+ else:
+ outputfile = []
+ else:
+ printusage(sys.argv[0])
+ sys.exit(0)
+
+ defines = {}
+ keyrex = {}
+ keys = []
+ incdirs = []
+ ccomm = False
+ for item in options:
+ result = item.split('=')
+ if result[0] == '-help':
+ printusage(sys.argv[0])
+ sys.exit(0)
+ elif result[0] == '-ccomm':
+ ccomm = True
+ elif result[0][0:2] == '-I':
+ incdirs.append(result[0][2:])
+ elif result[0][0:2] == '-D':
+ keyword = result[0][2:]
+ try:
+ value = result[1]
+ except:
+ value = '1'
+ defines[keyword] = value
+ keyrex[keyword] = re.compile(keyword)
+ keys.append(keyword)
+ keys = sortkeys(keys)
+ else:
+ print('Bad option ' + item + ', options are -help, -ccomm, -D<def> -I<dir>\n')
+ sys.exit(1)
+
+ if outputfile:
+ ofile = open(outputfile, 'w')
+ else:
+ ofile = sys.stdout
+
+ if not ofile:
+ print("Error: Cannot open file " + output_file + " for writing.")
+ sys.exit(1)
+
+ # Sort keys so that if any definition contains another definition, the
+ # subset word is handled last; otherwise the subset word will get
+ # substituted, screwing up the definition names in which it occurs.
+
+ keys = sortkeys(keys)
+
+ runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile)
+ if ofile != sys.stdout:
+ ofile.close()
+ sys.exit(0)
diff --git a/common/remove_specify.py b/common/remove_specify.py
new file mode 100755
index 0000000..746a06f
--- /dev/null
+++ b/common/remove_specify.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# Remove timing information from a verilog file, which is everything between
+# the keywords "specify" and "endspecify".
+#
+# Filter a verilog file to remove any backslash continuation lines, which
+# iverilog does not parse. If targetroot is a directory, then find and
+# process all files in the path of targetroot. If any file to be processed
+# is unmodified (has no backslash continuation lines), then ignore it. If
+# any file is a symbolic link and gets modified, then remove the symbolic
+# link before overwriting with the modified file.
+#
+
+import stat
+import sys
+import os
+import re
+
+def makeuserwritable(filepath):
+ if os.path.exists(filepath):
+ st = os.stat(filepath)
+ os.chmod(filepath, st.st_mode | stat.S_IWUSR)
+
+def remove_specify(vfile, outfile):
+ modified = False
+ with open(vfile, 'r') as ifile:
+ vtext = ifile.read()
+
+ if outfile == None:
+ outfile = vfile
+
+ # Remove backslash-followed-by-newline and absorb initial whitespace. It
+ # is unclear what initial whitespace means in this context, as the use-
+ # case that has been seen seems to work under the assumption that leading
+ # whitespace is ignored up to the amount used by the last indentation.
+
+ vlines = re.sub('\\\\\n[ \t]*', '', vtext)
+
+ specrex = re.compile('\n[ \t]*specify[ \t\n]+')
+ endspecrex = re.compile('\n[ \t]*endspecify')
+ smatch = specrex.search(vlines)
+ while smatch:
+ specstart = smatch.start()
+ specpos = smatch.end()
+ ematch = endspecrex.search(vlines[specpos:])
+ specend = ematch.end()
+ vtemp = vlines[0:specstart + 1] + vlines[specpos + specend + 1:]
+ vlines = vtemp
+ smatch = specrex.search(vlines)
+
+ if vlines != vtext:
+ # File contents have been modified, so if this file was a symbolic
+ # link, then remove it. Otherwise, overwrite the file with the
+ # modified contents.
+ if outfile == vfile:
+ if os.path.islink(vfile):
+ os.unlink(vfile)
+ if os.path.exists(outfile):
+ makeuserwritable(outfile)
+ with open(outfile, 'w') as ofile:
+ ofile.write(vlines)
+
+ elif outfile != vfile:
+ if os.path.exists(outfile):
+ makeuserwritable(outfile)
+ with open(outfile, 'w') as ofile:
+ ofile.write(vlines)
+
+# If called as main, run remove_specify
+
+if __name__ == '__main__':
+
+ # Divide up command line into options and arguments
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ # Need one argument: path to verilog netlist
+ # If two arguments, then 2nd argument is the output file.
+
+ if len(arguments) == 2:
+ netlist_path = arguments[0]
+ output_path = arguments[1]
+ remove_specify(netlist_path, output_path)
+ elif len(arguments) != 1:
+ print("Usage: remove_spcify.py <file_path> [<output_path>]")
+ elif len(arguments) == 1:
+ netlist_path = arguments[0]
+ remove_specify(netlist_path, None)
+
diff --git a/common/soc_floorplanner.py b/common/soc_floorplanner.py
new file mode 100755
index 0000000..959a623
--- /dev/null
+++ b/common/soc_floorplanner.py
@@ -0,0 +1,2619 @@
+#!/usr/bin/env python3
+#
+#--------------------------------------------------------
+# Padframe Editor and Core Floorplanner
+#
+#--------------------------------------------------------
+# Written by Tim Edwards
+# efabless, inc.
+# April 24, 2019
+# Version 0.5
+# Based on https://github.com/YosysHQ/padring (requirement)
+# Update: May 9, 2019 to add console message window
+# Update: May 10, 2019 to incorporate core floorplanning
+# Update: Jan 31, 2020 to allow batch operation
+#--------------------------------------------------------
+
+import os
+import re
+import sys
+import glob
+import json
+import math
+import shutil
+import signal
+import select
+import subprocess
+import faulthandler
+
+import tkinter
+from tkinter import ttk
+from tkinter import filedialog
+import tksimpledialog
+from consoletext import ConsoleText
+
+# User preferences file (if it exists)
+prefsfile = '~/design/.profile/prefs.json'
+
+#------------------------------------------------------
+# Dialog for entering a pad
+#------------------------------------------------------
+
+class PadNameDialog(tksimpledialog.Dialog):
+ def body(self, master, warning=None, seed=None):
+ if warning:
+ ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
+ ttk.Label(master, text="Enter new group name:").grid(row = 1, column = 0, sticky = 'wns')
+ self.nentry = ttk.Entry(master)
+ self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
+ if seed:
+ self.nentry.insert(0, seed)
+ return self.nentry # initial focus
+
+ def apply(self):
+ return self.nentry.get()
+
+#------------------------------------------------------
+# Dialog for entering core dimensions
+#------------------------------------------------------
+
+class CoreSizeDialog(tksimpledialog.Dialog):
+ def body(self, master, warning="Chip core dimensions", seed=None):
+ if warning:
+ ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
+ ttk.Label(master, text="Enter core width x height (microns):").grid(row = 1, column = 0, sticky = 'wns')
+ self.nentry = ttk.Entry(master)
+ self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
+
+
+ if seed:
+ self.nentry.insert(0, seed)
+ return self.nentry # initial focus
+
+ def apply(self):
+ return self.nentry.get()
+
+#------------------------------------------------
+# SoC Floorplanner and Padframe Generator GUI
+#------------------------------------------------
+
+class SoCFloorplanner(ttk.Frame):
+ """Open Galaxy Pad Frame Generator."""
+
+ def __init__(self, parent = None, *args, **kwargs):
+ '''See the __init__ for Tkinter.Toplevel.'''
+ ttk.Frame.__init__(self, parent, *args[1:], **kwargs)
+ self.root = parent
+ self.init_data()
+ if args[0] == True:
+ self.do_gui = True
+ self.init_gui()
+ else:
+ self.do_gui = False
+ self.use_console = False
+
+ def on_quit(self):
+ """Exits program."""
+ quit()
+
+ def init_gui(self):
+ """Builds GUI."""
+ global prefsfile
+
+ message = []
+ fontsize = 11
+
+ # Read user preferences file, get default font size from it.
+ prefspath = os.path.expanduser(prefsfile)
+ if os.path.exists(prefspath):
+ with open(prefspath, 'r') as f:
+ self.prefs = json.load(f)
+ if 'fontsize' in self.prefs:
+ fontsize = self.prefs['fontsize']
+ else:
+ self.prefs = {}
+
+ s = ttk.Style()
+
+ available_themes = s.theme_names()
+ s.theme_use(available_themes[0])
+
+ s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
+ s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
+ foreground = 'brown', anchor = 'center')
+ s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
+ s.configure('normal.TLabel', font=('Helvetica', fontsize))
+ s.configure('normal.TCheckbutton', font=('Helvetica', fontsize))
+ s.configure('normal.TMenubutton', font=('Helvetica', fontsize))
+ s.configure('normal.TEntry', font=('Helvetica', fontsize), background='white')
+ s.configure('pad.TLabel', font=('Helvetica', fontsize), foreground = 'blue', relief = 'flat')
+ s.configure('select.TLabel', font=('Helvetica', fontsize, 'bold'), foreground = 'white',
+ background = 'blue', relief = 'flat')
+
+ # parent.withdraw()
+ self.root.title('Padframe Generator and Core Floorplanner')
+ self.root.option_add('*tearOff', 'FALSE')
+ self.pack(side = 'top', fill = 'both', expand = 'true')
+ self.root.protocol("WM_DELETE_WINDOW", self.on_quit)
+
+ pane = tkinter.PanedWindow(self, orient = 'vertical', sashrelief = 'groove',
+ sashwidth = 6)
+ pane.pack(side = 'top', fill = 'both', expand = 'true')
+
+ self.toppane = ttk.Frame(pane)
+ self.botpane = ttk.Frame(pane)
+
+ self.toppane.columnconfigure(0, weight = 1)
+ self.toppane.rowconfigure(0, weight = 1)
+ self.botpane.columnconfigure(0, weight = 1)
+ self.botpane.rowconfigure(0, weight = 1)
+
+ # Scrolled frame using canvas widget
+ self.pframe = tkinter.Frame(self.toppane)
+ self.pframe.grid(row = 0, column = 0, sticky = 'news')
+ self.pframe.rowconfigure(0, weight = 1)
+ self.pframe.columnconfigure(0, weight = 1)
+
+ # Add column on the left, listing all groups and the pads they belong to.
+ # This starts as just a frame to be filled. Use a canvas to create a
+ # scrolled frame.
+
+ # The primary frame holds the canvas
+ self.canvas = tkinter.Canvas(self.pframe, background = "white")
+ self.canvas.grid(row = 0, column = 0, sticky = 'news')
+
+ # Add Y scrollbar to pad list window
+ xscrollbar = ttk.Scrollbar(self.pframe, orient = 'horizontal')
+ xscrollbar.grid(row = 1, column = 0, sticky = 'news')
+ yscrollbar = ttk.Scrollbar(self.pframe, orient = 'vertical')
+ yscrollbar.grid(row = 0, column = 1, sticky = 'news')
+
+ self.canvas.config(xscrollcommand = xscrollbar.set)
+ xscrollbar.config(command = self.canvas.xview)
+ self.canvas.config(yscrollcommand = yscrollbar.set)
+ yscrollbar.config(command = self.canvas.yview)
+
+ self.canvas.bind("<Button-4>", self.on_scrollwheel)
+ self.canvas.bind("<Button-5>", self.on_scrollwheel)
+
+ # Configure callback
+ self.canvas.bind("<Configure>", self.frame_configure)
+
+ # Add a text window to capture output. Redirect print statements to it.
+ self.console = ttk.Frame(self.botpane)
+ self.console.grid(column = 0, row = 0, sticky = "news")
+ self.text_box = ConsoleText(self.console, wrap='word', height = 4)
+ self.text_box.pack(side='left', fill='both', expand='true')
+ console_scrollbar = ttk.Scrollbar(self.console)
+ console_scrollbar.pack(side='right', fill='y')
+ # Attach console to scrollbar
+ self.text_box.config(yscrollcommand = console_scrollbar.set)
+ console_scrollbar.config(command = self.text_box.yview)
+
+ # Add the bottom bar with buttons
+ self.bbar = ttk.Frame(self.botpane)
+ self.bbar.grid(column = 0, row = 1, sticky = "news")
+
+ self.bbar.import_button = ttk.Button(self.bbar, text='Import',
+ command=self.vlogimport, style='normal.TButton')
+ self.bbar.import_button.grid(column=0, row=0, padx = 5)
+
+ self.bbar.generate_button = ttk.Button(self.bbar, text='Generate',
+ command=self.generate, style='normal.TButton')
+ self.bbar.generate_button.grid(column=1, row=0, padx = 5)
+
+ self.bbar.save_button = ttk.Button(self.bbar, text='Save',
+ command=self.save, style='normal.TButton')
+ self.bbar.save_button.grid(column=2, row=0, padx = 5)
+
+ self.bbar.cancel_button = ttk.Button(self.bbar, text='Quit',
+ command=self.on_quit, style='normal.TButton')
+ self.bbar.cancel_button.grid(column=3, row=0, padx = 5)
+
+ pane.add(self.toppane)
+ pane.add(self.botpane)
+ pane.paneconfig(self.toppane, stretch='first')
+
+ def init_data(self):
+
+ self.vlogpads = []
+ self.corecells = []
+ self.Npads = []
+ self.Spads = []
+ self.Epads = []
+ self.Wpads = []
+ self.NEpad = []
+ self.NWpad = []
+ self.SEpad = []
+ self.SWpad = []
+ self.coregroup = []
+
+ self.celldefs = []
+ self.coredefs = []
+ self.selected = []
+ self.ioleflibs = []
+ self.llx = 0
+ self.lly = 0
+ self.urx = 0
+ self.ury = 0
+
+ self.event_data = {}
+ self.event_data['x0'] = 0
+ self.event_data['y0'] = 0
+ self.event_data['x'] = 0
+ self.event_data['y'] = 0
+ self.event_data['tag'] = None
+ self.scale = 1.0
+ self.margin = 10
+ self.pad_rotation = 0
+
+ self.init_messages = []
+ self.stdout = None
+ self.stderr = None
+
+ self.keep_cfg = False
+ self.ef_format = False
+ self.use_console = False
+
+ def init_padframe(self):
+ self.set_project()
+ self.vlogimport()
+ self.readplacement(precheck=True)
+ self.resolve()
+ self.generate(0)
+
+ # Local routines for handling printing to the text console
+
+ def print(self, message, file=None, end='\n', flush=True):
+ if not file:
+ if not self.use_console:
+ file = sys.stdout
+ else:
+ file = ConsoleText.StdoutRedirector(self.text_box)
+ if self.stdout:
+ print(message, file=file, end=end)
+ if flush:
+ self.stdout.flush()
+ self.update_idletasks()
+ else:
+ self.init_messages.append(message)
+
+ def text_to_console(self):
+ # Redirect stdout and stderr to the console as the last thing to do. . .
+ # Otherwise errors in the GUI get sucked into the void.
+
+ self.stdout = sys.stdout
+ self.stderr = sys.stderr
+ if self.use_console:
+ sys.stdout = ConsoleText.StdoutRedirector(self.text_box)
+ sys.stderr = ConsoleText.StderrRedirector(self.text_box)
+
+ if len(self.init_messages) > 0:
+ for message in self.init_messages:
+ self.print(message)
+ self.init_messages = []
+
+ # Set the project name(s). This is the name of the top-level verilog.
+ # The standard protocol is that the project directory contains a file
+ # project.json that defines a name 'ip-name' that is the same as the
+ # layout name, the verilog module name, etc.
+
+ def set_project(self):
+ # Check pwd
+ pwdname = self.projectpath if self.projectpath else os.getcwd()
+
+ subdir = os.path.split(pwdname)[1]
+ if subdir == 'mag' or subdir == 'verilog':
+ projectpath = os.path.split(pwdname)[0]
+ else:
+ projectpath = pwdname
+
+ projectroot = os.path.split(projectpath)[0]
+ projectdirname = os.path.split(projectpath)[1]
+
+ # Check for efabless format. This is probably more complicated than
+ # it deserves to be. Option -ef_format is the best way to specify
+ # efabless format. However, if it is not specified, then check the
+ # technology PDK directory and the project directory for the tell-tale
+ # ".ef-config" (efabless format) directory vs. ".config" (not efabless
+ # format).
+
+ if not self.ef_format:
+ if os.path.exists(projectpath + '/.ef-config'):
+ self.ef_format = True
+ elif self.techpath:
+ if os.path.exists(self.techpath + '/.ef-config'):
+ self.ef_format = True
+ else:
+ # Do a quick consistency check. Honor the -ef_format option but warn if
+ # there is an apparent inconsistency.
+ if os.path.exists(projectpath + '/.config'):
+ self.print('Warning: -ef_format used in apparently non-efabless setup.')
+ elif self.techpath:
+ if os.path.exists(self.techpath + '/.config'):
+ self.print('Warning: -ef_format used in apparently non-efabless setup.')
+
+ # Check for project.json
+
+ jsonname = None
+ if os.path.isfile(projectpath + '/project.json'):
+ jsonname = projectpath + '/project.json'
+ elif os.path.isfile(projectroot + '/' + projectdirname + '.json'):
+ jsonname = projectroot + '/' + projectdirname + '.json'
+ if os.path.isfile(projectroot + '/project.json'):
+ # Just in case this was started from some other subdirectory
+ projectpath = projectroot
+ jsonname = projectroot + '/project.json'
+
+ if jsonname:
+ self.print('Reading project JSON file ' + jsonname)
+ with open(jsonname, 'r') as ifile:
+ topdata = json.load(ifile)
+ if 'data-sheet' in topdata:
+ dsheet = topdata['data-sheet']
+ if 'ip-name' in dsheet:
+ self.project = dsheet['ip-name']
+ self.projectpath = projectpath
+ else:
+ self.print('No project JSON file; using directory name as the project name.')
+ self.project = os.path.split(projectpath)[1]
+ self.projectpath = projectpath
+
+ self.print('Project name is ' + self.project + ' (' + self.projectpath + ')')
+
+ # Functions for drag-and-drop capability
+ def add_draggable(self, tag):
+ self.canvas.tag_bind(tag, '<ButtonPress-1>', self.on_button_press)
+ self.canvas.tag_bind(tag, '<ButtonRelease-1>', self.on_button_release)
+ self.canvas.tag_bind(tag, '<B1-Motion>', self.on_button_motion)
+ self.canvas.tag_bind(tag, '<ButtonPress-2>', self.on_button2_press)
+ self.canvas.tag_bind(tag, '<ButtonPress-3>', self.on_button3_press)
+
+ def on_button_press(self, event):
+ '''Begining drag of an object'''
+ # Find the closest item, then record its tag.
+ locx = event.x + self.canvas.canvasx(0)
+ locy = event.y + self.canvas.canvasy(0)
+ item = self.canvas.find_closest(locx, locy)[0]
+ self.event_data['tag'] = self.canvas.gettags(item)[0]
+ self.event_data['x0'] = event.x
+ self.event_data['y0'] = event.y
+ self.event_data['x'] = event.x
+ self.event_data['y'] = event.y
+
+ def on_button2_press(self, event):
+ '''Flip an object (excluding corners)'''
+ locx = event.x + self.canvas.canvasx(0)
+ locy = event.y + self.canvas.canvasy(0)
+ item = self.canvas.find_closest(locx, locy)[0]
+ tag = self.canvas.gettags(item)[0]
+
+ try:
+ corecell = next(item for item in self.coregroup if item['name'] == tag)
+ except:
+ try:
+ pad = next(item for item in self.Npads if item['name'] == tag)
+ except:
+ pad = None
+ if not pad:
+ try:
+ pad = next(item for item in self.Epads if item['name'] == tag)
+ except:
+ pad = None
+ if not pad:
+ try:
+ pad = next(item for item in self.Spads if item['name'] == tag)
+ except:
+ pad = None
+ if not pad:
+ try:
+ pad = next(item for item in self.Wpads if item['name'] == tag)
+ except:
+ pad = None
+ if not pad:
+ self.print('Error: Object cannot be flipped.')
+ else:
+ # Flip the pad (in the only way meaningful for the pad).
+ orient = pad['o']
+ if orient == 'N':
+ pad['o'] = 'FN'
+ elif orient == 'E':
+ pad['o'] = 'FW'
+ elif orient == 'S':
+ pad['o'] = 'FS'
+ elif orient == 'W':
+ pad['o'] = 'FE'
+ elif orient == 'FN':
+ pad['o'] = 'N'
+ elif orient == 'FE':
+ pad['o'] = 'W'
+ elif orient == 'FS':
+ pad['o'] = 'S'
+ elif orient == 'FW':
+ pad['o'] = 'E'
+ else:
+ # Flip the cell. Use the DEF meaning of flip, which is to
+ # add or subtract 'F' from the orientation.
+ orient = corecell['o']
+ if not 'F' in orient:
+ corecell['o'] = 'F' + orient
+ else:
+ corecell['o'] = orient[1:]
+
+ # Redraw
+ self.populate(0)
+
+ def on_button3_press(self, event):
+ '''Rotate a core object (no pads) '''
+ locx = event.x + self.canvas.canvasx(0)
+ locy = event.y + self.canvas.canvasy(0)
+ item = self.canvas.find_closest(locx, locy)[0]
+ tag = self.canvas.gettags(item)[0]
+
+ try:
+ corecell = next(item for item in self.coregroup if item['name'] == tag)
+ except:
+ self.print('Error: Object cannot be rotated.')
+ else:
+ # Modify its orientation
+ orient = corecell['o']
+ if orient == 'N':
+ corecell['o'] = 'E'
+ elif orient == 'E':
+ corecell['o'] = 'S'
+ elif orient == 'S':
+ corecell['o'] = 'W'
+ elif orient == 'W':
+ corecell['o'] = 'N'
+ elif orient == 'FN':
+ corecell['o'] = 'FW'
+ elif orient == 'FW':
+ corecell['o'] = 'FS'
+ elif orient == 'FS':
+ corecell['o'] = 'FE'
+ elif orient == 'FE':
+ corecell['o'] = 'FN'
+
+ # rewrite the core DEF file
+ self.write_core_def()
+
+ # Redraw
+ self.populate(0)
+
+ def on_button_motion(self, event):
+ '''Handle dragging of an object'''
+ # compute how much the mouse has moved
+ delta_x = event.x - self.event_data['x']
+ delta_y = event.y - self.event_data['y']
+ # move the object the appropriate amount
+ self.canvas.move(self.event_data['tag'], delta_x, delta_y)
+ # record the new position
+ self.event_data['x'] = event.x
+ self.event_data['y'] = event.y
+
+ def on_button_release(self, event):
+ '''End drag of an object'''
+
+ # Find the pad associated with the tag and update its position information
+ tag = self.event_data['tag']
+
+ # Collect pads in clockwise order. Note that E and S rows are not clockwise
+ allpads = []
+ allpads.extend(self.Npads)
+ allpads.extend(self.NEpad)
+ allpads.extend(reversed(self.Epads))
+ allpads.extend(self.SEpad)
+ allpads.extend(reversed(self.Spads))
+ allpads.extend(self.SWpad)
+ allpads.extend(self.Wpads)
+ allpads.extend(self.NWpad)
+
+ # Create a list of row references (also in clockwise order, but no reversing)
+ padrows = [self.Npads, self.NEpad, self.Epads, self.SEpad, self.Spads, self.SWpad, self.Wpads, self.NWpad]
+
+ # Record the row or corner where this pad was located before the move
+ for row in padrows:
+ try:
+ pad = next(item for item in row if item['name'] == tag)
+ except:
+ pass
+ else:
+ padrow = row
+ break
+
+ # Currently there is no procedure to move a pad out of the corner
+ # position; corners are fixed by definition.
+ if padrow == self.NEpad or padrow == self.SEpad or padrow == self.SWpad or padrow == self.NWpad:
+ # Easier to run generate() than to put the pad back. . .
+ self.generate(0)
+ return
+
+ # Find the original center point of the pad being moved
+
+ padllx = pad['x']
+ padlly = pad['y']
+ if pad['o'] == 'N' or pad['o'] == 'S':
+ padurx = padllx + pad['width']
+ padury = padlly + pad['height']
+ else:
+ padurx = padllx + pad['height']
+ padury = padlly + pad['width']
+ padcx = (padllx + padurx) / 2
+ padcy = (padlly + padury) / 2
+
+ # Add distance from drag information (note that drag position in y
+ # is negative relative to the chip dimensions)
+ padcx += (self.event_data['x'] - self.event_data['x0']) / self.scale
+ padcy -= (self.event_data['y'] - self.event_data['y0']) / self.scale
+
+ # reset the drag information
+ self.event_data['tag'] = None
+ self.event_data['x'] = 0
+ self.event_data['y'] = 0
+ self.event_data['x0'] = 0
+ self.event_data['y0'] = 0
+
+ # Find the distance from the pad to all other pads, and get the two
+ # closest entries.
+
+ wwidth = self.urx - self.llx
+ dist0 = wwidth
+ dist1 = wwidth
+ pad0 = None
+ pad1 = None
+
+ for npad in allpads:
+ if npad == pad:
+ continue
+
+ npadllx = npad['x']
+ npadlly = npad['y']
+ if npad['o'] == 'N' or npad['o'] == 'S':
+ npadurx = npadllx + npad['width']
+ npadury = npadlly + npad['height']
+ else:
+ npadurx = npadllx + npad['height']
+ npadury = npadlly + npad['width']
+ npadcx = (npadllx + npadurx) / 2
+ npadcy = (npadlly + npadury) / 2
+
+ deltx = npadcx - padcx
+ delty = npadcy - padcy
+ pdist = math.sqrt(deltx * deltx + delty * delty)
+ if pdist < dist0:
+ dist1 = dist0
+ pad1 = pad0
+ dist0 = pdist
+ pad0 = npad
+
+ elif pdist < dist1:
+ dist1 = pdist
+ pad1 = npad
+
+ # Diagnostic
+ # self.print('Two closest pads to pad ' + pad['name'] + ' (' + pad['cell'] + '): ')
+ # self.print(pad0['name'] + ' (' + pad0['cell'] + ') dist = ' + str(dist0))
+ # self.print(pad1['name'] + ' (' + pad1['cell'] + ') dist = ' + str(dist1))
+
+ # Record the row or corner where these pads are
+ for row in padrows:
+ try:
+ testpad = next(item for item in row if item['name'] == pad0['name'])
+ except:
+ pass
+ else:
+ padrow0 = row
+ break
+
+ for row in padrows:
+ try:
+ testpad = next(item for item in row if item['name'] == pad1['name'])
+ except:
+ pass
+ else:
+ padrow1 = row
+ break
+
+ # Remove pad from its own row
+ padrow.remove(pad)
+
+ # Insert pad into new row. Watch for wraparound from the last entry to the first
+ padidx0 = allpads.index(pad0)
+ padidx1 = allpads.index(pad1)
+ if padidx0 == 0 and padidx1 > 2:
+ padidx1 = -1
+
+ if padidx1 > padidx0:
+ padafter = pad1
+ rowafter = padrow1
+ padbefore = pad0
+ rowbefore = padrow0
+ else:
+ padafter = pad0
+ rowafter = padrow0
+ padbefore = pad1
+ rowbefore = padrow1
+
+ # Do not replace corner positions (? may be necessary ?)
+ if rowafter == self.NWpad:
+ self.Wpads.append(pad)
+ elif rowafter == self.NWpad:
+ self.Npads.append(pad)
+ elif rowafter == self.SEpad:
+ self.Epads.insert(0, pad)
+ elif rowafter == self.SWpad:
+ self.Spads.insert(0, pad)
+ elif rowafter == self.Wpads or rowafter == self.Npads:
+ idx = rowafter.index(padafter)
+ rowafter.insert(idx, pad)
+ elif rowbefore == self.NEpad:
+ self.Epads.append(pad)
+ elif rowbefore == self.SEpad:
+ self.Spads.append(pad)
+ else:
+ # rows E and S are ordered counterclockwise
+ idx = rowbefore.index(padbefore)
+ rowbefore.insert(idx, pad)
+
+ # Re-run padring
+ self.generate(0)
+
+ def on_scrollwheel(self, event):
+ if event.num == 4:
+ zoomval = 1.1;
+ elif event.num == 5:
+ zoomval = 0.9;
+ else:
+ zoomval = 1.0;
+
+ self.scale *= zoomval
+ self.canvas.scale('all', -15 * zoomval, -15 * zoomval, zoomval, zoomval)
+ self.event_data['x'] *= zoomval
+ self.event_data['y'] *= zoomval
+ self.event_data['x0'] *= zoomval
+ self.event_data['y0'] *= zoomval
+ self.frame_configure(event)
+
+ # Callback functions similar to the pad event callbacks above, but for
+ # core cells. Unlike pad cells, core cells can be rotated and flipped
+ # arbitrarily, and they do not force a recomputation of the padframe
+ # unless their position forces the padframe to expand
+
+ def add_core_draggable(self, tag):
+ self.canvas.tag_bind(tag, '<ButtonPress-1>', self.on_button_press)
+ self.canvas.tag_bind(tag, '<ButtonRelease-1>', self.core_on_button_release)
+ self.canvas.tag_bind(tag, '<B1-Motion>', self.on_button_motion)
+ self.canvas.tag_bind(tag, '<ButtonPress-2>', self.on_button2_press)
+ self.canvas.tag_bind(tag, '<ButtonPress-3>', self.on_button3_press)
+
+ def core_on_button_release(self, event):
+ '''End drag of a core cell'''
+
+ # Find the pad associated with the tag and update its position information
+ tag = self.event_data['tag']
+
+ try:
+ corecell = next(item for item in self.coregroup if item['name'] == tag)
+ except:
+ self.print('Error: cell ' + item['name'] + ' is not in coregroup!')
+ else:
+ # Modify its position values
+ corex = corecell['x']
+ corey = corecell['y']
+
+ # Add distance from drag information (note that drag position in y
+ # is negative relative to the chip dimensions)
+ deltax = (self.event_data['x'] - self.event_data['x0']) / self.scale
+ deltay = (self.event_data['y'] - self.event_data['y0']) / self.scale
+
+ corecell['x'] = corex + deltax
+ corecell['y'] = corey - deltay
+
+ # rewrite the core DEF file
+ self.write_core_def()
+
+ # reset the drag information
+ self.event_data['tag'] = None
+ self.event_data['x'] = 0
+ self.event_data['y'] = 0
+ self.event_data['x0'] = 0
+ self.event_data['y0'] = 0
+
+ # Critically needed or else frame does not resize to scrollbars!
+ def grid_configure(self, padx, pady):
+ pass
+
+ # Redraw the chip frame view in response to changes in the pad list
+ def redraw_frame(self):
+ self.canvas.coords('boundary', self.llx, self.urx, self.lly, self.ury)
+
+ # Update the canvas scrollregion to incorporate all the interior windows
+ def frame_configure(self, event):
+ if self.do_gui == False:
+ return
+ self.update_idletasks()
+ bbox = self.canvas.bbox("all")
+ try:
+ newbbox = (-15, -15, bbox[2] + 15, bbox[3] + 15)
+ except:
+ pass
+ else:
+ self.canvas.configure(scrollregion = newbbox)
+
+ # Fill the GUI entries with resident data
+ def populate(self, level):
+ if self.do_gui == False:
+ return
+
+ if level > 1:
+ self.print('Recursion error: Returning now.')
+ return
+
+ self.print('Populating floorplan view.')
+
+ # Remove all entries from the canvas
+ self.canvas.delete('all')
+
+ allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+ notfoundlist = []
+
+ for pad in allpads:
+ if 'x' not in pad:
+ self.print('Error: Pad ' + pad['name'] + ' has no placement information.')
+ continue
+ llx = int(pad['x'])
+ lly = int(pad['y'])
+ pado = pad['o']
+ try:
+ padcell = next(item for item in self.celldefs if item['name'] == pad['cell'])
+ except:
+ # This should not happen (failsafe)
+ if pad['cell'] not in notfoundlist:
+ self.print('Warning: there is no cell named ' + pad['cell'] + ' in the libraries.')
+ notfoundlist.append(pad['cell'])
+ continue
+ padw = padcell['width']
+ padh = padcell['height']
+ if 'N' in pado or 'S' in pado:
+ urx = int(llx + padw)
+ ury = int(lly + padh)
+ else:
+ urx = int(llx + padh)
+ ury = int(lly + padw)
+
+ pad['llx'] = llx
+ pad['lly'] = lly
+ pad['urx'] = urx
+ pad['ury'] = ury
+
+ # Note that the DEF coordinate system is reversed in Y from the canvas. . .
+
+ height = self.ury - self.lly
+ for pad in allpads:
+
+ llx = pad['llx']
+ lly = height - pad['lly']
+ urx = pad['urx']
+ ury = height - pad['ury']
+
+ tag_id = pad['name']
+ if 'subclass' in pad:
+ if pad['subclass'] == 'POWER':
+ pad_color = 'orange2'
+ elif pad['subclass'] == 'INOUT':
+ pad_color = 'yellow'
+ elif pad['subclass'] == 'OUTPUT':
+ pad_color = 'powder blue'
+ elif pad['subclass'] == 'INPUT':
+ pad_color = 'goldenrod1'
+ elif pad['subclass'] == 'SPACER':
+ pad_color = 'green yellow'
+ elif pad['class'] == 'ENDCAP':
+ pad_color = 'green yellow'
+ elif pad['subclass'] == '' or pad['class'] == ';':
+ pad_color = 'khaki1'
+ else:
+ self.print('Unhandled pad class ' + pad['class'])
+ pad_color = 'gray'
+ else:
+ pad_color = 'gray'
+
+ sllx = self.scale * llx
+ slly = self.scale * lly
+ surx = self.scale * urx
+ sury = self.scale * ury
+
+ self.canvas.create_rectangle((sllx, slly), (surx, sury), fill=pad_color, tags=[tag_id])
+ cx = (sllx + surx) / 2
+ cy = (slly + sury) / 2
+
+ s = 10 if pad['width'] >= 10 else pad['width']
+ if pad['height'] < s:
+ s = pad['height']
+
+ # Create an indicator line at the bottom left corner of the cell
+ if pad['o'] == 'N':
+ allx = sllx
+ ally = slly - s
+ aurx = sllx + s
+ aury = slly
+ elif pad['o'] == 'E':
+ allx = sllx
+ ally = sury + s
+ aurx = sllx + s
+ aury = sury
+ elif pad['o'] == 'S':
+ allx = surx
+ ally = sury + s
+ aurx = surx - s
+ aury = sury
+ elif pad['o'] == 'W':
+ allx = surx
+ ally = slly - s
+ aurx = surx - s
+ aury = slly
+ elif pad['o'] == 'FN':
+ allx = surx
+ ally = slly - s
+ aurx = surx - s
+ aury = slly
+ elif pad['o'] == 'FE':
+ allx = surx
+ ally = sury + s
+ aurx = surx - s
+ aury = sury
+ elif pad['o'] == 'FS':
+ allx = sllx
+ ally = sury + s
+ aurx = sllx + s
+ aury = sury
+ elif pad['o'] == 'FW':
+ allx = sllx
+ ally = slly - s
+ aurx = sllx + s
+ aury = slly
+ self.canvas.create_line((allx, ally), (aurx, aury), tags=[tag_id])
+
+ # Rotate text on top and bottom rows if the tkinter version allows it.
+ if tkinter.TclVersion >= 8.6:
+ if pad['o'] == 'N' or pad['o'] == 'S':
+ angle = 90
+ else:
+ angle = 0
+ self.canvas.create_text((cx, cy), text=pad['name'], angle=angle, tags=[tag_id])
+ else:
+ self.canvas.create_text((cx, cy), text=pad['name'], tags=[tag_id])
+
+ # Make the pad draggable
+ self.add_draggable(tag_id)
+
+ # Now add the core cells
+ for cell in self.coregroup:
+ if 'x' not in cell:
+ self.print('Error: Core cell ' + cell['name'] + ' has no placement information.')
+ continue
+ # else:
+ # self.print('Diagnostic: Creating object for core cell ' + cell['name'])
+ llx = int(cell['x'])
+ lly = int(cell['y'])
+ cello = cell['o']
+ try:
+ corecell = next(item for item in self.coredefs if item['name'] == cell['cell'])
+ except:
+ # This should not happen (failsafe)
+ if cell['cell'] not in notfoundlist:
+ self.print('Warning: there is no cell named ' + cell['cell'] + ' in the libraries.')
+ notfoundlist.append(cell['cell'])
+ continue
+ cellw = corecell['width']
+ cellh = corecell['height']
+ if 'N' in cello or 'S' in cello:
+ urx = int(llx + cellw)
+ ury = int(lly + cellh)
+ else:
+ urx = int(llx + cellh)
+ ury = int(lly + cellw)
+ print('NOTE: cell ' + corecell['name'] + ' is rotated, w = ' + str(urx - llx) + '; h = ' + str(ury - lly))
+
+ cell['llx'] = llx
+ cell['lly'] = lly
+ cell['urx'] = urx
+ cell['ury'] = ury
+
+ # Watch for out-of-window position in core cells.
+ corellx = self.llx
+ corelly = self.lly
+ coreurx = self.urx
+ coreury = self.ury
+
+ for cell in self.coregroup:
+
+ if 'llx' not in cell:
+ # Error message for this was handled above
+ continue
+
+ llx = cell['llx']
+ lly = height - cell['lly']
+ urx = cell['urx']
+ ury = height - cell['ury']
+
+ # Check for out-of-window cell
+ if llx < corellx:
+ corellx = llx
+ if lly < corelly:
+ corelly = lly
+ if urx > coreurx:
+ coreurx = urx
+ if ury > coreury:
+ coreury = ury
+
+ tag_id = cell['name']
+ cell_color = 'gray40'
+
+ sllx = self.scale * llx
+ slly = self.scale * lly
+ surx = self.scale * urx
+ sury = self.scale * ury
+
+ self.canvas.create_rectangle((sllx, slly), (surx, sury), fill=cell_color, tags=[tag_id])
+ cx = (sllx + surx) / 2
+ cy = (slly + sury) / 2
+
+ s = 10 if cell['width'] >= 10 else cell['width']
+ if cell['height'] < s:
+ s = cell['height']
+
+ # Create an indicator line at the bottom left corner of the cell
+ if cell['o'] == 'N':
+ allx = sllx
+ ally = slly - s
+ aurx = sllx + s
+ aury = slly
+ elif cell['o'] == 'E':
+ allx = sllx
+ ally = sury + s
+ aurx = sllx + s
+ aury = sury
+ elif cell['o'] == 'S':
+ allx = surx
+ ally = sury + s
+ aurx = surx - s
+ aury = sury
+ elif cell['o'] == 'W':
+ allx = surx
+ ally = slly - s
+ aurx = surx - s
+ aury = slly
+ elif cell['o'] == 'FN':
+ allx = surx
+ ally = slly - s
+ aurx = surx - s
+ aury = slly
+ elif cell['o'] == 'FE':
+ allx = surx
+ ally = sury + s
+ aurx = surx - s
+ aury = sury
+ elif cell['o'] == 'FS':
+ allx = sllx
+ ally = sury + s
+ aurx = sllx + s
+ aury = sury
+ elif cell['o'] == 'FW':
+ allx = sllx
+ ally = slly - s
+ aurx = sllx + s
+ aury = slly
+ self.canvas.create_line((allx, ally), (aurx, aury), tags=[tag_id])
+
+ # self.print('Created entry for cell ' + cell['name'] + ' at {0:g}, {1:g}'.format(cx, cy))
+
+ # Rotate text on top and bottom rows if the tkinter version allows it.
+ if tkinter.TclVersion >= 8.6:
+ if 'N' in cell['o'] or 'S' in cell['o']:
+ angle = 90
+ else:
+ angle = 0
+ self.canvas.create_text((cx, cy), text=cell['name'], angle=angle, tags=[tag_id])
+ else:
+ self.canvas.create_text((cx, cy), text=cell['name'], tags=[tag_id])
+
+ # Make the core cell draggable
+ self.add_core_draggable(tag_id)
+
+ # Is there a boundary size defined?
+ if self.urx > self.llx and self.ury > self.lly:
+ self.create_boundary()
+
+ # Did the core extend into negative X or Y? If so, adjust all canvas
+ # coordinates to fit in the window, or else objects cannot be reached
+ # even by zooming out (since zooming is pinned on the top corner).
+
+ offsetx = 0
+ offsety = 0
+
+ # NOTE: Probably want to check if the core exceeds the inner
+ # dimension of the pad ring, not the outer (to check and to do).
+
+ if corellx < self.llx:
+ offsetx = self.llx - corellx
+ if corelly < self.lly:
+ offsety = self.lly - corelly
+ if offsetx > 0 or offsety > 0:
+ self.canvas.move("all", offsetx, offsety)
+ # An offset implies that the chip is core limited, and the
+ # padframe requires additional space. This can be accomplished
+ # simply by running "Generate". NOTE: Since generate() calls
+ # populate(), be VERY SURE that this does not infinitely recurse!
+ self.generate(level)
+
+ # Generate a DEF file of the core area
+
+ def write_core_def(self):
+ self.print('Writing core placementment information in DEF file "core.def".')
+
+ mag_path = self.projectpath + '/mag'
+
+ # The core cells must always clear the I/O pads on the left and
+ # bottom (with the ad-hoc margin of self.margin). If core cells have
+ # been moved to the left or down past the padframe edge, then the
+ # entire core needs to be repositioned.
+
+ # To be done: draw a boundary around the core, let the edges of that
+ # boundary be draggable, and let the difference between the boundary
+ # and the core area define the margin.
+
+ if self.SWpad != []:
+ corellx = self.SWpad[0]['x'] + self.SWpad[0]['width'] + self.margin
+ corelly = self.SWpad[0]['y'] + self.SWpad[0]['height'] + self.margin
+ else:
+ corellx = self.Wpads[0]['x'] + self.Wpads[0]['height'] + self.margin
+ corelly = self.Spads[0]['x'] + self.Spads[0]['height'] + self.margin
+
+ offsetx = 0
+ offsety = 0
+ for corecell in self.coregroup:
+ if corecell['x'] < corellx:
+ if corellx - corecell['x'] > offsetx:
+ offsetx = corellx - corecell['x']
+ if corecell['y'] < corelly:
+ if corelly - corecell['y'] > offsety:
+ offsety = corelly - corecell['y']
+ if offsetx > 0 or offsety > 0:
+ for corecell in self.coregroup:
+ corecell['x'] += offsetx
+ corecell['y'] += offsety
+
+ # Now write the core DEF file
+
+ with open(mag_path + '/core.def', 'w') as ofile:
+ print('DESIGN CORE ;', file=ofile)
+ print('UNITS DISTANCE MICRONS 1000 ;', file=ofile)
+ print('COMPONENTS {0:d} ;'.format(len(self.coregroup)), file=ofile)
+ for corecell in self.coregroup:
+ print(' - ' + corecell['name'] + ' ' + corecell['cell'], file=ofile)
+ print(' + PLACED ( {0:d} {1:d} ) {2:s} ;'.format(int(corecell['x'] * 1000), int(corecell['y'] * 1000), corecell['o']), file=ofile)
+ print ('END COMPONENTS', file=ofile)
+ print ('END DESIGN', file=ofile)
+
+ # Create the chip boundary area
+
+ def create_boundary(self):
+ scale = self.scale
+ llx = (self.llx - 10) * scale
+ lly = (self.lly - 10) * scale
+ urx = (self.urx + 10) * scale
+ ury = (self.ury + 10) * scale
+
+ pad_color = 'plum1'
+ tag_id = 'boundary'
+ self.canvas.create_rectangle((llx, lly), (urx, ury), outline=pad_color, width=2, tags=[tag_id])
+ # Add text to the middle representing the chip and core areas
+ cx = ((self.llx + self.urx) / 2) * scale
+ cy = ((self.lly + self.ury) / 2) * scale
+ width = self.urx - self.llx
+ height = self.ury - self.lly
+ areatext = 'Chip dimensions (um): {0:g} x {1:g}'.format(width, height)
+ tag_id = 'chiparea'
+ self.canvas.create_text((cx, cy), text=areatext, tags=[tag_id])
+
+ # Rotate orientation according to self.pad_rotation.
+
+ def rotate_orientation(self, orient_in):
+ orient_v = ['N', 'E', 'S', 'W', 'N', 'E', 'S', 'W']
+ idxadd = int(self.pad_rotation / 90)
+ idx = orient_v.index(orient_in)
+ return orient_v[idx + idxadd]
+
+ # Read a list of cell macros (name, size, class) from a LEF library
+
+ def read_lef_macros(self, libpath, libname = None, libtype = 'iolib'):
+ if libtype == 'iolib':
+ libtext = 'I/O '
+ elif libtype == 'celllib':
+ libtext = 'core '
+ else:
+ libtext = ''
+
+ macros = []
+
+ if libname:
+ if os.path.splitext(libname)[1] == '':
+ libname += '.lef'
+ leffiles = glob.glob(libpath + '/' + libname)
+ else:
+ leffiles = glob.glob(libpath + '/*.lef')
+ if leffiles == []:
+ if libname:
+ self.print('WARNING: No file ' + libpath + '/' + libname + '.lef')
+ else:
+ self.print('WARNING: No files ' + libpath + '/*.lef')
+ for leffile in leffiles:
+ libpath = os.path.split(leffile)[0]
+ libname = os.path.split(libpath)[1]
+ self.print('Reading LEF ' + libtext + 'library ' + leffile)
+ with open(leffile, 'r') as ifile:
+ ilines = ifile.read().splitlines()
+ in_macro = False
+ for iline in ilines:
+ iparse = iline.split()
+ if iparse == []:
+ continue
+ elif iparse[0] == 'MACRO':
+ in_macro = True
+ newmacro = {}
+ newmacro['name'] = iparse[1]
+ newmacro[libtype] = leffile
+ macros.append(newmacro)
+ elif in_macro:
+ if iparse[0] == 'END':
+ if len(iparse) > 1 and iparse[1] == newmacro['name']:
+ in_macro = False
+ elif iparse[0] == 'CLASS':
+ newmacro['class'] = iparse[1]
+ if len(iparse) > 2:
+ newmacro['subclass'] = iparse[2]
+
+ # Use the 'ENDCAP' class to identify pad rotations
+ # other than BOTTOMLEFT. This is somewhat ad-hoc
+ # depending on the foundry; may not be generally
+ # applicable.
+
+ if newmacro['class'] == 'ENDCAP':
+ if newmacro['subclass'] == 'TOPLEFT':
+ self.pad_rotation = 90
+ elif newmacro['subclass'] == 'TOPRIGHT':
+ self.pad_rotation = 180
+ elif newmacro['subclass'] == 'BOTTOMRIGHT':
+ self.pad_rotation = 270
+ else:
+ newmacro['subclass'] = None
+ elif iparse[0] == 'SIZE':
+ newmacro['width'] = float(iparse[1])
+ newmacro['height'] = float(iparse[3])
+ elif iparse[0] == 'ORIGIN':
+ newmacro['x'] = float(iparse[1])
+ newmacro['y'] = float(iparse[2])
+ return macros
+
+ # Read a list of cell names from a verilog file
+ # If filename is relative, then check in the same directory as the verilog
+ # top-level netlist (vlogpath) and in the subdirectory 'source/' of the top-
+ # level directory. Also check in the ~/design/ip/ directory. These are
+ # common include paths for the simulation.
+
+ def read_verilog_lib(self, incpath, vlogpath):
+ iocells = []
+ if not os.path.isfile(incpath) and incpath[0] != '/':
+ locincpath = vlogpath + '/' + incpath
+ if not os.path.isfile(locincpath):
+ locincpath = vlogpath + '/source/' + incpath
+ if not os.path.isfile(locincpath):
+ projectpath = os.path.split(vlogpath)[0]
+ designpath = os.path.split(projectpath)[0]
+ locincpath = designpath + '/ip/' + incpath
+ else:
+ locincpath = incpath
+
+ if not os.path.isfile(locincpath):
+ self.print('File ' + incpath + ' not found (at ' + locincpath + ')!')
+ else:
+ self.print('Reading verilog library ' + locincpath)
+ with open(locincpath, 'r') as ifile:
+ ilines = ifile.read().splitlines()
+ for iline in ilines:
+ iparse = re.split('[\t ()]', iline)
+ while '' in iparse:
+ iparse.remove('')
+ if iparse == []:
+ continue
+ elif iparse[0] == 'module':
+ iocells.append(iparse[1])
+ return iocells
+
+ # Generate a LEF abstract view from a magic layout. If "outpath" is not
+ # "None", then write output to outputpath (this is required if the input
+ # file is in a read-only directory).
+
+ def write_lef_file(self, magfile, outpath=None):
+ mag_path = os.path.split(magfile)[0]
+ magfullname = os.path.split(magfile)[1]
+ module = os.path.splitext(magfullname)[0]
+
+ if outpath:
+ write_path = outpath
+ else:
+ write_path = mag_path
+
+ self.print('Generating LEF view from layout for module ' + module)
+
+ with open(write_path + '/pfg_write_lef.tcl', 'w') as ofile:
+ print('drc off', file=ofile)
+ print('box 0 0 0 0', file=ofile)
+ # NOTE: Using "-force" option in case an IP with a different but
+ # compatible tech is used (e.g., EFHX035A IP inside EFXH035C). This
+ # is not checked for legality!
+ if outpath:
+ print('load ' + magfile + ' -force', file=ofile)
+ else:
+ print('load ' + module + ' -force', file=ofile)
+ print('lef write -hide', file=ofile)
+ print('quit', file=ofile)
+
+ magicexec = self.magic_path if self.magic_path else 'magic'
+ mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+ 'pfg_write_lef.tcl'],
+ stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = write_path, universal_newlines = True)
+
+ self.watch(mproc)
+ os.remove(write_path + '/pfg_write_lef.tcl')
+
+ # Watch a running process, polling for output and updating the GUI message
+ # window as output arrives. Return only when the process has exited.
+ # Note that this process cannot handle stdin(), so any input to the process
+ # must be passed from a file.
+
+ def watch(self, process):
+ if process == None:
+ return
+
+ while True:
+ status = process.poll()
+ if status != None:
+ try:
+ outputpair = process.communicate(timeout=1)
+ except ValueError:
+ self.print("Process forced stop, status " + str(status))
+ else:
+ for line in outputpair[0].splitlines():
+ self.print(line)
+ for line in outputpair[1].splitlines():
+ self.print(line, file=sys.stderr)
+ break
+ else:
+ sresult = select.select([process.stdout, process.stderr], [], [], 0)[0]
+ if process.stdout in sresult:
+ outputline = process.stdout.readline().strip()
+ self.print(outputline)
+ elif process.stderr in sresult:
+ outputline = process.stderr.readline().strip()
+ self.print(outputline, file=sys.stderr)
+ else:
+ self.update_idletasks()
+
+ # Reimport the pad list by reading the top-level verilog netlist. Determine
+ # what pads are listed in the file, and check against the existing pad list.
+
+ # The verilog/ directory should have a .v file containing a module of the
+ # same name as self.project (ip-name). The .v filename should have the
+ # same name as well (but not necessarily). To do: Handle import of
+ # projects having a top-level schematic instead of a verilog netlist.
+
+ def vlogimport(self):
+
+ if self.ef_format:
+ config_dir = '/.ef-config'
+ else:
+ config_dir = '/.config'
+
+ # First find the process PDK name for this project. Read the nodeinfo.json
+ # file and find the list of I/O cell libraries.
+
+ if self.techpath:
+ pdkpath = self.techpath
+ elif os.path.islink(self.projectpath + config_dir + '/techdir'):
+ pdkpath = os.path.realpath(self.projectpath + config_dir + '/techdir')
+ else:
+ self.print('Error: Cannot determine path to PDK. Try using option -tech-path=')
+ return
+
+ self.print('Importing verilog sources.')
+
+ nodeinfopath = pdkpath + config_dir + '/nodeinfo.json'
+ ioleflist = []
+ if os.path.exists(nodeinfopath):
+ self.print('Reading known I/O cell libraries from ' + nodeinfopath)
+ with open(nodeinfopath, 'r') as ifile:
+ itop = json.load(ifile)
+ if 'iocells' in itop:
+ ioleflist = []
+ for iolib in itop['iocells']:
+ if '/' in iolib:
+ # Entries <lib>/<cell> refer to specific files
+ if self.ef_format:
+ iolibpath = pdkpath + '/libs.ref/lef/' + iolib
+ else:
+ iolibpath = pdkpath + '/libs.ref/' + iolib
+ if os.path.splitext(iolib)[1] == '':
+ if not os.path.exists(iolibpath):
+ iolibpath = iolibpath + '.lib'
+ if not os.path.exists(iolibpath):
+ self.print('Warning: nodeinfo.json bad I/O library path ' + iolibpath)
+ ioleflist.append(iolibpath)
+ else:
+ # All other entries refer to everything in the directory.
+ if self.ef_format:
+ iolibpath = pdkpath + '/libs.ref/lef/' + iolib
+ else:
+ iolibpath = pdkpath + '/libs.ref/' + iolib + '/lef/'
+ iolibfiles = glob.glob(iolibpath + '/*.lef')
+ if len(iolibfiles) == 0:
+ self.print('Warning: nodeinfo.json bad I/O library path ' + iolibpath)
+ ioleflist.extend(iolibfiles)
+ else:
+ # Diagnostic
+ self.print('Cannot read PDK information file ' + nodeinfopath)
+
+ # Fallback behavior: List everything in libs.ref/lef/ beginning with "IO"
+ if len(ioleflist) == 0:
+ if self.ef_format:
+ ioleflist = glob.glob(pdkpath + '/libs.ref/lef/IO*/*.lef')
+ else:
+ ioleflist = glob.glob(pdkpath + '/libs.ref/IO*/lef/*.lef')
+
+ if len(ioleflist) == 0:
+ self.print('Cannot find any I/O cell libraries for this technology')
+ return
+
+ # Read the LEF libraries to get a list of all available cells. Keep
+ # this list of cells in "celldefs".
+
+ celldefs = []
+ ioliblist = []
+ ioleflibs = []
+ for iolib in ioleflist:
+ iolibpath = os.path.split(iolib)[0]
+ iolibfile = os.path.split(iolib)[1]
+ ioliblist.append(os.path.split(iolibpath)[1])
+ celldefs.extend(self.read_lef_macros(iolibpath, iolibfile, 'iolib'))
+
+ verilogcells = []
+ newpadlist = []
+ coredefs = []
+ corecells = []
+ corecelllist = []
+ lefprocessed = []
+
+ busrex = re.compile('.*\[[ \t]*([0-9]+)[ \t]*:[ \t]*([0-9]+)[ \t]*\]')
+
+ vlogpath = self.projectpath + '/verilog'
+ vlogfile = vlogpath + '/' + self.project + '.v'
+
+ # Verilog netlists are too difficult to parse from a simple script.
+ # Use qflow tools to convert to SPICE, if they are available. Parse
+ # the verilog only for "include" statements to find the origin of
+ # the various IP blocks, and then parse the SPICE file to get the
+ # full list of instances.
+ #
+ # (to be done)
+
+ if os.path.isfile(vlogfile):
+ with open(vlogfile, 'r') as ifile:
+ vloglines = ifile.read().splitlines()
+ for vlogline in vloglines:
+ vlogparse = re.split('[\t ()]', vlogline)
+ while '' in vlogparse:
+ vlogparse.remove('')
+ if vlogparse == []:
+ continue
+ elif vlogparse[0] == '//':
+ continue
+ elif vlogparse[0] == '`include':
+ incpath = vlogparse[1].strip('"')
+ libpath = os.path.split(incpath)[0]
+ libname = os.path.split(libpath)[1]
+ libfile = os.path.split(incpath)[1]
+
+ # Read the verilog library for module names to match
+ # against macro names in celldefs.
+ modulelist = self.read_verilog_lib(incpath, vlogpath)
+ matching = list(item for item in celldefs if item['name'] in modulelist)
+ for imatch in matching:
+ verilogcells.append(imatch['name'])
+ leffile = imatch['iolib']
+ if leffile not in ioleflibs:
+ ioleflibs.append(leffile)
+
+ # Read a corresponding LEF file entry for non-I/O macros, if one
+ # can be found (this handles files in the PDK).
+ if len(matching) == 0:
+ if libname != '':
+ # (NOTE: Assumes full path starting with '/')
+ lefpath = libpath.replace('verilog', 'lef')
+ lefname = libfile.replace('.v', '.lef')
+ if not os.path.exists(lefpath + '/' + lefname):
+ leffiles = glob.glob(lefpath + '/*.lef')
+ else:
+ leffiles = [lefpath + '/' + lefname]
+
+ for leffile in leffiles:
+ if leffile in ioleflibs:
+ continue
+ elif leffile in lefprocessed:
+ continue
+ else:
+ lefprocessed.append(leffile)
+
+ lefname = os.path.split(leffile)[1]
+
+ newcoredefs = self.read_lef_macros(lefpath, lefname, 'celllib')
+ coredefs.extend(newcoredefs)
+ corecells.extend(list(item['name'] for item in newcoredefs))
+
+ if leffiles == []:
+ maglefname = libfile.replace('.v', '.mag')
+
+ # Handle PDK files with a maglef/ view but no LEF file.
+ maglefpath = libpath.replace('verilog', 'maglef')
+ if not os.path.exists(maglefpath + '/' + maglefname):
+ magleffiles = glob.glob(maglefpath + '/*.mag')
+ else:
+ magleffiles = [maglefpath + '/' + maglefname]
+
+ if magleffiles == []:
+ # Handle user ip/ files with a maglef/ view but
+ # no LEF file.
+ maglefpath = libpath.replace('verilog', 'maglef')
+ designpath = os.path.split(self.projectpath)[0]
+ maglefpath = designpath + '/ip/' + maglefpath
+
+ if not os.path.exists(maglefpath + '/' + maglefname):
+ magleffiles = glob.glob(maglefpath + '/*.mag')
+ else:
+ magleffiles = [maglefpath + '/' + maglefname]
+
+ for magleffile in magleffiles:
+ # Generate LEF file. Since PDK and ip/ entries
+ # are not writeable, write into the project mag/
+ # directory.
+ magpath = self.projectpath + '/mag'
+ magname = os.path.split(magleffile)[1]
+ magroot = os.path.splitext(magname)[0]
+ leffile = magpath + '/' + magroot + '.lef'
+ if not os.path.isfile(leffile):
+ self.write_lef_file(magleffile, magpath)
+
+ if leffile in ioleflibs:
+ continue
+ elif leffile in lefprocessed:
+ continue
+ else:
+ lefprocessed.append(leffile)
+
+ lefname = os.path.split(leffile)[1]
+
+ newcoredefs = self.read_lef_macros(magpath, lefname, 'celllib')
+ coredefs.extend(newcoredefs)
+ corecells.extend(list(item['name'] for item in newcoredefs))
+ # LEF files generated on-the-fly are not needed
+ # after they have been parsed.
+ # os.remove(leffile)
+
+ # Check if all modules in modulelist are represented by
+ # corresponding LEF macros. If not, then go looking for a LEF
+ # file in the mag/ or maglef/ directory. Then, go looking for
+ # a .mag file in the mag/ or maglef/ directory, and build a
+ # LEF macro from it.
+
+ matching = list(item['name'] for item in coredefs if item['name'] in modulelist)
+ for module in modulelist:
+ if module not in matching:
+ lefpath = self.projectpath + '/lef'
+ magpath = self.projectpath + '/mag'
+ maglefpath = self.projectpath + '/mag'
+ lefname = libfile.replace('.v', '.lef')
+
+ # If the verilog file root name is not the same as
+ # the module name, then make a quick check for a
+ # LEF file with the same root name as the verilog.
+ # That indicates that the module does not exist in
+ # the LEF file, probably because it is a primary
+ # module that does not correspond to any layout.
+
+ leffile = lefpath + '/' + lefname
+ if os.path.exists(leffile):
+ self.print('Diagnostic: module ' + module + ' is not in ' + leffile + ' (probably a primary module)')
+ continue
+
+ leffile = magpath + '/' + lefname
+ istemp = False
+ if not os.path.exists(leffile):
+ magname = libfile.replace('.v', '.mag')
+ magfile = magpath + '/' + magname
+ if os.path.exists(magfile):
+ self.print('Diagnostic: Found a .mag file for ' + module + ' in ' + magfile)
+ self.write_lef_file(magfile)
+ istemp = True
+ else:
+ magleffile = maglefpath + '/' + lefname
+ if not os.path.exists(magleffile):
+ self.print('Diagnostic: (module ' + module + ') has no LEF file ' + leffile + ' or ' + magleffile)
+ magleffile = maglefpath + '/' + magname
+ if os.path.exists(magleffile):
+ self.print('Diagnostic: Found a .mag file for ' + module + ' in ' + magleffile)
+ if os.access(maglefpath, os.W_OK):
+ self.write_lef_file(magleffile)
+ leffile = magleffile
+ istemp = True
+ else:
+ self.write_lef_file(magleffile, magpath)
+ else:
+ self.print('Did not find a file ' + magfile)
+ # self.print('Warning: module ' + module + ' has no LEF or .mag views')
+ pass
+ else:
+ self.print('Diagnostic: Found a LEF file for ' + module + ' in ' + magleffile)
+ leffile = magleffile
+ else:
+ self.print('Diagnostic: Found a LEF file for ' + module + ' in ' + leffile)
+
+ if os.path.exists(leffile):
+ if leffile in lefprocessed:
+ continue
+ else:
+ lefprocessed.append(leffile)
+
+ newcoredefs = self.read_lef_macros(magpath, lefname, 'celllib')
+ # The LEF file generated on-the-fly is not needed
+ # any more after parsing the macro(s).
+ # if istemp:
+ # os.remove(leffile)
+ coredefs.extend(newcoredefs)
+ corecells.extend(list(item['name'] for item in newcoredefs))
+ else:
+ # self.print('Failed to find a LEF view for module ' + module)
+ pass
+
+ elif vlogparse[0] in verilogcells:
+ # Check for array of pads
+ bushigh = buslow = -1
+ if len(vlogparse) >= 3:
+ bmatch = busrex.match(vlogline)
+ if bmatch:
+ bushigh = int(bmatch.group(1))
+ buslow = int(bmatch.group(2))
+
+ for i in range(buslow, bushigh + 1):
+ newpad = {}
+ if i >= 0:
+ newpad['name'] = vlogparse[1] + '[' + str(i) + ']'
+ else:
+ newpad['name'] = vlogparse[1]
+ newpad['cell'] = vlogparse[0]
+ padcell = next(item for item in celldefs if item['name'] == vlogparse[0])
+ newpad['iolib'] = padcell['iolib']
+ newpad['class'] = padcell['class']
+ newpad['subclass'] = padcell['subclass']
+ newpad['width'] = padcell['width']
+ newpad['height'] = padcell['height']
+ newpadlist.append(newpad)
+
+ elif vlogparse[0] in corecells:
+ # Check for array of cells
+ bushigh = buslow = -1
+ if len(vlogparse) >= 3:
+ bmatch = busrex.match(vlogline)
+ if bmatch:
+ bushigh = int(bmatch.group(1))
+ buslow = int(bmatch.group(2))
+
+ for i in range(buslow, bushigh + 1):
+ newcorecell = {}
+ if i >= 0:
+ newcorecell['name'] = vlogparse[1] + '[' + str(i) + ']'
+ else:
+ newcorecell['name'] = vlogparse[1]
+ newcorecell['cell'] = vlogparse[0]
+ corecell = next(item for item in coredefs if item['name'] == vlogparse[0])
+ newcorecell['celllib'] = corecell['celllib']
+ newcorecell['class'] = corecell['class']
+ newcorecell['subclass'] = corecell['subclass']
+ newcorecell['width'] = corecell['width']
+ newcorecell['height'] = corecell['height']
+ corecelllist.append(newcorecell)
+
+ self.print('')
+ self.print('Source file information:')
+ self.print('Source filename: ' + vlogfile)
+ self.print('Number of I/O libraries is ' + str(len(ioleflibs)))
+ self.print('Number of library cells in I/O libraries used: ' + str(len(verilogcells)))
+ self.print('Number of core celldefs is ' + str(len(coredefs)))
+ self.print('')
+ self.print('Number of I/O cells in design: ' + str(len(newpadlist)))
+ self.print('Number of core cells in design: ' + str(len(corecelllist)))
+ self.print('')
+
+ # Save the results
+ self.celldefs = celldefs
+ self.coredefs = coredefs
+ self.vlogpads = newpadlist
+ self.corecells = corecelllist
+ self.ioleflibs = ioleflibs
+
+ # Check self.vlogpads, which was created during import (above) against
+ # self.(N,S,W,E)pads, which was read from the DEF file (if there was one)
+ # Also check self.corecells, which was created during import against
+ # self.coregroup, which was read from the DEF file.
+
+ def resolve(self):
+ self.print('Resolve differences in verilog and LEF views.')
+
+ samepads = []
+ addedpads = []
+ removedpads = []
+
+ # (1) Create list of entries that are in both self.vlogpads and self.()pads
+ # (2) Create list of entries that are in self.vlogpads but not in self.()pads
+
+ allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+ for pad in self.vlogpads:
+ newpadname = pad['name']
+ try:
+ lpad = next(item for item in allpads if item['name'] == newpadname)
+ except:
+ addedpads.append(pad)
+ else:
+ samepads.append(lpad)
+
+ # (3) Create list of entries that are in allpads but not in self.vlogpads
+ for pad in allpads:
+ newpadname = pad['name']
+ try:
+ lpad = next(item for item in self.vlogpads if item['name'] == newpadname)
+ except:
+ removedpads.append(pad)
+
+ # Print results
+ if len(addedpads) > 0:
+ self.print('Added pads:')
+ for pad in addedpads:
+ self.print(pad['name'] + ' (' + pad['cell'] + ')')
+
+ if len(removedpads) > 0:
+ plist = []
+ nspacers = 0
+ for pad in removedpads:
+ if 'subclass' in pad:
+ if pad['subclass'] != 'SPACER':
+ plist.append(pad)
+ else:
+ nspacers += 1
+
+ if nspacers > 0:
+ self.print(str(nspacers) + ' spacer cells ignored.')
+ if len(plist) > 0:
+ self.print('Removed pads:')
+ for pad in removedpads:
+ self.print(pad['name'] + ' (' + pad['cell'] + ')')
+
+ if len(addedpads) + len(removedpads) == 0:
+ self.print('Pad list has not changed.')
+
+ # Remove all cells from the "removed" list, with comment
+
+ allpads = [self.Npads, self.NEpad, self.Epads, self.SEpad, self.Spads, self.SWpad, self.Wpads, self.NWpad]
+
+ for pad in removedpads:
+ rname = pad['name']
+ for row in allpads:
+ try:
+ rpad = next(item for item in row if item['name'] == rname)
+ except:
+ rpad = None
+ else:
+ row.remove(rpad)
+
+ # Now the verilog file has no placement information, so the old padlist
+ # entries (if they exist) are preferred. Add to these the new padlist
+ # entries
+
+ # First pass for unassigned pads: Use of "CLASS ENDCAP" is preferred
+ # for identifying corner pads. Otherwise, if 'CORNER' or 'corner' is
+ # in the pad name, then make sure there is one per row in the first
+ # position. This is not foolproof and depends on the cell library
+ # using the text 'corner' in the name of the corner cell. However,
+ # if the ad hoc methods fail, the user can still manually move the
+ # corner cells to the right place (to be done: Identify if library
+ # uses ENDCAP designation for corner cells up front; don't go
+ # looking for 'corner' text if the cells are easily identifiable by
+ # LEF class).
+
+ for pad in addedpads[:]:
+ iscorner = False
+ if 'class' in pad and pad['class'] == 'ENDCAP':
+ iscorner = True
+ elif 'CORNER' in pad['cell'].upper():
+ iscorner = True
+
+ if iscorner:
+ if self.NWpad == []:
+ self.NWpad.append(pad)
+ pad['o'] = 'E'
+ addedpads.remove(pad)
+ elif self.NEpad == []:
+ self.NEpad.append(pad)
+ pad['o'] = 'S'
+ addedpads.remove(pad)
+ elif self.SEpad == []:
+ self.SEpad.append(pad)
+ pad['o'] = 'W'
+ addedpads.remove(pad)
+ elif self.SWpad == []:
+ self.SWpad.append(pad)
+ pad['o'] = 'N'
+ addedpads.remove(pad)
+
+ numN = len(self.Npads)
+ numS = len(self.Spads)
+ numE = len(self.Epads)
+ numW = len(self.Wpads)
+
+ minnum = min(numN, numS, numE, numW)
+ minnum = max(minnum, int(len(addedpads) / 4))
+
+ # Add pads in clockwise order. Note that S and E pads are defined counterclockwise
+ for pad in addedpads:
+ if numN < minnum:
+ self.Npads.append(pad)
+ numN += 1
+ pad['o'] = 'S'
+ self.print("Adding pad " + pad['name'] + " to Npads")
+ elif numE < minnum:
+ self.Epads.insert(0, pad)
+ numE += 1
+ pad['o'] = 'W'
+ self.print("Adding pad " + pad['name'] + " to Epads")
+ elif numS < minnum:
+ self.Spads.insert(0, pad)
+ numS += 1
+ pad['o'] = 'N'
+ self.print("Adding pad " + pad['name'] + " to Spads")
+ # elif numW < minnum:
+ else:
+ self.Wpads.append(pad)
+ numW += 1
+ pad['o'] = 'E'
+ self.print("Adding pad " + pad['name'] + " to Wpads")
+
+ minnum = min(numN, numS, numE, numW)
+ minnum = max(minnum, int(len(addedpads) / 4))
+
+ # Make sure all pads have included information from the cell definition
+
+ allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+ for pad in allpads:
+ if 'width' not in pad:
+ try:
+ celldef = next(item for item in celldefs if item['name'] == pad['cell'])
+ except:
+ self.print('Cell ' + pad['cell'] + ' not found!')
+ else:
+ pad['width'] = celldef['width']
+ pad['height'] = celldef['height']
+ pad['class'] = celldef['class']
+ pad['subclass'] = celldef['subclass']
+
+ # Now treat the core cells in the same way (resolve list parsed from verilog
+ # against the list parsed from DEF)
+
+ # self.print('Diagnostic: ')
+ # self.print('self.corecells = ' + str(self.corecells))
+ # self.print('self.coregroup = ' + str(self.coregroup))
+
+ samecore = []
+ addedcore = []
+ removedcore = []
+
+ # (1) Create list of entries that are in both self.corecells and self.coregroup
+ # (2) Create list of entries that are in self.corecells but not in self.coregroup
+
+ for cell in self.corecells:
+ newcellname = cell['name']
+ try:
+ lcore = next(item for item in self.coregroup if item['name'] == newcellname)
+ except:
+ addedcore.append(cell)
+ else:
+ samecore.append(lcore)
+
+ # (3) Create list of entries that are in self.coregroup but not in self.corecells
+ for cell in self.coregroup:
+ newcellname = cell['name']
+ try:
+ lcore = next(item for item in self.corecells if item['name'] == newcellname)
+ except:
+ removedcore.append(cell)
+
+ # Print results
+ if len(addedcore) > 0:
+ self.print('Added core cells:')
+ for cell in addedcore:
+ self.print(cell['name'] + ' (' + cell['cell'] + ')')
+
+ if len(removedcore) > 0:
+ clist = []
+ for cell in removedcore:
+ clist.append(cell)
+
+ if len(clist) > 0:
+ self.print('Removed core cells:')
+ for cell in removedcore:
+ self.print(cell['name'] + ' (' + cell['cell'] + ')')
+
+ if len(addedcore) + len(removedcore) == 0:
+ self.print('Core cell list has not changed.')
+
+ # Remove all cells from the "removed" list
+
+ coregroup = self.coregroup
+ for cell in removedcore:
+ rname = cell['name']
+ try:
+ rcell = next(item for item in coregroup if item['name'] == rname)
+ except:
+ rcell = None
+ else:
+ coregroup.remove(rcell)
+
+ # Add all cells from the "added" list to coregroup
+
+ for cell in addedcore:
+ rname = cell['name']
+ try:
+ rcell = next(item for item in coregroup if item['name'] == rname)
+ except:
+ coregroup.append(cell)
+ if not 'o' in cell:
+ cell['o'] = 'N'
+ if not 'x' in cell:
+ if len(self.Wpads) > 0:
+ pad = self.Wpads[0]
+ padx = pad['x'] if 'x' in pad else 0
+ cell['x'] = padx + pad['height'] + self.margin
+ else:
+ cell['x'] = self.margin
+ if not 'y' in cell:
+ if len(self.Spads) > 0:
+ pad = self.Spads[0]
+ pady = pad['y'] if 'y' in pad else 0
+ cell['y'] = pady + pad['height'] + self.margin
+ else:
+ cell['y'] = self.margin
+ else:
+ rcell = None
+
+ # Make sure all core cells have included information from the cell definition
+
+ for cell in coregroup:
+ if 'width' not in cell:
+ try:
+ coredef = next(item for item in coredefs if item['name'] == cell['cell'])
+ except:
+ self.print('Cell ' + cell['cell'] + ' not found!')
+ else:
+ cell['width'] = coredef['width']
+ cell['height'] = coredef['height']
+ cell['class'] = coredef['class']
+ cell['subclass'] = coredef['subclass']
+
+ # Generate a new padframe by writing the configuration file, running
+ # padring, reading back the DEF file, and (re)poplulating the workspace
+
+ def generate(self, level):
+ self.print('Generate legal padframe using padring')
+
+ # Write out the configuration file
+ self.writeconfig()
+ # Run the padring app
+ self.runpadring()
+ # Rotate pads in the output if pad orientations are different from
+ # padring's expectations
+ self.rotate_pads_in_def()
+ # Read the placement information back from the generated DEF file
+ self.readplacement()
+ # Resolve differences (e.g., remove spacers)
+ self.resolve()
+ # Recreate and draw the padframe view on the canvas
+ self.populate(level + 1)
+ self.frame_configure(None)
+
+ # Write a new configuration file
+
+ def writeconfig(self):
+ mag_path = self.projectpath + '/mag'
+ if not os.path.exists(mag_path):
+ self.print('Error: No project path /mag directory exists. Cannot write config file.')
+ return
+
+ self.print('Writing padring configuration file.')
+
+ # Determine cell width and height from pad sizes.
+ # NOTE: This compresses the chip to the minimum dimensions
+ # allowed by the arrangement of pads. Use a "core" block to
+ # force the area larger than minimum (not yet implemented)
+
+ topwidth = 0
+ for pad in self.Npads:
+ if 'width' not in pad:
+ self.print('No width: pad = ' + str(pad))
+ topwidth += pad['width']
+
+ # Add in the corner cells
+ if self.NWpad != []:
+ topwidth += self.NWpad[0]['height']
+ if self.NEpad != []:
+ topwidth += self.NEpad[0]['width']
+
+ botwidth = 0
+ for pad in self.Spads:
+ botwidth += pad['width']
+
+ # Add in the corner cells
+ if self.SWpad != []:
+ botwidth += self.SWpad[0]['width']
+ if self.SEpad != []:
+ botwidth += self.SEpad[0]['height']
+
+ width = max(botwidth, topwidth)
+
+ # if width < self.urx - self.llx:
+ # width = self.urx - self.llx
+
+ leftheight = 0
+ for pad in self.Wpads:
+ leftheight += pad['width']
+
+ # Add in the corner cells
+ if self.NWpad != []:
+ leftheight += self.NWpad[0]['height']
+ if self.SWpad != []:
+ leftheight += self.SWpad[0]['width']
+
+ rightheight = 0
+ for pad in self.Epads:
+ rightheight += pad['width']
+
+ # Add in the corner cells
+ if self.NEpad != []:
+ rightheight += self.NEpad[0]['width']
+ if self.SEpad != []:
+ rightheight += self.SEpad[0]['height']
+
+ height = max(leftheight, rightheight)
+
+ # Check the dimensions of the core cells. If they exceed the available
+ # padframe area, then expand the padframe to accomodate the core.
+
+ corellx = coreurx = (self.llx + self.urx) / 2
+ corelly = coreury = (self.lly + self.ury) / 2
+
+ for corecell in self.coregroup:
+ corient = corecell['o']
+ if 'S' in corient or 'N' in corient:
+ cwidth = corecell['width']
+ cheight = corecell['height']
+ else:
+ cwidth = corecell['height']
+ cheight = corecell['width']
+
+ if corecell['x'] < corellx:
+ corellx = corecell['x']
+ if corecell['x'] + cwidth > coreurx:
+ coreurx = corecell['x'] + cwidth
+ if corecell['y'] < corelly:
+ corelly = corecell['y']
+ if corecell['y'] + cheight > coreury:
+ coreury = corecell['y'] + cheight
+
+ coreheight = coreury - corelly
+ corewidth = coreurx - corellx
+
+ # Ignoring the possibility of overlaps with nonstandard-sized pads,
+ # assuming that the user has visually separated them. Only check
+ # the core bounds against the standard padframe inside edge.
+
+ if self.SWpad != [] and self.SEpad != []:
+ if corewidth > width - self.SWpad[0]['width'] - self.SEpad[0]['width']:
+ width = corewidth + self.SWpad[0]['width'] + self.SEpad[0]['width']
+ if self.NWpad != [] and self.SWpad != []:
+ if coreheight > height - self.NWpad[0]['height'] - self.SWpad[0]['height']:
+ height = coreheight + self.NWpad[0]['height'] + self.SWpad[0]['height']
+
+ # Core cells are given a margin of self.margin from the pad inside edge, so the
+ # core area passed to the padring app is 2 * self.margin larger than the
+ # measured size of the core area.
+ width += 2 * self.margin
+ height += 2 * self.margin
+
+ if self.keep_cfg == False or not os.path.exists(mag_path + '/padframe.cfg'):
+
+ if os.path.exists(mag_path + '/padframe.cfg'):
+ # Copy the previous padframe.cfg file to a backup. In case something
+ # goes badly wrong, this should be the only file overwritten, and can
+ # be recovered from the backup.
+ shutil.copy(mag_path + '/padframe.cfg', mag_path + '/padframe.cfg.bak')
+
+ with open(mag_path + '/padframe.cfg', 'w') as ofile:
+ print('AREA ' + str(int(width)) + ' ' + str(int(height)) + ' ;',
+ file=ofile)
+ print('', file=ofile)
+ for pad in self.NEpad:
+ print('CORNER ' + pad['name'] + ' SW ' + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.SEpad:
+ print('CORNER ' + pad['name'] + ' NW ' + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.SWpad:
+ print('CORNER ' + pad['name'] + ' NE ' + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.NWpad:
+ print('CORNER ' + pad['name'] + ' SE ' + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.Npads:
+ flip = 'F ' if 'F' in pad['o'] else ''
+ print('PAD ' + pad['name'] + ' N ' + flip + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.Epads:
+ flip = 'F ' if 'F' in pad['o'] else ''
+ print('PAD ' + pad['name'] + ' E ' + flip + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.Spads:
+ flip = 'F ' if 'F' in pad['o'] else ''
+ print('PAD ' + pad['name'] + ' S ' + flip + pad['cell'] + ' ;',
+ file=ofile)
+ for pad in self.Wpads:
+ flip = 'F ' if 'F' in pad['o'] else ''
+ print('PAD ' + pad['name'] + ' W ' + flip + pad['cell'] + ' ;',
+ file=ofile)
+
+ # Run the padring app.
+
+ def runpadring(self):
+ mag_path = self.projectpath + '/mag'
+ if not os.path.exists(mag_path):
+ self.print('No path /mag exists in project space; cannot run padring.')
+ return
+
+ self.print('Running padring')
+
+ if self.padring_path:
+ padringopts = [self.padring_path]
+ else:
+ padringopts = ['padring']
+
+ # Diagnostic
+ # self.print('Used libraries (self.ioleflibs) = ' + str(self.ioleflibs))
+
+ for iolib in self.ioleflibs:
+ padringopts.append('-L')
+ padringopts.append(iolib)
+ padringopts.append('--def')
+ padringopts.append('padframe.def')
+ padringopts.append('padframe.cfg')
+
+ self.print('Running ' + str(padringopts))
+
+ p = subprocess.Popen(padringopts, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = mag_path)
+ self.watch(p)
+
+ # Read placement information from the DEF file generated by padring.
+
+ def readplacement(self, precheck=False):
+ self.print('Reading placement information from DEF file')
+
+ mag_path = self.projectpath + '/mag'
+ if not os.path.isfile(mag_path + '/padframe.def'):
+ if not precheck:
+ self.print('No file padframe.def: pad frame was not generated.')
+ return False
+
+ # Very simple DEF file parsing. The placement DEF only contains a
+ # COMPONENTS section. Certain assumptions are made about the syntax
+ # that depends on the way 'padring' writes its output. This is not
+ # a rigorous DEF parser!
+
+ units = 1000
+ in_components = False
+ Npadlist = []
+ Spadlist = []
+ Epadlist = []
+ Wpadlist = []
+ NEpad = []
+ NWpad = []
+ SEpad = []
+ SWpad = []
+ coregroup = []
+
+ # Reset bounds
+ self.llx = self.lly = self.urx = self.ury = 0
+ corners = 0
+
+ with open(mag_path + '/padframe.def', 'r') as ifile:
+ deflines = ifile.read().splitlines()
+ for line in deflines:
+ if 'UNITS DISTANCE MICRONS' in line:
+ units = line.split()[3]
+ elif in_components:
+ lparse = line.split()
+ if lparse[0] == '-':
+ instname = lparse[1]
+ cellname = lparse[2]
+
+ elif lparse[0] == '+':
+ if lparse[1] == 'PLACED':
+ placex = lparse[3]
+ placey = lparse[4]
+ placeo = lparse[6]
+
+ newpad = {}
+ newpad['name'] = instname
+ newpad['cell'] = cellname
+
+ try:
+ celldef = next(item for item in self.celldefs if item['name'] == cellname)
+ except:
+ celldef = None
+ else:
+ newpad['iolib'] = celldef['iolib']
+ newpad['width'] = celldef['width']
+ newpad['height'] = celldef['height']
+ newpad['class'] = celldef['class']
+ newpad['subclass'] = celldef['subclass']
+
+ newpad['x'] = float(placex) / float(units)
+ newpad['y'] = float(placey) / float(units)
+ newpad['o'] = placeo
+
+ # Adjust bounds
+ if celldef:
+ if newpad['x'] < self.llx:
+ self.llx = newpad['x']
+ if newpad['y'] < self.lly:
+ self.lly = newpad['y']
+
+ if newpad['o'] == 'N' or newpad['o'] == 'S':
+ padurx = newpad['x'] + celldef['width']
+ padury = newpad['y'] + celldef['height']
+ else:
+ padurx = newpad['x'] + celldef['height']
+ padury = newpad['y'] + celldef['width']
+
+ if padurx > self.urx:
+ self.urx = padurx
+ if padury > self.ury:
+ self.ury = padury
+
+ # First four entries in the DEF file are corners
+ # padring puts the lower left corner at zero, so
+ # use the zero coordinates to determine which pads
+ # are which. Note that padring assumes the corner
+ # pad is drawn in the SW corner position!
+
+ if corners < 4:
+ if newpad['x'] == 0 and newpad['y'] == 0:
+ SWpad.append(newpad)
+ elif newpad['x'] == 0:
+ NWpad.append(newpad)
+ elif newpad['y'] == 0:
+ SEpad.append(newpad)
+ else:
+ NEpad.append(newpad)
+ corners += 1
+ else:
+ # Place according to orientation. If orientation
+ # is not standard, be sure to make it standard!
+ placeo = self.rotate_orientation(placeo)
+ if placeo == 'N':
+ Spadlist.append(newpad)
+ elif placeo == 'E':
+ Wpadlist.append(newpad)
+ elif placeo == 'S':
+ Npadlist.append(newpad)
+ else:
+ Epadlist.append(newpad)
+
+ elif 'END COMPONENTS' in line:
+ in_components = False
+ elif 'COMPONENTS' in line:
+ in_components = True
+
+ self.Npads = Npadlist
+ self.Wpads = Wpadlist
+ self.Spads = Spadlist
+ self.Epads = Epadlist
+
+ self.NWpad = NWpad
+ self.NEpad = NEpad
+ self.SWpad = SWpad
+ self.SEpad = SEpad
+
+ # The padframe has its own DEF file from the padring app, but the core
+ # does not. The core needs to be floorplanned in a very similar manner.
+ # This will be done by searching for a DEF file of the project top-level
+ # layout. If none exists, it is created by generating it from the layout.
+ # If the top-level layout does not exist, then all core cells are placed
+ # at the origin, and the origin placed at the padframe inside corner.
+
+ mag_path = self.projectpath + '/mag'
+ if not os.path.isfile(mag_path + '/' + self.project + '.def'):
+ if os.path.isfile(mag_path + '/' + self.project + '.mag'):
+
+ # Create a DEF file from the layout
+ with open(mag_path + '/pfg_write_def.tcl', 'w') as ofile:
+ print('drc off', file=ofile)
+ print('box 0 0 0 0', file=ofile)
+ print('load ' + self.project, file=ofile)
+ print('def write', file=ofile)
+ print('quit', file=ofile)
+
+ magicexec = self.magic_path if self.magic_path else 'magic'
+ mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+ 'pfg_write_def.tcl'],
+ stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = mag_path, universal_newlines = True)
+
+ self.watch(mproc)
+ os.remove(mag_path + '/pfg_write_def.tcl')
+
+ elif not os.path.isfile(mag_path + '/core.def'):
+
+ # With no other information available, copy the corecells
+ # (from the verilog file) into the coregroup list.
+ # Position all core cells starting at the padframe top left
+ # inside corner, and arranging in rows without overlapping.
+ # Note that no attempt is made to organize the cells or
+ # otherwise produce an efficient layout. Any dimension larger
+ # than the current padframe overruns to the right or bottom.
+
+ if self.SWpad != []:
+ corellx = SWpad[0]['x'] + SWpad[0]['width'] + self.margin
+ corelly = SWpad[0]['y'] + SWpad[0]['height'] + self.margin
+ else:
+ corellx = Wpadlist[0]['x'] + Wpadlist[0]['height'] + self.margin
+ corelly = Spadlist[0]['x'] + Spadlist[0]['height'] + self.margin
+ if self.NEpad != []:
+ coreurx = NEpad[0]['x'] - self.margin
+ coreury = NEpad[0]['y'] - self.margin
+ else:
+ coreurx = Epadlist[0]['x'] - self.margin
+ coreury = Npadlist[0]['x'] - self.margin
+ locllx = corellx
+ testllx = corellx
+ loclly = corelly
+ testlly = corelly
+ nextlly = corelly
+
+ for cell in self.corecells:
+
+ testllx = locllx + cell['width']
+ if testllx > coreurx:
+ locllx = corellx
+ corelly = nextlly
+ loclly = nextlly
+
+ newcore = cell
+ newcore['x'] = locllx
+ newcore['y'] = loclly
+ newcore['o'] = 'N'
+
+ locllx += cell['width'] + self.margin
+
+ testlly = corelly + cell['height'] + self.margin
+ if testlly > nextlly:
+ nextlly = testlly
+
+ coregroup.append(newcore)
+
+ self.coregroup = coregroup
+
+ if os.path.isfile(mag_path + '/' + self.project + '.def'):
+ # Read the top-level DEF, and use it to position the core cells.
+ self.print('Reading the top-level cell DEF for core cell placement.')
+
+ units = 1000
+ in_components = False
+ with open(mag_path + '/' + self.project + '.def', 'r') as ifile:
+ deflines = ifile.read().splitlines()
+ for line in deflines:
+ if 'UNITS DISTANCE MICRONS' in line:
+ units = line.split()[3]
+ elif in_components:
+ lparse = line.split()
+ if lparse[0] == '-':
+ instname = lparse[1]
+ # NOTE: Magic should not drop the entire path to the
+ # cell for the cellname; this needs to be fixed! To
+ # work around it, remove any path components.
+ cellpath = lparse[2]
+ cellname = os.path.split(cellpath)[1]
+
+ elif lparse[0] == '+':
+ if lparse[1] == 'PLACED':
+ placex = lparse[3]
+ placey = lparse[4]
+ placeo = lparse[6]
+
+ newcore = {}
+ newcore['name'] = instname
+ newcore['cell'] = cellname
+
+ try:
+ celldef = next(item for item in self.coredefs if item['name'] == cellname)
+ except:
+ celldef = None
+ else:
+ newcore['celllib'] = celldef['celllib']
+ newcore['width'] = celldef['width']
+ newcore['height'] = celldef['height']
+ newcore['class'] = celldef['class']
+ newcore['subclass'] = celldef['subclass']
+
+ newcore['x'] = float(placex) / float(units)
+ newcore['y'] = float(placey) / float(units)
+ newcore['o'] = placeo
+ coregroup.append(newcore)
+
+ elif 'END COMPONENTS' in line:
+ in_components = False
+ elif 'COMPONENTS' in line:
+ in_components = True
+
+ self.coregroup = coregroup
+
+ elif os.path.isfile(mag_path + '/core.def'):
+ # No DEF or .mag file, so fallback position is the last core.def
+ # file generated by this script.
+ self.read_core_def(precheck=precheck)
+
+ return True
+
+ # Read placement information from the "padframe.def" file and rotate
+ # all cells according to self.pad_rotation. This accounts for the
+ # problem that the default orientation of pads is arbitrarily defined
+ # by the foundry, while padring assumes that the corner pad is drawn
+ # in the lower-left position and other pads are drawn with the pad at
+ # the bottom and the buses at the top.
+
+ def rotate_pads_in_def(self):
+ if self.pad_rotation == 0:
+ return
+
+ self.print('Rotating pads in padframe DEF file.')
+ mag_path = self.projectpath + '/mag'
+
+ if not os.path.isfile(mag_path + '/padframe.def'):
+ self.print('No file padframe.def: Cannot modify pad rotations.')
+ return
+
+ deflines = []
+ with open(mag_path + '/padframe.def', 'r') as ifile:
+ deflines = ifile.read().splitlines()
+
+ outlines = []
+ in_components = False
+ for line in deflines:
+ if in_components:
+ lparse = line.split()
+ if lparse[0] == '+':
+ if lparse[1] == 'PLACED':
+ neworient = self.rotate_orientation(lparse[6])
+ lparse[6] = neworient
+ line = ' '.join(lparse)
+
+ elif 'END COMPONENTS' in line:
+ in_components = False
+ elif 'COMPONENTS' in line:
+ in_components = True
+ outlines.append(line)
+
+ with open(mag_path + '/padframe.def', 'w') as ofile:
+ for line in outlines:
+ print(line, file=ofile)
+
+ # Read placement information from the DEF file for the core (created by
+ # a previous run of this script)
+
+ def read_core_def(self, precheck=False):
+ self.print('Reading placement information from core DEF file.')
+
+ mag_path = self.projectpath + '/mag'
+
+ if not os.path.isfile(mag_path + '/core.def'):
+ if not precheck:
+ self.print('No file core.def: core placement was not generated.')
+ return False
+
+ # Very simple DEF file parsing, similar to the padframe.def reading
+ # routine above.
+
+ units = 1000
+ in_components = False
+
+ coregroup = []
+
+ with open(mag_path + '/core.def', 'r') as ifile:
+ deflines = ifile.read().splitlines()
+ for line in deflines:
+ if 'UNITS DISTANCE MICRONS' in line:
+ units = line.split()[3]
+ elif in_components:
+ lparse = line.split()
+ if lparse[0] == '-':
+ instname = lparse[1]
+ cellname = lparse[2]
+
+ elif lparse[0] == '+':
+ if lparse[1] == 'PLACED':
+ placex = lparse[3]
+ placey = lparse[4]
+ placeo = lparse[6]
+
+ newcore = {}
+ newcore['name'] = instname
+ newcore['cell'] = cellname
+
+ try:
+ celldef = next(item for item in self.coredefs if item['name'] == cellname)
+ except:
+ celldef = None
+ else:
+ newcore['celllib'] = celldef['celllib']
+ newcore['width'] = celldef['width']
+ newcore['height'] = celldef['height']
+ newcore['class'] = celldef['class']
+ newcore['subclass'] = celldef['subclass']
+
+ newcore['x'] = float(placex) / float(units)
+ newcore['y'] = float(placey) / float(units)
+ newcore['o'] = placeo
+ coregroup.append(newcore)
+
+ elif 'END COMPONENTS' in line:
+ in_components = False
+ elif 'COMPONENTS' in line:
+ in_components = True
+
+ self.coregroup = coregroup
+
+ return True
+
+ # Save the layout to a Magic database file (to be completed)
+
+ def save(self):
+ self.print('Saving results in a magic layout database.')
+
+ # Generate a list of (unique) LEF libraries for all padframe and core cells
+ leflist = []
+ for pad in self.celldefs:
+ if pad['iolib'] not in leflist:
+ leflist.append(pad['iolib'])
+
+ for core in self.coredefs:
+ if core['celllib'] not in leflist:
+ leflist.append(core['celllib'])
+
+ # Run magic, and generate the padframe with a series of commands
+ mag_path = self.projectpath + '/mag'
+
+ with open(mag_path + '/pfg_write_mag.tcl', 'w') as ofile:
+ print('drc off', file=ofile)
+ print('box 0 0 0 0', file=ofile)
+ for leffile in leflist:
+ print('lef read ' + leffile, file=ofile)
+ print('def read padframe', file=ofile)
+ print('select top cell', file=ofile)
+ print('select area', file=ofile)
+ print('select save padframe', file=ofile)
+ print('delete', file=ofile)
+ print('def read core', file=ofile)
+ print('getcell padframe', file=ofile)
+ print('save ' + self.project, file=ofile)
+ print('writeall force ' + self.project, file=ofile)
+ print('quit', file=ofile)
+
+ magicexec = self.magic_path if self.magic_path else 'magic'
+ mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+ 'pfg_write_mag.tcl'],
+ stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = mag_path, universal_newlines = True)
+ self.watch(mproc)
+ os.remove(mag_path + '/pfg_write_mag.tcl')
+ self.print('Done writing layout ' + self.project + '.mag')
+
+ # Write the core DEF file if it does not exist yet.
+ if not os.path.isfile(mag_path + '/core.def'):
+ self.write_core_def()
+
+if __name__ == '__main__':
+ faulthandler.register(signal.SIGUSR2)
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ if '-help' in options:
+ print(sys.argv[0] + ' [options]')
+ print('')
+ print('options:')
+ print(' -noc Print output to terminal, not the gui window')
+ print(' -nog No graphics, run in batch mode')
+ print(' -cfg Use existing padframe.cfg, do not regenerate')
+ print(' -padring-path=<path> path to padring executable')
+ print(' -magic-path=<path> path to magic executable')
+ print(' -tech-path=<path> path to tech root folder')
+ print(' -project-path=<path> path to project root folder')
+ print(' -help Print this usage information')
+ print('')
+ sys.exit(0)
+
+ root = tkinter.Tk()
+ do_gui = False if ('-nog' in options or '-nogui' in options) else True
+ app = SoCFloorplanner(root, do_gui)
+
+ # Allow option -noc to bypass the text-to-console redirection, so crash
+ # information doesn't disappear with the app.
+
+ app.use_console = False if ('-noc' in options or '-noconsole' in options) else True
+ if do_gui == False:
+ app.use_console = False
+
+ # efabless format can be specified on the command line, but note that it
+ # is otherwise auto-detected by checking for .config vs. .ef-config in
+ # the project space.
+
+ app.ef_format = True if '-ef_format' in options else False
+ app.keep_cfg = True if '-cfg' in options else False
+
+ app.padring_path = None
+ app.magic_path = None
+ app.techpath = None
+ app.projectpath = None
+
+ for option in options:
+ if option.split('=')[0] == '-padring-path':
+ app.padring_path = option.split('=')[1]
+ elif option.split('=')[0] == '-magic-path':
+ app.magic_path = option.split('=')[1]
+ elif option.split('=')[0] == '-tech-path':
+ app.techpath = option.split('=')[1]
+ elif option.split('=')[0] == '-project-path':
+ app.projectpath = option.split('=')[1]
+ app.projectpath = app.projectpath[:-1] if app.projectpath[-1] == '/' else app.projectpath
+
+ app.text_to_console()
+ app.init_padframe()
+ if app.do_gui:
+ root.mainloop()
+ else:
+ # Run 'save' in non-GUI mode
+ app.save()
+ sys.exit(0)
+
diff --git a/common/split_gds.py b/common/split_gds.py
new file mode 100755
index 0000000..a673c2f
--- /dev/null
+++ b/common/split_gds.py
@@ -0,0 +1,76 @@
+#!/bin/env python3
+# Script to read a GDS library and write into individual GDS files, one per cell
+
+import os
+import sys
+import subprocess
+
+def usage():
+ print('split_gds.py <path_to_gds_library> <magic_techfile> [<file_with_list_of_cells>]')
+
+if __name__ == '__main__':
+
+ if len(sys.argv) == 1:
+ print("No options given to split_gds.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ arguments = []
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ optionlist.append(option)
+ else:
+ arguments.append(option)
+
+ if len(arguments) != 3:
+ print("Wrong number of arguments given to split_gds.py.")
+ usage()
+ sys.exit(0)
+
+ source = arguments[0]
+
+ techfile = arguments[1]
+
+ celllist = arguments[2]
+ if os.path.isfile(celllist):
+ with open(celllist, 'r') as ifile:
+ celllist = ifile.read().splitlines()
+
+ destdir = os.path.split(source)[0]
+ gdsfile = os.path.split(source)[1]
+
+ with open(destdir + '/split_gds.tcl', 'w') as ofile:
+ print('#!/bin/env wish', file=ofile)
+ print('drc off', file=ofile)
+ print('gds readonly true', file=ofile)
+ print('gds rescale false', file=ofile)
+ print('tech unlock *', file=ofile)
+ print('gds read ' + gdsfile, file=ofile)
+
+ for cell in celllist:
+ print('load ' + cell, file=ofile)
+ print('gds write ' + cell, file=ofile)
+
+ print('quit -noprompt', file=ofile)
+
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+ '-T', techfile,
+ destdir + '/split_gds.tcl'],
+ stdin = subprocess.DEVNULL,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, cwd = destdir,
+ universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+ os.remove(destdir + '/split_gds.tcl')
+ exit(0)
diff --git a/common/staging_install.py b/common/staging_install.py
new file mode 100755
index 0000000..3e13cb0
--- /dev/null
+++ b/common/staging_install.py
@@ -0,0 +1,617 @@
+#!/usr/bin/env python3
+#
+# staging_install.py
+#
+# This file copies the staging area created by foundry_install.py
+# into the target directory area, changing paths to match the target,
+# and creating symbolic links where requested and allowed.
+#
+# 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)
+# -ef_format Use efabless naming (libs.ref/techLEF),
+# otherwise use generic naming (libs.tech/lef)
+#
+# -staging <path> Path to staging 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.
+# -source <path> Path to original source top level directory,
+# if link_from is "source". This option may
+# be called multiple times if there are multiple
+# sources.
+
+import re
+import os
+import sys
+import glob
+import stat
+import shutil
+import filecmp
+import subprocess
+
+# NOTE: This version of copy_tree from distutils works like shutil.copytree()
+# in Python 3.8 and up ONLY using "dirs_exist_ok=True".
+from distutils.dir_util import copy_tree
+
+def usage():
+ print("staging_install.py [options...]")
+ print(" -link_from <name> Make symbolic links from target to <name>")
+ print(" where <name> can be 'source' or a PDK name.")
+ print(" Default behavior is to copy all files.")
+ print(" -copy Copy files from source to target (default)")
+ print(" -ef_format Use efabless naming conventions for local directories")
+ print("")
+ print(" -staging <path> Path to top of staging directory tree")
+ print(" -target <path> Path to top of target directory tree")
+ print(" -local <path> Local path to top of target directory tree for distributed install")
+ print("")
+ print(" If <target> is unspecified then <name> is used for the target.")
+
+def makeuserwritable(filepath):
+ if os.path.exists(filepath):
+ st = os.stat(filepath)
+ os.chmod(filepath, st.st_mode | stat.S_IWUSR)
+
+# Filter files to replace all strings matching "stagingdir" with "localdir" for
+# every file in "tooldir". If "tooldir" contains subdirectories, then recursively
+# apply the replacement filter to all files in the subdirectories. Do not follow
+# symbolic links.
+
+def filter_recursive(tooldir, stagingdir, localdir):
+ gdstypes = ['.gds', '.gds2', '.gdsii']
+
+ if not os.path.exists(tooldir):
+ return 0
+ elif os.path.islink(tooldir):
+ return 0
+
+ toolfiles = os.listdir(tooldir)
+ total = 0
+
+ for file in toolfiles:
+ # Do not attempt to do text substitutions on a binary file!
+ if os.path.splitext(file)[1] in gdstypes:
+ continue
+
+ filepath = tooldir + '/' + file
+ if os.path.islink(filepath):
+ continue
+ elif os.path.isdir(filepath):
+ total += filter_recursive(filepath, stagingdir, localdir)
+ else:
+ with open(filepath, 'r') as ifile:
+ try:
+ flines = ifile.read().splitlines()
+ except UnicodeDecodeError:
+ print('Failure to read file ' + filepath + '; non-ASCII content.')
+ continue
+
+ # Make sure this file is writable (as the original may not be)
+ makeuserwritable(filepath)
+
+ modified = False
+ with open(filepath, 'w') as ofile:
+ for line in flines:
+ newline = line.replace(stagingdir, localdir)
+ print(newline, file=ofile)
+ if newline != line:
+ modified = True
+
+ if modified:
+ total += 1
+ return total
+
+# To avoid problems with various library functions that copy hierarchical
+# directory trees, remove all the files from the target that are going to
+# be replaced by the contents of staging. This avoids problems with
+# symbolic links and such.
+
+def remove_target(stagingdir, targetdir):
+
+ slist = os.listdir(stagingdir)
+ tlist = os.listdir(targetdir)
+
+ for sfile in slist:
+ if sfile in tlist:
+ tpath = targetdir + '/' + sfile
+ if os.path.islink(tpath):
+ os.unlink(tpath)
+ elif os.path.isdir(tpath):
+ remove_target(stagingdir + '/' + sfile, targetdir + '/' + sfile)
+ else:
+ os.remove(tpath)
+
+# Create a list of source files/directories from the contents of source.txt
+
+def make_source_list(sources):
+ sourcelist = []
+ for source in sources:
+ sourcelist.extend(glob.glob(source))
+ return sourcelist
+
+# Replace all files in list "libfiles" with symbolic links to files in
+# "sourcelist", where the files are found to be the same. If the entry
+# in "libfiles" is a directory and the same directory is found in "sourcelist",
+# then repeat recursively on the subdirectory.
+#
+# Because the installation may be distributed, there may be a difference
+# between where the files to be linked to currently are (checklist)
+# and where they will eventually be located (sourcelist).
+
+def replace_with_symlinks(libfiles, sourcelist):
+ # List of files that never get installed
+ exclude = ['generate_magic.tcl', '.magicrc', 'sources.txt']
+ total = 0
+ for libfile in libfiles:
+ if os.path.islink(libfile):
+ continue
+ else:
+ try:
+ sourcefile = next(item for item in sourcelist if os.path.split(item)[1] == os.path.split(libfile)[1])
+ except:
+ pass
+ else:
+ if os.path.isdir(libfile):
+ newlibfiles = glob.glob(libfile + '/*')
+ newsourcelist = glob.glob(sourcefile + '/*')
+ total += replace_with_symlinks(newlibfiles, newsourcelist)
+ elif filecmp.cmp(libfile, sourcefile):
+ if not os.path.split(libfile)[1] in exclude:
+ os.remove(libfile)
+ # Use absolute path for the source file
+ sourcepath = os.path.abspath(sourcefile)
+ os.symlink(sourcepath, libfile)
+ total += 1
+ return total
+
+# Similar to the routine above, replace files in "libdir" with symbolic
+# links to the files in "srclibdir", where the files are found to be the
+# same. The difference from the routine above is that "srclibdir" is
+# another installed PDK, and so the directory hierarchy is expected to
+# match that of "libdir" exactly, so the process of finding matches is
+# a bit more straightforward.
+#
+# Because the installation may be distributed, there may be a difference
+# between where the files to be linked to currently are (checklibdir)
+# and where they will eventually be located (srclibdir).
+
+def replace_all_with_symlinks(libdir, srclibdir, checklibdir):
+ total = 0
+ try:
+ libfiles = os.listdir(libdir)
+ except FileNotFoundError:
+ print('Cannot list directory ' + libdir)
+ print('Called: replace_all_with_symlinks(' + libdir + ', ' + srclibdir + ', ' + checklibdir + ')')
+ return total
+
+ try:
+ checkfiles = os.listdir(checklibdir)
+ except FileNotFoundError:
+ print('Cannot list check directory ' + checklibdir)
+ print('Called: replace_all_with_symlinks(' + libdir + ', ' + srclibdir + ', ' + checklibdir + ')')
+ return total
+
+ for libfile in libfiles:
+ if libfile in checkfiles:
+ libpath = libdir + '/' + libfile
+ checkpath = checklibdir + '/' + libfile
+ srcpath = srclibdir + '/' + libfile
+
+ if os.path.isdir(libpath):
+ if os.path.isdir(checkpath):
+ total += replace_all_with_symlinks(libpath, srcpath, checkpath)
+ else:
+ try:
+ if filecmp.cmp(libpath, checkpath):
+ os.remove(libpath)
+ os.symlink(srcpath, libpath)
+ total += 1
+ except FileNotFoundError:
+ print('Failed file compare with libpath=' + libpath + ', checkpath=' + checkpath)
+
+ return total
+
+#----------------------------------------------------------------
+# This is the main entry point for the staging install script.
+#----------------------------------------------------------------
+
+if __name__ == '__main__':
+
+ if len(sys.argv) == 1:
+ print("No options given to staging_install.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ newopt = []
+
+ stagingdir = None
+ targetdir = None
+ link_from = None
+ localdir = None
+
+ ef_format = False
+ do_install = True
+
+ # Break arguments into groups where the first word begins with "-".
+ # All following words not beginning with "-" are appended to the
+ # same list (optionlist). Then each optionlist is processed.
+ # Note that the first entry in optionlist has the '-' removed.
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ if newopt != []:
+ optionlist.append(newopt)
+ newopt = []
+ newopt.append(option[1:])
+ else:
+ newopt.append(option)
+
+ if newopt != []:
+ optionlist.append(newopt)
+
+ # Check for option "ef_format" or "std_format"
+ for option in optionlist[:]:
+ if option[0] == 'ef_naming' or option[0] == 'ef_names' or option[0] == 'ef_format':
+ optionlist.remove(option)
+ ef_format = True
+ elif option[0] == 'std_naming' or option[0] == 'std_names' or option[0] == 'std_format':
+ optionlist.remove(option)
+ ef_format = False
+ elif option[0] == 'uninstall':
+ optionlist.remove(option)
+ do_install = False
+
+ # Check for options "link_from", "staging", "target", and "local"
+
+ link_name = None
+ for option in optionlist[:]:
+ if option[0] == 'link_from':
+ optionlist.remove(option)
+ if option[1].lower() == 'none':
+ link_from = None
+ elif option[1].lower() == 'source':
+ link_from = 'source'
+ else:
+ link_from = option[1]
+ link_name = os.path.split(link_from)[1]
+ elif option[0] == 'staging' or option[0] == 'source':
+ optionlist.remove(option)
+ stagingdir = option[1]
+ elif option[0] == 'target':
+ optionlist.remove(option)
+ targetdir = option[1]
+ elif option[0] == 'local':
+ optionlist.remove(option)
+ localdir = option[1]
+
+ # Error if no staging or dest specified
+ if not stagingdir:
+ print("No staging directory specified. Exiting.")
+ sys.exit(1)
+
+ if not targetdir:
+ print("No target directory specified. Exiting.")
+ sys.exit(1)
+
+ # If localdir is not specified, then it is the same as the parent
+ # of the target (local installation assumed)
+ if not localdir:
+ localdir = targetdir
+
+ # Take the target PDK name from the target path last component
+ pdkname = os.path.split(targetdir)[1]
+
+ # If link source is a PDK name, if it has no path, then pull the
+ # path from the target name.
+
+ if link_from:
+ if link_from != 'source':
+ if link_from.find('/', 0) < 0:
+ link_name = link_from
+ link_from = os.path.split(localdir)[0] + '/' + link_name
+ else:
+ # If linking from source, convert the source path to an
+ # absolute pathname.
+ stagingdir = os.path.abspath(stagingdir)
+
+ # If link_from is the same as localdir, then set link_from to None
+ if link_from == localdir:
+ link_from = None
+
+ # checkdir is the DIST target directory for the PDK pointed
+ # to by link_name. Files must be found there before creating
+ # symbolic links to the (not yet existing) final install location.
+
+ if link_name:
+ checkdir = os.path.split(targetdir)[0] + '/' + link_name
+ else:
+ checkdir = ''
+
+ # Diagnostic
+ if do_install:
+ print("Installing in target directory " + targetdir)
+ else:
+ print("Uninstalling from target directory " + targetdir)
+ print("(Method not yet implemented)")
+
+ # Create the top-level directories
+
+ os.makedirs(targetdir, exist_ok=True)
+ os.makedirs(targetdir + '/libs.tech', exist_ok=True)
+ os.makedirs(targetdir + '/libs.ref', exist_ok=True)
+ if os.path.isdir(stagingdir + '/libs.priv'):
+ os.makedirs(targetdir + '/libs.priv', exist_ok=True)
+ has_priv = True
+ else:
+ has_priv = False
+
+ # Path to magic techfile depends on ef_format
+
+ if ef_format == True:
+ mag_current = '/libs.tech/magic/current/'
+ else:
+ mag_current = '/libs.tech/magic/'
+
+ # First install everything by direct copy. Keep the staging files
+ # as they will be used to reference the target area to know which
+ # files need to be checked and/or modified.
+
+ if not os.path.isdir(targetdir):
+ try:
+ os.makedirs(targetdir, exist_ok=True)
+ except:
+ print('Fatal error: Cannot make target directory ' + targetdir + '!')
+ exit(1)
+
+ # Remove any files from the target directory that are going to be replaced
+ print('Removing files from target')
+ remove_target(stagingdir, targetdir)
+
+ print('Copying staging files to target')
+ # print('Diagnostic: copy_tree ' + stagingdir + ' ' + targetdir)
+ copy_tree(stagingdir, targetdir, preserve_symlinks=True)
+ print('Done.')
+
+ # Magic and qflow setup files have references to the staging area that have
+ # been used by the vendor install; these need to be changed to the target
+ # directory.
+
+ print('Changing local path references from ' + stagingdir + ' to ' + localdir)
+ print('Part 1: Tools')
+
+ needcheck = ['ngspice']
+ techdirs = ['/libs.tech/']
+ if has_priv:
+ techdirs.append('/libs.priv/')
+
+ for techdir in techdirs:
+ tools = os.listdir(targetdir + techdir)
+ for tool in tools:
+ tooldir = targetdir + techdir + tool
+
+ # There are few enough tool setup files that they can just all be
+ # filtered directly. This code only looks in the directory 'tooldir'.
+ # If there are files is subdirectories of 'tooldir' that require
+ # substitution, then this code needs to be revisited.
+
+ # Note that due to the low overhead of tool setup files, there is
+ # no attempt to check for possible symlinks to link_from if link_from
+ # is a base PDK.
+
+ total = filter_recursive(tooldir, stagingdir, localdir)
+ if total > 0:
+ substr = 'substitutions' if total > 1 else 'substitution'
+ print(' ' + tool + ' (' + str(total) + ' ' + substr + ')')
+
+ # If "link_from" is another PDK, then check all files against the files in
+ # the other PDK, and replace the file with a symbolic link if the file contents
+ # match (Note: This is done only for ngspice model files; other tool files are
+ # generally small and deemed unnecessary to make symbolic links).
+
+ if link_from != 'source':
+ thispdk = os.path.split(targetdir)[1]
+
+ # Only create links for PDKs other than the one we are making links to.
+ if thispdk != link_from:
+ print('Replacing files with symbolic links to ' + link_from + ' where possible.')
+ for techdir in techdirs:
+ for tool in needcheck:
+ tooldir = targetdir + techdir + tool
+ srctooldir = link_from + techdir + tool
+ if checkdir != '':
+ checktooldir = checkdir + techdir + tool
+ else:
+ checktooldir = srctooldir
+ if os.path.exists(tooldir):
+ total = replace_all_with_symlinks(tooldir, srctooldir, checktooldir)
+ if total > 0:
+ symstr = 'symlinks' if total > 1 else 'symlink'
+ print(' ' + tool + ' (' + str(total) + ' ' + symstr + ')')
+
+ # In .mag files in mag/ and maglef/, also need to change the staging
+ # directory name to localdir
+
+ needcheck = ['mag', 'maglef']
+ refdirs = ['/libs.ref/']
+ if has_priv:
+ refdirs.append('/libs.priv/')
+
+ if ef_format:
+ print('Part 2: Formats')
+ for refdir in refdirs:
+ for filetype in needcheck:
+ print(' ' + filetype)
+ filedir = targetdir + refdir + filetype
+ if os.path.isdir(filedir):
+ libraries = os.listdir(filedir)
+ for library in libraries:
+ libdir = filedir + '/' + library
+ total = filter_recursive(libdir, stagingdir, localdir)
+ if total > 0:
+ substr = 'substitutions' if total > 1 else 'substitution'
+ print(' ' + library + ' (' + str(total) + ' ' + substr + ')')
+ else:
+ print('Part 2: Libraries')
+ for refdir in refdirs:
+ libraries = os.listdir(targetdir + refdir)
+ for library in libraries:
+ print(' ' + library)
+ for filetype in needcheck:
+ filedir = targetdir + refdir + library + '/' + filetype
+ total = filter_recursive(filedir, stagingdir, localdir)
+ if total > 0:
+ substr = 'substitutions' if total > 1 else 'substitution'
+ print(' ' + filetype + ' (' + str(total) + ' ' + substr + ')')
+
+ # If "link_from" is "source", then check all files against the source
+ # directory, and replace the file with a symbolic link if the file
+ # contents match. The "foundry_install.py" script should have added a
+ # file "sources.txt" with the name of the source directories for each
+ # install directory.
+
+ if link_from == 'source':
+ print('Replacing files with symbolic links to source where possible.')
+ for refdir in refdirs:
+ if ef_format:
+ filedirs = os.listdir(targetdir + refdir)
+ for filedir in filedirs:
+ print(' ' + filedir)
+ dirpath = targetdir + refdir + filedir
+ if os.path.isdir(dirpath):
+ libraries = os.listdir(dirpath)
+ for library in libraries:
+ libdir = targetdir + refdir + filedir + '/' + library
+ libfiles = os.listdir(libdir)
+ if 'sources.txt' in libfiles:
+ libfiles = glob.glob(libdir + '/*')
+ libfiles.remove(libdir + '/sources.txt')
+ with open(libdir + '/sources.txt') as ifile:
+ sources = ifile.read().splitlines()
+ sourcelist = make_source_list(sources)
+ total = replace_with_symlinks(libfiles, sourcelist)
+ if total > 0:
+ symstr = 'symlinks' if total > 1 else 'symlink'
+ print(' ' + library + ' (' + str(total) + ' ' + symstr + ')')
+ else:
+ libraries = os.listdir(targetdir + refdir)
+ for library in libraries:
+ print(' ' + library)
+ filedirs = os.listdir(targetdir + refdir + library)
+ for filedir in filedirs:
+ libdir = targetdir + refdir + library + '/' + filedir
+ if os.path.isdir(libdir):
+ libfiles = os.listdir(libdir)
+ if 'sources.txt' in libfiles:
+ # List again, but with full paths.
+ libfiles = glob.glob(libdir + '/*')
+ libfiles.remove(libdir + '/sources.txt')
+ with open(libdir + '/sources.txt') as ifile:
+ sources = ifile.read().splitlines()
+ sourcelist = make_source_list(sources)
+ total = replace_with_symlinks(libfiles, sourcelist)
+ if total > 0:
+ symstr = 'symlinks' if total > 1 else 'symlink'
+ print(' ' + filedir + ' (' + str(total) + ' ' + symstr + ')')
+
+ # Otherwise, if "link_from" is another PDK, then check all files against
+ # the files in the other PDK, and replace the file with a symbolic link
+ # if the file contents match.
+
+ elif link_from:
+ thispdk = os.path.split(targetdir)[1]
+
+ # Only create links for PDKs other than the one we are making links to.
+ if thispdk != link_from:
+
+ print('Replacing files with symbolic links to ' + link_from + ' where possible.')
+
+ for refdir in refdirs:
+ if ef_format:
+ filedirs = os.listdir(targetdir + refdir)
+ for filedir in filedirs:
+ print(' ' + filedir)
+ dirpath = targetdir + refdir + filedir
+ if os.path.isdir(dirpath):
+ libraries = os.listdir(dirpath)
+ for library in libraries:
+ libdir = targetdir + refdir + filedir + '/' + library
+ srclibdir = link_from + refdir + filedir + '/' + library
+ if checkdir != '':
+ checklibdir = checkdir + refdir + filedir + '/' + library
+ else:
+ checklibdir = srclibdir
+ if os.path.exists(libdir):
+ total = replace_all_with_symlinks(libdir, srclibdir, checklibdir)
+ if total > 0:
+ symstr = 'symlinks' if total > 1 else 'symlink'
+ print(' ' + library + ' (' + str(total) + ' ' + symstr + ')')
+ else:
+ libraries = os.listdir(targetdir + refdir)
+ for library in libraries:
+ print(' ' + library)
+ filedirs = os.listdir(targetdir + refdir + library)
+ for filedir in filedirs:
+ libdir = targetdir + refdir + library + '/' + filedir
+ srclibdir = link_from + refdir + library + '/' + filedir
+ if checkdir != '':
+ checklibdir = checkdir + refdir + library + '/' + filedir
+ else:
+ checklibdir = srclibdir
+ if os.path.exists(libdir):
+ total = replace_all_with_symlinks(libdir, srclibdir, checklibdir)
+ if total > 0:
+ symstr = 'symlinks' if total > 1 else 'symlink'
+ print(' ' + filedir + ' (' + str(total) + ' ' + symstr + ')')
+
+ # Remove temporary files: Magic generation scripts, sources.txt
+ # file, and magic extract files.
+
+ print('Removing temporary files from destination.')
+
+ for refdir in refdirs:
+ if ef_format:
+ filedirs = os.listdir(targetdir + refdir)
+ for filedir in filedirs:
+ if os.path.islink(filedir):
+ continue
+ elif os.path.isdir(filedir):
+ libraries = os.listdir(targetdir + refdir + filedir)
+ for library in libraries:
+ libdir = targetdir + refdir + filedir + '/' + library
+ libfiles = os.listdir(libdir)
+ for libfile in libfiles:
+ filepath = libdir + '/' + libfile
+ if os.path.islink(filepath):
+ continue
+ elif libfile == 'sources.txt':
+ os.remove(filepath)
+ elif libfile == 'generate_magic.tcl':
+ os.remove(filepath)
+ elif os.path.splitext(libfile)[1] == '.ext':
+ os.remove(filepath)
+ else:
+ libraries = os.listdir(targetdir + refdir)
+ for library in libraries:
+ filedirs = os.listdir(targetdir + refdir + library)
+ for filedir in filedirs:
+ filepath = targetdir + refdir + library + '/' + filedir
+ if os.path.islink(filepath):
+ continue
+ elif os.path.isdir(filepath):
+ libfiles = os.listdir(filepath)
+ for libfile in libfiles:
+ libfilepath = filepath + '/' + libfile
+ if os.path.islink(libfilepath):
+ continue
+ elif libfile == 'sources.txt':
+ os.remove(libfilepath)
+ elif libfile == 'generate_magic.tcl':
+ os.remove(libfilepath)
+ elif os.path.splitext(libfile)[1] == '.ext':
+ os.remove(libfilepath)
+
+ print('Done with PDK migration.')
+ sys.exit(0)
diff --git a/common/tksimpledialog.py b/common/tksimpledialog.py
new file mode 100755
index 0000000..4734291
--- /dev/null
+++ b/common/tksimpledialog.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#
+# Dialog class for tkinter
+
+import os
+import tkinter
+from tkinter import ttk
+
+class Dialog(tkinter.Toplevel):
+
+ def __init__(self, parent, message = None, title = None, seed = None, border = 'blue', **kwargs):
+
+ tkinter.Toplevel.__init__(self, parent)
+ self.transient(parent)
+
+ if title:
+ self.title(title)
+
+ self.configure(background=border, padx=2, pady=2)
+ self.obox = ttk.Frame(self)
+ self.obox.pack(side = 'left', fill = 'both', expand = 'true')
+
+ self.parent = parent
+ self.result = None
+ body = ttk.Frame(self.obox)
+ self.initial_focus = self.body(body, message, seed, **kwargs)
+ body.pack(padx = 5, pady = 5)
+ self.buttonbox()
+ self.grab_set()
+
+ if not self.initial_focus:
+ self.initial_focus = self
+
+ self.protocol("WM_DELETE_WINDOW", self.cancel)
+ self.geometry("+%d+%d" % (parent.winfo_rootx() + 50,
+ parent.winfo_rooty() + 50))
+
+ self.initial_focus.focus_set()
+ self.wait_window(self)
+
+ # Construction hooks
+
+ def body(self, master, **kwargs):
+ # Create dialog body. Return widget that should have
+ # initial focus. This method should be overridden
+ pass
+
+ def buttonbox(self):
+ # Add standard button box. Override if you don't want the
+ # standard buttons
+
+ box = ttk.Frame(self.obox)
+
+ self.okb = ttk.Button(box, text="OK", width=10, command=self.ok, default='active')
+ self.okb.pack(side='left', padx=5, pady=5)
+ w = ttk.Button(box, text="Cancel", width=10, command=self.cancel)
+ w.pack(side='left', padx=5, pady=5)
+
+ self.bind("<Return>", self.ok)
+ self.bind("<Escape>", self.cancel)
+ box.pack(fill='x', expand='true')
+
+ # Standard button semantics
+
+ def ok(self, event=None):
+
+ if not self.validate():
+ self.initial_focus.focus_set() # put focus back
+ return
+
+ self.withdraw()
+ self.update_idletasks()
+ self.result = self.apply()
+ self.cancel()
+
+ def cancel(self, event=None):
+
+ # Put focus back to the parent window
+ self.parent.focus_set()
+ self.destroy()
+
+ def validate(self):
+ return 1 # Override this
+
+ def apply(self):
+ return None # Override this
diff --git a/sky130/Makefile b/sky130/Makefile
new file mode 100644
index 0000000..2673519
--- /dev/null
+++ b/sky130/Makefile
@@ -0,0 +1,397 @@
+# Makefile for efabless design kits for SkyWater Sky130:
+#
+# sky130A = 5-metal backend stack with dual MiM
+#
+# Written by Tim Edwards March 2019
+# efabless corporation
+# updated October 2019
+# updated December 2019 (divide installation sections for individual tools)
+# updated March 2020 (refactored the install process)
+# updated May 2020 (changed to new process name Sky130)
+#
+# Instructions:
+#
+# Modify values below as needed:
+#
+# VENDOR_PATH: points to vendor sources
+# EF_STYLE: 1 for efabless style, 0 otherwise
+# LINK_TARGETS: link back to source or link to 1st PDK when possible
+# DIST_PATH: install location for distributed install
+# LOCAL_PATH: install location for local install or runtime location
+# for distributed install
+#
+# Run "make" to stage the PDK for tool setup and vendor libraries
+
+# If installing into the final destination (local install):
+#
+# Run "make install-local" to install all staged files
+# ("make install" is equivalent to "make install-local")
+#
+# If installing into a repository to be distributed to the final destination:
+#
+# Run "make install-dist" to install all staged files
+#
+# Run "make clean" to remove all staging files.
+#
+# Run "make veryclean" to remove all staging and install log files.
+#
+# For the sake of simplicity, the "standard" local install can be done
+# with the usual
+#
+# make
+# make install
+# make clean
+#
+#--------------------------------------------------------------------
+# This Makefile contains bash-isms
+SHELL = bash
+
+REVISION = 20200508
+TECH = sky130
+
+# If EF_STYLE is set to 1, then efabless naming conventions are
+# used, otherwise the generic naming conventions are used.
+# Mainly, the hierarchy of library names and file types is reversed
+# (e.g., sky130_fd_sc_hd/lef vs. lef/sky130_fd_sc_hd).
+
+EF_STYLE = 0
+# EF_STYLE = 1
+
+# Normally it's fine to keep the staging path in a local directory,
+# although /tmp or a dedicated staging area are also fine, as long
+# as the install process can write to the path.
+
+STAGING_PATH = `pwd`
+
+# If LINK_TARGETS is set to "none", then files are copied
+# from the SkyWater sources to the target. If set to "source",
+# symbolic links are made in the target directories pointing
+# back to the SkyWater sources. If set to the name of another
+# PDK (e.g, "sky130A"), then symbolic links are made to the
+# same files in that PDK, where they exist, and are copied
+# from source, where they don't.
+
+# LINK_TARGETS = source
+# LINK_TARGETS = none
+# LINK_TARGETS = sky130A
+LINK_TARGETS = source
+
+# Paths:
+
+# Path to skywater_pdk (to be changed to public repo; work in progress)
+# Version below comes from foss-eda-tools.googlesource.com
+# SKYWATER_PATH = ~/gits/skywater-pdk-scratch/skywater-pdk/libraries
+# Version below is also from foss-eda-tools and is more recent than
+# the scratch repo above.
+SKYWATER_PATH = ~/gits/skywater-pdk/libraries
+
+# NOTE: Install destination is the git repository of the technology platform.
+# Once updated in git, the git project can be distributed to all hosts.
+#
+ifeq (${EF_STYLE}, 1)
+ LOCAL_PATH = /ef/tech/SW
+ CONFIG_DIR = .ef-config
+ REV_DIR = ${REVISION}
+else
+ # LOCAL_PATH = /usr/local/share/vlsi/SkyWater
+ LOCAL_PATH = ~/projects/efabless/tech/SW
+ CONFIG_DIR = .config
+ REV_DIR = .
+endif
+
+DIST_PATH = ~/gits/ef-skywater-${TECH}
+
+# EF process nodes created from the master sources
+SKY130A = sky130A
+
+ifeq (${LINK_TARGETS}, ${SKY130A})
+ DIST_LINK_TARGETS = ${LOCAL_PATH}/${LINK_TARGETS}
+else
+ DIST_LINK_TARGETS = ${LINK_TARGETS}
+endif
+
+# Basic definitions for each EF process node
+SKY130A_DEFS = -DTECHNAME=sky130A -DREVISION=${REVISION}
+
+# Module definitions for each process node
+# (Note that MOS is default and therefore not used anywhere)
+# SKY130A_DEFS += -DMETAL5 -DMIM -DREDISTRIBUTION
+SKY130A_DEFS += -DMETAL5 -DMIM
+
+# Add staging path
+SKY130A_DEFS += -DSTAGING_PATH=${STAGING_PATH}
+
+ifeq (${EF_STYLE}, 1)
+ EF_FORMAT = -ef_format
+ SKY130A_DEFS += -DEF_FORMAT
+else
+ EF_FORMAT = -std_format
+endif
+
+MAGICTOP = libs.tech/magic
+NETGENTOP = libs.tech/netgen
+QFLOWTOP = libs.tech/qflow
+KLAYOUTTOP = libs.tech/klayout
+OPENLANETOP = libs.tech/openlane
+
+ifeq (${EF_STYLE}, 1)
+ MAGICPATH = ${MAGICTOP}/${REVISION}
+else
+ MAGICPATH = ${MAGICTOP}
+endif
+
+# Currently, netgen, qflow, and klayout do not use revisioning (needs to change!)
+NETGENPATH = ${NETGENTOP}
+QFLOWPATH = ${QFLOWTOP}
+KLAYOUTPATH = ${KLAYOUTTOP}
+OPENLANEPATH = ${OPENLANETOP}
+
+MAGICTOP_STAGING_A = ${STAGING_PATH}/${SKY130A}/${MAGICTOP}
+NETGENTOP_STAGING_A = ${STAGING_PATH}/${SKY130A}/${NETGENTOP}
+QFLOWTOP_STAGING_A = ${STAGING_PATH}/${SKY130A}/${QFLOWTOP}
+KLAYOUTTOP_STAGING_A = ${STAGING_PATH}/${SKY130A}/${KLAYOUTTOP}
+OPENLANETOP_STAGING_A = ${STAGING_PATH}/${SKY130A}/${OPENLANETOP}
+
+MAGIC_STAGING_A = ${STAGING_PATH}/${SKY130A}/${MAGICPATH}
+NETGEN_STAGING_A = ${STAGING_PATH}/${SKY130A}/${NETGENPATH}
+QFLOW_STAGING_A = ${STAGING_PATH}/${SKY130A}/${QFLOWPATH}
+KLAYOUT_STAGING_A = ${STAGING_PATH}/${SKY130A}/${KLAYOUTPATH}
+OPENLANE_STAGING_A = ${STAGING_PATH}/${SKY130A}/${OPENLANEPATH}
+
+SKY130A_DEFS += -DMAGIC_CURRENT=${MAGICTOP}/current
+
+# Where cpp syntax is followed, this is equivalent to cpp, but it does not
+# mangle non-C source files under the belief that they are actually C code.
+CPP = ../common/preproc.py
+
+# The following script in the ../common directory does most of the work of
+# copying or linking the foundry vendor files to the target directory.
+STAGE = set -f ; ../common/foundry_install.py ${EF_FORMAT}
+INSTALL = ../common/staging_install.py ${EF_FORMAT}
+
+# The script(s) below are used for custom changes to the vendor PDK files
+ADDPROP = ../common/insert_property.py ${EF_FORMAT}
+
+# List the EDA tools to install local setup files for
+TOOLS = magic qflow netgen klayout openlane
+
+all: all-a
+
+all-a:
+ echo "Starting sky130A PDK staging on "`date` > ${SKY130A}_install.log
+ ${MAKE} tools-a
+ ${MAKE} vendor-a
+ echo "Ended sky130A PDK staging on "`date` >> ${SKY130A}_install.log
+
+tools-a: general-a magic-a qflow-a netgen-a klayout-a openlane-a
+
+general-a: ${TECH}.json
+ mkdir -p ${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}
+ rm -f ${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}/nodeinfo.json
+ ${CPP} ${SKY130A_DEFS} ${TECH}.json > \
+ ${STAGING_PATH}/${SKY130A}/${CONFIG_DIR}/nodeinfo.json
+
+magic-a: ${TECH}.tech ${TECH}gds.tech ${TECH}.magicrc ${TECH}.tcl
+ mkdir -p ${MAGICTOP_STAGING_A}
+ mkdir -p ${MAGIC_STAGING_A}
+ rm -f ${MAGICTOP_STAGING_A}/current
+ rm -f ${MAGIC_STAGING_A}/${SKY130A}.tech
+ rm -f ${MAGIC_STAGING_A}/${SKY130A}-GDS.tech
+ rm -f ${MAGIC_STAGING_A}/${SKY130A}.tcl
+ rm -f ${MAGIC_STAGING_A}/${SKY130A}-BindKeys
+ rm -f ${MAGIC_STAGING_A}/magicrc
+ (cd ${MAGICTOP_STAGING_A} ; ln -s ${REV_DIR} current)
+ cp -rp custom/scripts/seal_ring_generator ${MAGIC_STAGING_A}/.
+ ${CPP} ${SKY130A_DEFS} ${TECH}.tech > ${MAGIC_STAGING_A}/${SKY130A}.tech
+ ${CPP} ${SKY130A_DEFS} ${TECH}gds.tech > ${MAGIC_STAGING_A}/${SKY130A}-GDS.tech
+ ${CPP} ${SKY130A_DEFS} ${TECH}.magicrc > ${MAGIC_STAGING_A}/${SKY130A}.magicrc
+ ${CPP} ${SKY130A_DEFS} ../common/pdk.bindkeys > ${MAGIC_STAGING_A}/${SKY130A}-BindKeys
+ ${CPP} ${SKY130A_DEFS} ${TECH}.tcl > ${MAGIC_STAGING_A}/${SKY130A}.tcl
+ ${CPP} ${SKY130A_DEFS} ../common/pdk.tcl >> ${MAGIC_STAGING_A}/${SKY130A}.tcl
+
+qflow-a: ${TECH}.sh ${TECH}.par
+ mkdir -p ${QFLOWTOP_STAGING_A}
+ mkdir -p ${QFLOW_STAGING_A}
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hd.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hd.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hdll.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hdll.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hs.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hs.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hvl.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}hvl.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}ls.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}ls.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}lp.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}lp.par
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}ms.sh
+ rm -f ${QFLOW_STAGING_A}/${SKY130A}ms.par
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_hd ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}hd.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_hdll ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}hdll.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_hvl ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}hvl.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_hs ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}hs.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_lp ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}lp.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_ls ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}ls.sh
+ ${CPP} ${SKY130A_DEFS} -DLIBRARY=sky130_fd_sc_ms ${TECH}.sh > \
+ ${QFLOW_STAGING_A}/${SKY130A}ms.sh
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}hd.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}hdll.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}hvl.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}hs.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}ms.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}lp.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}ls.par
+ ${CPP} ${SKY130A_DEFS} ${TECH}.par > ${QFLOW_STAGING_A}/${SKY130A}osu.par
+
+netgen-a: ${TECH}_setup.tcl
+ mkdir -p ${NETGENTOP_STAGING_A}
+ mkdir -p ${NETGEN_STAGING_A}
+ rm -f ${NETGEN_STAGING_A}/${SKY130A}_setup.tcl
+ rm -f ${NETGEN_STAGING_A}/setup.tcl
+ ${CPP} ${SKY130A_DEFS} ${TECH}_setup.tcl > ${NETGEN_STAGING_A}/${SKY130A}_setup.tcl
+ (cd ${NETGEN_STAGING_A} ; ln -s ${SKY130A}_setup.tcl setup.tcl)
+
+klayout-a: ${TECH}.lyp ${TECH}.lyt
+ mkdir -p ${KLAYOUTTOP_STAGING_A}
+ mkdir -p ${KLAYOUT_STAGING_A}
+ rm -f ${KLAYOUT_STAGING_A}/${SKY130A}.lyp
+ rm -f ${KLAYOUT_STAGING_A}/${SKY130A}.lyt
+ ${CPP} ${SKY130A_DEFS} ${TECH}.lyp > ${KLAYOUT_STAGING_A}/${SKY130A}.lyp
+ ${CPP} ${SKY130A_DEFS} ${TECH}.lyt > ${KLAYOUT_STAGING_A}/${SKY130A}.lyt
+
+openlane-a: common_pdn.tcl common_tracks.info config.tcl sky130_fd_sc_hd_config.tcl
+ mkdir -p ${OPENLANETOP_STAGING_A}
+ mkdir -p ${OPENLANE_STAGING_A}
+ mkdir -p ${OPENLANE_STAGING_A}/sky130_fd_sc_hd
+ rm -f ${OPENLANE_STAGING_A}/common_pdn.info
+ rm -f ${OPENLANE_STAGING_A}/common_tracks.info
+ rm -f ${OPENLANE_STAGING_A}/config.tcl
+ rm -f ${OPENLANE_STAGING_A}/sky130_fd_sc_hd/config.tcl
+ ${CPP} ${SKY130A_DEFS} common_pdn.tcl > ${OPENLANE_STAGING_A}/common_pdn.tcl
+ ${CPP} ${SKY130A_DEFS} common_tracks.info > ${OPENLANE_STAGING_A}/common_tracks.info
+ ${CPP} ${SKY130A_DEFS} config.tcl > ${OPENLANE_STAGING_A}/config.tcl
+ ${CPP} ${SKY130A_DEFS} sky130_fd_sc_hd_config.tcl > ${OPENLANE_STAGING_A}/sky130_fd_sc_hd/config.tcl
+
+vendor-a:
+ # Install base device models from vendor files
+ # (NOTE: .mod and .pm3 files should not be in /cells/?)
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -ngspice sky130_fd_pr_base/v%v/models/* filter=custom/scripts/fixspice.py \
+ -ngspice sky130_fd_pr_base/v%v/cells/*.mod filter=custom/scripts/fixspice.py \
+ -ngspice sky130_fd_pr_base/v%v/cells/*.pm3 filter=custom/scripts/fixspice.py \
+ |& tee -a ${SKY130A}_install.log
+ # Install RF device models from vendor files
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -ngspice sky130_fd_pr_rf/v%v/models/* filter=custom/scripts/fixspice.py \
+ |& tee -a ${SKY130A}_install.log
+ # Install additional RF device models from vendor files
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -ngspice sky130_fd_pr_rf2/v%v/models/* filter=custom/scripts/fixspice.py \
+ |& tee -a ${SKY130A}_install.log
+ # Install base device library from vendor files
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -gds %l/v%v/cells/*/*.gds \
+ -spice %l/v%v/cells/*/*.spice ignore=topography \
+ -spice %l/v%v/cells/*/*.sp \
+ -library primitive sky130_fd_pr_base \
+ -library primitive sky130_fd_pr_rf \
+ -library primitive sky130_fd_pr_rf2 |& tee -a ${SKY130A}_install.log
+ # Install SkyWater I/O pad library
+ # Purposely ignoring "-lef sky130_fd_io/v%v/lef/*.lef" and making our own LEF views
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -gds %l/v%v/cells/*/*.gds \
+ -verilog %l/v%v/cells/*/*.v \
+ -lib %l/v%v/cells/*/*.lib \
+ -doc %l/v%v/cells/*/*.doc \
+ -cdl %l/v%v/cells/*/*.cdl ignore=topography \
+ -spice %l/v%v/cells/*/*.spice \
+ -library general sky130_fd_io |& tee -a ${SKY130A}_install.log
+ # Install all SkyWater digital standard cells.
+ ${STAGE} -source ${SKYWATER_PATH} -target ${STAGING_PATH}/${SKY130A} \
+ -spice %l/v%v/cells/*/*.spice compile-only \
+ -cdl %l/v%v/cells/*/*.cdl ignore=topography compile-only \
+ -lef %l/v%v/cells/*/*.lef compile-only \
+ -doc %l/v%v/cells/*/*.pdf \
+ -lib %l/v%v/timing/*.lib \
+ -gds %l/v%v/cells/*/*.gds compile-only \
+ -verilog %l/v%v/cells/*/*.v exclude=*.*.v compile-only \
+ -library digital sky130_fd_sc_hd \
+ -library digital sky130_fd_sc_hdll \
+ -library digital sky130_fd_sc_hvl \
+ -library digital sky130_fd_sc_hs \
+ -library digital sky130_fd_sc_ls \
+ -library digital sky130_fd_sc_ms \
+ -library digital sky130_fd_sc_lp |& tee -a ${SKY130A}_install.log
+ # Install additional model file (efabless)
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -ngspice models/*.lib rename ${SKY130A}.lib \
+ |& tee -a ${SKY130A}_install.log
+ # Install custom additions to digital libraries
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -techlef techLEF/sky130_fd_sc_hd_tech.lef \
+ -library digital sky130_fd_sc_hd |& tee -a ${SKY130A}_install.log
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -techlef techLEF/sky130_fd_sc_hd_tech.lef \
+ rename sky130_fd_sc_hdll_tech.lef \
+ -library digital sky130_fd_sc_hdll |& tee -a ${SKY130A}_install.log
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -techlef techLEF/sky130_fd_sc_hs_tech.lef \
+ -library digital sky130_fd_sc_hs |& tee -a ${SKY130A}_install.log
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -techlef techLEF/sky130_fd_sc_hs_tech.lef \
+ rename sky130_fd_sc_ms_tech.lef \
+ -library digital sky130_fd_sc_ms |& tee -a ${SKY130A}_install.log
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -techlef techLEF/sky130_fd_sc_hs_tech.lef \
+ rename sky130_fd_sc_ls_tech.lef \
+ -library digital sky130_fd_sc_ls |& tee -a ${SKY130A}_install.log
+ # Install custom additions to I/O pad library
+ ${STAGE} -source ./custom -target ${STAGING_PATH}/${SKY130A} \
+ -gds %l/gds/*.gds \
+ -verilog %l/verilog/*.v \
+ -lef %l/lef/*.lef \
+ -spice %l/spice/*.spice \
+ -library general sky130_fd_io |& tee -a ${SKY130A}_install.log
+ # Add correct bounding boxes on Magic layouts
+ ${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_gpio_ovtv2 \
+ "FIXED_BBOX 0 407 28000 40000"
+ ${ADDPROP} ${STAGING_PATH}/${SKY130A} sky130_fd_io sky130_fd_io_top_xres4v2 \
+ "FIXED_BBOX 0 407 15000 40000"
+
+install: install-local
+
+install-local: install-local-a
+
+install-local-a:
+ echo "Starting SKY130 PDK migration on "`date` > ${SKY130A}_migrate.log
+ ${INSTALL} -source ${STAGING_PATH}/${SKY130A} \
+ -target ${LOCAL_PATH}/${SKY130A} \
+ -link_from ${LINK_TARGETS} |& tee -a ${SKY130A}_migrate.log
+ echo "Ended SKY130 PDK migration on "`date` >> ${SKY130A}_migrate.log
+
+install-dist: install-dist-a
+
+install-dist-a:
+ echo "Starting SKY130 PDK migration on "`date` > ${SKY130A}_migrate.log
+ ${INSTALL} -source ${STAGING_PATH}/${SKY130A} \
+ -target ${DIST_PATH}/${SKY130A} \
+ -local ${LOCAL_PATH}/${SKY130A} \
+ -link_from ${DIST_LINK_TARGETS} |& tee -a ${SKY130A}_migrate.log
+ echo "Ended SKY130 PDK migration on "`date` >> ${SKY130A}_migrate.log
+
+clean: clean-a
+
+clean-a:
+ ${STAGE} -target ${STAGING_PATH}/${SKY130A} -clean
+
+veryclean: veryclean-a
+
+veryclean-a: clean-a
+ ${RM} ${SKY130A}_install.log
+ ${RM} ${SKY130A}_migrate.log
diff --git a/sky130/README b/sky130/README
new file mode 100644
index 0000000..00b9851
--- /dev/null
+++ b/sky130/README
@@ -0,0 +1,180 @@
+------------------------------------
+open_pdks
+----------------------------------------
+Master PDK generator for SkyWater Sky130
+Hybrid 180nm / 130nm foundry process
+for open source EDA tools
+----------------------------------------
+
+-------------------------------------------------------------------------------
+Prerequisites:
+
+1. Foundry source files:
+
+ Obtain sources for the SkyWater sky130 130nm process from the git repository at
+ the following location:
+
+ https://github.com/google/skywater-pdk
+
+ This repository may go in any convenient location. The Makefile suggests
+ the target location ~/projects/foundry/skywater-pdk but any location will
+ do as long as the definition for CYPRESS_PATH in the Makefile is set
+ appropriately.
+
+ So cd to the target location parent directory (e.g., "cd ~/projects/foundry")
+ and run the following command:
+
+ git clone https://github.com/google/skywater-pdk
+
+ Then follow the instructions below.
+
+2. EDA tools:
+
+ For installing files to use with the Magic layout tool, Magic must be installed.
+ Obtain Magic from:
+
+ https://github.com/RTimothyEdwards/magic
+
+-------------------------------------------------------------------------------
+Installation:
+
+ There are two methods for installation: Local and Distribution. Use Local
+ installation if you are installing on a single host computer. Use Distribution
+ installation if you are installing into a respository (such as git) that will
+ be distributed to multiple hosts.
+
+Step 1:
+
+ Edit the Makefile to set the following definitions for your host system:
+
+ EF_STYLE = Select "1" for an efabless-style file structure, "0"
+ otherwise. There are only minor differences in
+ these two styles, namely for version tracking of
+ the Magic setup files, and the location of the
+ technology LEF file.
+
+ LINK_TARGETS = "none" or "source". "none" copies files from the source
+ directories to the target. "source" makes symbolic links
+ to the source directories. Use "source" only if doing
+ a local install, and the source foundry data will not
+ be deleted. For distribution installations, LINK_TARGETS
+ must be set to "none".
+
+ LOCAL_PATH = The path to the target install directory. This is used
+ in both the local and distribution installations. For
+ a distribution installation, this is the local name of
+ the path to the PDK after it has been distributed to
+ the host computers.
+
+ DIST_PATH = The path to the location of the installed files prior to
+ distribution. This will most likely be a git or similar
+ repo.
+
+Step 2:
+ Run:
+
+ make
+
+ This will pre-process the setup files to create the PDK-specific files
+ for the SKY130A PDK, and process all vendor files, and place everything
+ in a local staging area.
+
+Step 3:
+ For a local install, do:
+
+ make install-local
+
+ This copies all files from the staging area into the destination
+ as specified by the variable LOCAL_PATH in the Makefile. All
+ pointers to absolute paths in the files are changed to match
+ LOCAL_PATH.
+
+ For a distribution install, do:
+
+ make install-dist
+
+ This copies all files from the staging area into the destination
+ as specified by the variable DIST_PATH in the Makefile. All
+ pointers to absolute paths in the files are changed to match
+ LOCAL_PATH. The assumption is that DIST_PATH is a repository
+ (such as a git repo) that is cloned to multiple hosts, and
+ the destination on the hosts where it is distributed is
+ LOCAL_PATH.
+
+-------------------------------------------------------------------------------
+Summary:
+
+ 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. The syntax
+ is similar to that used by the C preprocessor (cpp) but does not assume C
+ language syntax in the input file, so is generally better to use than cpp
+ (has less unexpected/unintentional behavior). See comments in the preproc.py
+ script for a full list of macros that it accepts (short list: #ifdef, #ifndef,
+ #define, #include, and boolean operators ||, &&, and !).
+
+ Files generated:
+ .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, standard 1.8V digital
+ .par graywolf setup file, standard 1.8V digital
+
+ The installation directory below LOCAL_PATH is the name of the PDK; e.g.,
+
+ sky130A/ 5-metal stack with MiM cap and redistribution layer
+
+ The installation directory hierarchy below the PDK name looks like the following:
+
+ libs.tech/ technology and setup files
+
+ 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
+
+ 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:
+
+ 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_hs/ 1.8V digital logic (low power)
+ sky130_fd_sc_hvl/ 1.8V digital logic (low speed)
+ sky130_fd_sc_lp/ 1.8V digital logic (medium speed)
+ sky130_fd_sc_ls/ 1.8V digital logic (high speed)
+ sky130_fd_sc_ms/ 3.3V digital logic
+
+ sky130_fd_io/ Standard I/O
+
+ sky130_fd_pr_base/ Primitive devices w/fixed layout
+ sky130_fd_pr_rf/ RF primitive devices w/fixed layout
+ sky130_fd_pr_rf2/ Additional RF primitive devices w/fixed layout
+
+ The target installation destinations assume the directory structure above. Changing
+ this requires editing the source files.
+
diff --git a/sky130/common_pdn.tcl b/sky130/common_pdn.tcl
new file mode 100644
index 0000000..9ad2264
--- /dev/null
+++ b/sky130/common_pdn.tcl
@@ -0,0 +1,44 @@
+# Power nets
+set ::power_nets "VDD"
+set ::ground_nets "VSS"
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+ name grid
+ rails {
+ met1 {width 0.48 pitch $::env(PLACE_SITE_WIDTH) offset 0}
+ }
+ straps {
+ met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+ met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+ }
+ connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+ orient {R0 R180 MX MY R90 R270 MXR90 MYR90}
+ power_pins "VDDE"
+ ground_pins "VSSE"
+ blockages "li1 met1 met2 met3 met4 met5"
+ straps {
+ }
+ connect { }
+}
+
+set ::halo 0
+
+# Metal layer for rails on every row
+set ::rails_mlayer "met1" ;
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
+
+proc generate_viarules {} {
+}
+
+cd $::env(TMP_DIR)/floorplan
+
diff --git a/sky130/common_tracks.info b/sky130/common_tracks.info
new file mode 100644
index 0000000..948dbd2
--- /dev/null
+++ b/sky130/common_tracks.info
@@ -0,0 +1,12 @@
+li1 X 0.23 0.46
+li1 Y 0.17 0.34
+met1 X 0.17 0.34
+met1 Y 0.17 0.34
+met2 X 0.23 0.46
+met2 Y 0.23 0.46
+met3 X 0.34 0.68
+met3 Y 0.34 0.68
+met4 X 0.46 0.92
+met4 Y 0.46 0.92
+met5 X 1.70 3.40
+met5 Y 1.70 3.40
diff --git a/sky130/config.tcl b/sky130/config.tcl
new file mode 100644
index 0000000..d34b05f
--- /dev/null
+++ b/sky130/config.tcl
@@ -0,0 +1,31 @@
+# Process node
+set ::env(PROCESS) 130
+set ::env(DEF_UNITS_PER_MICRON) 1000
+
+
+# Placement site for core cells
+# This can be found in the technology lef
+set ::env(PLACE_SITE) "unithd"
+set ::env(PLACE_SITE_WIDTH) 0.460
+set ::env(PLACE_SITE_HEIGHT) 2.720
+
+set ::env(VDD_PIN) "vpwr"
+set ::env(GND_PIN) "vgnd"
+
+# Track information for generating DEF tracks
+set ::env(TRACKS_INFO_FILE) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/common_tracks.info"
+
+
+# Technology LEF
+set ::env(TECH_LEF) "$::env(PDK_ROOT)/$::env(PDK)/libs.ref/techLEF/$::env(PDK_VARIANT)/$::env(PDK_VARIANT)_tech.lef"
+set ::env(CELLS_LEF) [glob "$::env(PDK_ROOT)/$::env(PDK)/libs.ref/lef/$::env(PDK_VARIANT)/*.lef"]
+set ::env(MAGIC_TECH_FILE) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/magic/current/EFS8A.tech"
+set ::env(MAGIC_MAGICRC) "$::env(PDK_ROOT)/$::env(PDK)/libs.tech/magic/current/EFS8A.magicrc"
+set ::env(GPIO_PADS_LEF) [glob "$::env(PDK_ROOT)/$::env(PDK)/libs.ref/lef/s8iom0s8/routing_abstract/*.lef"]
+
+# netgen setup
+set ::env(NETGEN_SETUP_FILE) $::env(PDK_ROOT)/$::env(PDK)/libs.tech/netgen/$::env(PDK)_setup.tcl
+# CTS luts
+set ::env(CTS_TECH_DIR) "N/A"
+
+set ::env(FP_TAPCELL_DIST) 20
diff --git a/sky130/custom/models/sky130.lib b/sky130/custom/models/sky130.lib
new file mode 100644
index 0000000..04c51ed
--- /dev/null
+++ b/sky130/custom/models/sky130.lib
@@ -0,0 +1,170 @@
+******* SkyWater s8 model library *********
+* Typical corner (tt)
+.lib tt
+* MOSFET
+.inc "./sky130_fd_pr_base__nshort_tt.cor"
+.inc "./sky130_fd_pr_base__nlowvt_tt.cor"
+.inc "./sky130_fd_pr_base__pshort_tt.cor"
+.inc "./sky130_fd_pr_base__ntvnative_tt.cor"
+.inc "./sky130_fd_pr_base__nhvnative_tt.cor"
+.inc "./sky130_fd_pr_base__nshortesd_tt.cor"
+.inc "./sky130_fd_pr_base__plowvt_tt.cor"
+.inc "./sky130_fd_pr_base__phighvt_tt.cor"
+.inc "./sky130_fd_pr_base__phvesd_tt.cor"
+.inc "./sky130_fd_pr_base__phv_tt.cor"
+.inc "./sky130_fd_pr_base__pvhv_tt.cor"
+.inc "./sky130_fd_pr_base__nhv_tt.cor"
+.inc "./sky130_fd_pr_base__nvhv_tt_discrete.cor"
+.inc "./sky130_fd_pr_base__nhvesd_tt.cor"
+.inc "./sky130_fd_pr_base__tt_nonfet.cor"
+* Mismatch parameters
+.inc "./sky130_fd_pr_base__nshort_mm.cor"
+.inc "./sky130_fd_pr_base__pshort_mm.cor"
+.inc "./sky130_fd_pr_base__nlowvt_mm.cor"
+.inc "./sky130_fd_pr_base__plowvt_mm.cor"
+.inc "./sky130_fd_pr_base__phighvt_mm.cor"
+.inc "./sky130_fd_pr_base__nhv_mm.cor"
+.inc "./sky130_fd_pr_base__phv_mm.cor"
+.inc "./sky130_fd_pr_base__nhvnative_mm.cor"
+.inc "./sky130_fd_pr_base__ntvnative_mm.cor"
+* All models
+.inc "models.all"
+* Corner
+.include "ttrf.cor"
+.endl
+
+* Slow-Fast corner (sf)
+.lib sf
+* MOSFET
+.inc "./sky130_fd_pr_base__nshort_sf.cor"
+.inc "./sky130_fd_pr_base__nlowvt_sf.cor"
+.inc "./sky130_fd_pr_base__pshort_sf.cor"
+.inc "./sky130_fd_pr_base__ntvnative_sf.cor"
+.inc "./sky130_fd_pr_base__nhvnative_sf.cor"
+.inc "./sky130_fd_pr_base__nshortesd_sf.cor"
+.inc "./sky130_fd_pr_base__plowvt_sf.cor"
+.inc "./sky130_fd_pr_base__phighvt_sf.cor"
+.inc "./sky130_fd_pr_base__phvesd_sf.cor"
+.inc "./sky130_fd_pr_base__phv_sf.cor"
+.inc "./sky130_fd_pr_base__pvhv_sf.cor"
+.inc "./sky130_fd_pr_base__nhv_sf.cor"
+.inc "./sky130_fd_pr_base__nvhv_sf_discrete.cor"
+.inc "./sky130_fd_pr_base__nhvesd_sf.cor"
+.inc "./sky130_fd_pr_base__sf_nonfet.cor"
+* Mismatch parameters
+.inc "./sky130_fd_pr_base__nshort_mm.cor"
+.inc "./sky130_fd_pr_base__pshort_mm.cor"
+.inc "./sky130_fd_pr_base__nlowvt_mm.cor"
+.inc "./sky130_fd_pr_base__plowvt_mm.cor"
+.inc "./sky130_fd_pr_base__phighvt_mm.cor"
+.inc "./sky130_fd_pr_base__nhv_mm.cor"
+.inc "./sky130_fd_pr_base__phv_mm.cor"
+.inc "./sky130_fd_pr_base__nhvnative_mm.cor"
+.inc "./sky130_fd_pr_base__ntvnative_mm.cor"
+* All models
+.inc "models.all"
+* Corner
+.include "sfrf.cor"
+.endl
+
+* Fast-Fast corner (ff)
+.lib ff
+* MOSFET
+.inc "./sky130_fd_pr_base__nshort_ff.cor"
+.inc "./sky130_fd_pr_base__nlowvt_ff.cor"
+.inc "./sky130_fd_pr_base__pshort_ff.cor"
+.inc "./sky130_fd_pr_base__ntvnative_ff.cor"
+.inc "./sky130_fd_pr_base__nhvnative_ff.cor"
+.inc "./sky130_fd_pr_base__nshortesd_ff.cor"
+.inc "./sky130_fd_pr_base__plowvt_ff.cor"
+.inc "./sky130_fd_pr_base__phighvt_ff.cor"
+.inc "./sky130_fd_pr_base__phvesd_ff.cor"
+.inc "./sky130_fd_pr_base__phv_ff.cor"
+.inc "./sky130_fd_pr_base__pvhv_ff.cor"
+.inc "./sky130_fd_pr_base__nhv_ff.cor"
+.inc "./sky130_fd_pr_base__nvhv_ff_discrete.cor"
+.inc "./sky130_fd_pr_base__nhvesd_ff.cor"
+.inc "./sky130_fd_pr_base__ff_nonfet.cor"
+* Mismatch parameters
+.inc "./sky130_fd_pr_base__nshort_mm.cor"
+.inc "./sky130_fd_pr_base__pshort_mm.cor"
+.inc "./sky130_fd_pr_base__nlowvt_mm.cor"
+.inc "./sky130_fd_pr_base__plowvt_mm.cor"
+.inc "./sky130_fd_pr_base__phighvt_mm.cor"
+.inc "./sky130_fd_pr_base__nhv_mm.cor"
+.inc "./sky130_fd_pr_base__phv_mm.cor"
+.inc "./sky130_fd_pr_base__nhvnative_mm.cor"
+.inc "./sky130_fd_pr_base__ntvnative_mm.cor"
+* All models
+.inc "models.all"
+* Corner
+.include "ffrf.cor"
+.endl
+
+* Slow-Slow corner (ss)
+.lib ss
+* MOSFET
+.inc "./sky130_fd_pr_base__nshort_ss.cor"
+.inc "./sky130_fd_pr_base__nlowvt_ss.cor"
+.inc "./sky130_fd_pr_base__pshort_ss.cor"
+.inc "./sky130_fd_pr_base__ntvnative_ss.cor"
+.inc "./sky130_fd_pr_base__nhvnative_ss.cor"
+.inc "./sky130_fd_pr_base__nshortesd_ss.cor"
+.inc "./sky130_fd_pr_base__plowvt_ss.cor"
+.inc "./sky130_fd_pr_base__phighvt_ss.cor"
+.inc "./sky130_fd_pr_base__phvesd_ss.cor"
+.inc "./sky130_fd_pr_base__phv_ss.cor"
+.inc "./sky130_fd_pr_base__pvhv_ss.cor"
+.inc "./sky130_fd_pr_base__nhv_ss.cor"
+.inc "./sky130_fd_pr_base__nvhv_ss_discrete.cor"
+.inc "./sky130_fd_pr_base__nhvesd_ss.cor"
+.inc "./sky130_fd_pr_base__ss_nonfet.cor"
+* Mismatch parameters
+.inc "./sky130_fd_pr_base__nshort_mm.cor"
+.inc "./sky130_fd_pr_base__pshort_mm.cor"
+.inc "./sky130_fd_pr_base__nlowvt_mm.cor"
+.inc "./sky130_fd_pr_base__plowvt_mm.cor"
+.inc "./sky130_fd_pr_base__phighvt_mm.cor"
+.inc "./sky130_fd_pr_base__nhv_mm.cor"
+.inc "./sky130_fd_pr_base__phv_mm.cor"
+.inc "./sky130_fd_pr_base__nhvnative_mm.cor"
+.inc "./sky130_fd_pr_base__ntvnative_mm.cor"
+* All models
+.inc "models.all"
+* Corner
+.include "ssrf.cor"
+.endl
+
+* Fast-Slow corner (fs)
+.lib fs
+* MOSFET
+.inc "./sky130_fd_pr_base__nshort_fs.cor"
+.inc "./sky130_fd_pr_base__nlowvt_fs.cor"
+.inc "./sky130_fd_pr_base__pshort_fs.cor"
+.inc "./sky130_fd_pr_base__ntvnative_fs.cor"
+.inc "./sky130_fd_pr_base__nhvnative_fs.cor"
+.inc "./sky130_fd_pr_base__nshortesd_fs.cor"
+.inc "./sky130_fd_pr_base__plowvt_fs.cor"
+.inc "./sky130_fd_pr_base__phighvt_fs.cor"
+.inc "./sky130_fd_pr_base__phvesd_fs.cor"
+.inc "./sky130_fd_pr_base__phv_fs.cor"
+.inc "./sky130_fd_pr_base__pvhv_fs.cor"
+.inc "./sky130_fd_pr_base__nhv_fs.cor"
+.inc "./sky130_fd_pr_base__nvhv_fs_discrete.cor"
+.inc "./sky130_fd_pr_base__nhvesd_fs.cor"
+.inc "./sky130_fd_pr_base__fs_nonfet.cor"
+* Mismatch parameters
+.inc "./sky130_fd_pr_base__nshort_mm.cor"
+.inc "./sky130_fd_pr_base__pshort_mm.cor"
+.inc "./sky130_fd_pr_base__nlowvt_mm.cor"
+.inc "./sky130_fd_pr_base__plowvt_mm.cor"
+.inc "./sky130_fd_pr_base__phighvt_mm.cor"
+.inc "./sky130_fd_pr_base__nhv_mm.cor"
+.inc "./sky130_fd_pr_base__phv_mm.cor"
+.inc "./sky130_fd_pr_base__nhvnative_mm.cor"
+.inc "./sky130_fd_pr_base__ntvnative_mm.cor"
+* All models
+.inc "models.all"
+* Corner
+.include "fsrf.cor"
+.endl
diff --git a/sky130/custom/scripts/fixspice.py b/sky130/custom/scripts/fixspice.py
new file mode 100755
index 0000000..92cca88
--- /dev/null
+++ b/sky130/custom/scripts/fixspice.py
@@ -0,0 +1,96 @@
+#!/bin/env python3
+#
+# fixspice ---
+#
+# This script fixes problems in the SkyWater SPICE models. This should be
+# made obsolete by the forthcoming set of models from the foundry, but the
+# script will get the original set working with ngspice.
+#
+# This script is a filter to be run by setting the name of this script as
+# the value to "filter=" for the model install in the s8 Makefile.
+
+import re
+import os
+import sys
+
+def filter(inname, outname):
+
+ # Read input
+ try:
+ with open(inname, 'r') as inFile:
+ spitext = inFile.read()
+ # (Don't) unwrap continuation lines
+ # spilines = spitext.replace('\n+', ' ').splitlines()
+ spilines = spitext.splitlines()
+ except:
+ print('fixspice.py: failed to open ' + fnmIn + ' for reading.', file=sys.stderr)
+ return 1
+
+ # Process input with regexp
+
+ fixedlines = []
+ modified = False
+
+ for line in spilines:
+
+ # Fix 1: ngspice does not understand the syntax used for the dev/gauss lines,
+ # so remove them.
+ fixedline = re.sub('dev/gauss[ \t]*=.*$', '', line)
+
+ # Fix 2: Remove references to *_dlc_rotweak
+ # fixedline = re.sub('\+[ \t]*[^ \t_]+_dlc_rotweak', '', fixedline)
+
+ # Fix 2: Remove references to *_[a,p]junction_mult
+ # fixedline = re.sub('\*[ \t]*[^ \t_]+_[ap]junction_mult', '', fixedline)
+
+ fixedlines.append(fixedline)
+ if fixedline != line:
+ modified = True
+
+ # Write output
+ if outname == None:
+ for i in fixedlines:
+ print(i)
+ else:
+ # If the output is a symbolic link but no modifications have been made,
+ # then leave it alone. If it was modified, then remove the symbolic
+ # link before writing.
+ if os.path.islink(outname):
+ if not modified:
+ return 0
+ else:
+ os.unlink(outname)
+ try:
+ with open(outname, 'w') as outFile:
+ for i in fixedlines:
+ print(i, file=outFile)
+ except:
+ print('fixspice.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
+ return 1
+
+
+if __name__ == '__main__':
+
+ # This script expects to get one or two arguments. One argument is
+ # mandatory and is the input file. The other argument is optional and
+ # is the output file. The output file and input file may be the same
+ # name, in which case the original input is overwritten.
+
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item[1:])
+ else:
+ arguments.append(item)
+
+ if len(arguments) > 0:
+ infilename = arguments[0]
+
+ if len(arguments) > 1:
+ outfilename = arguments[1]
+ else:
+ outfilename = None
+
+ result = filter(infilename, outfilename)
+ sys.exit(result)
diff --git a/sky130/custom/scripts/seal_ring_generator/.magicrc b/sky130/custom/scripts/seal_ring_generator/.magicrc
new file mode 100644
index 0000000..2a18665
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/.magicrc
@@ -0,0 +1,3 @@
+scalegrid 1 10
+tech load s8seal_ring.tech
+drc off
diff --git a/sky130/custom/scripts/seal_ring_generator/README b/sky130/custom/scripts/seal_ring_generator/README
new file mode 100644
index 0000000..af48894
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/README
@@ -0,0 +1,37 @@
+# This directory contains a seal ring generator for SkyWater s8 using magic.
+# Because the seal ring contains many layers that do not appear in standard
+# layout editing, they are all specially implemented in the s8seal_ring.tech
+# file in this directory.
+#
+# An example seal ring was generated by SkyWater and imported using magic's
+# gdsquery.sh script. It was then hand-edited to contain only the bottom
+# quarter. Then it was saved in .mag databases.
+#
+# The generator script s8_gen_sealring.py calls magic using the s8seal_ring.tech
+# file, and automatically modifies the geometry to stretch to the half width
+# and height of the specified dimensions. Then the lower-left cells are
+# copied and folded over the centerline to make the complete seal ring.
+# The seal ring is then written out in GDS format. Then a simplified magic
+# view is generated in the usual user-facing s8 technology file, with the
+# GDS_FILE property pointing to the seal ring GDS. This layout and GDS can
+# then be imported into a layout.
+#
+# Usage:
+#
+# s8_gen_sealring.py width height target_dir [-force] [-outer]
+#
+# Where:
+# width = the full-chip layout width
+# height = the full-chip layout height
+# target_dir = location of the full-chip layout
+#
+# -force = overwrite existing files in the target directory
+# -outer = width and height represent the seal ring outer edge, not the chip area
+#
+# Results:
+# Files advSeal_6u_gen.mag and advSeal_6um_gen.gds are generated and placed in
+# target_dir. advSeal_6u_gen.mag is an "abstract" view that represents the
+# seal ring in diffusion and the nikon cross in metal1, and references
+# the advSeal_6um_gen.gds file in the same directory as a GDS_FILE property.
+#
+
diff --git a/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl b/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl
new file mode 100644
index 0000000..9aedf7b
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/generate_gds.tcl
@@ -0,0 +1,10 @@
+# Tcl script input to magic to generate seal ring GDS
+tech load s8seal_ring -noprompt
+drc off
+load advSeal_6um_gen
+select top cell
+expand
+cif *hier write disable
+cif *array write disable
+gds write advSeal_6um_gen
+quit
diff --git a/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag b/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag
new file mode 100644
index 0000000..caf7cc9
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/nikon_sealring_shape.mag
@@ -0,0 +1,130 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< checkpaint >>
+rect 0 0 400 400
+<< type21 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type22 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type23 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type27 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type28 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type30 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type32 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type34 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type35 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type36 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type40 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type41 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type43 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type44 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type46 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type50 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type51 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type56 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type58 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type59 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type88 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type96 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type97 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+<< type98 >>
+rect 175 225 225 320
+rect 80 175 320 225
+rect 175 80 225 175
+use sr_polygon00006 sr_polygon00006_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00005 sr_polygon00005_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00004 sr_polygon00004_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00003 sr_polygon00003_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00002 sr_polygon00002_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00001 sr_polygon00001_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+use sr_polygon00007 sr_polygon00007_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 400 400
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py b/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py
new file mode 100755
index 0000000..d1c3761
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/s8_gen_sealring.py
@@ -0,0 +1,349 @@
+#!/bin/env python3
+#-------------------------------------------------------------------------
+# s8_gen_sealring.py --- a seal ring generator for SkyWater s8 using magic.
+#
+# Because the seal ring contains many layers that do not appear in standard
+# layout editing, they are all specially implemented in the s8seal_ring.tech
+# file in this directory.
+#
+# An example seal ring was generated by SkyWater and imported using magic's
+# gdsquery.sh script. It was then hand-edited to contain only the bottom
+# quarter. Then it was saved in .mag databases.
+#
+# The generator script s8_gen_sealring.py calls magic using the s8seal_ring.tech
+# file, and automatically modifies the geometry to stretch to the half width
+# and height of the specified dimensions. Then the lower-left cells are
+# copied and folded over the centerline to make the complete seal ring.
+# The seal ring is then written out in GDS format. Then a simplified magic
+# view is generated in the usual user-facing s8 technology file, with the
+# GDS_FILE property pointing to the seal ring GDS. This layout and GDS can
+# then be imported into a layout.
+#
+# Usage:
+#
+# s8_gen_sealring.py width height target_dir [-force] [-outer] [-keep]
+#
+# Where:
+# width = the full-chip layout width
+# height = the full-chip layout height
+# target_dir = location of the full-chip layout
+#
+# -force = overwrite any existing files at the target
+# -outer = width and height are the seal ring outer edge, not the chip area
+# -keep = keep local working directory of results
+#
+# Results:
+# Files advSeal_6um_gen.mag and advSeal_6um_gen.gds are generated and placed in
+# target_dir. advSeal_6um_gen.mag is an "abstract" view that represents the
+# seal ring in diffusion and the nikon cross in metal1, and references
+# the advSeal_6um_gen.gds file in the same directory as a GDS_FILE property.
+#-------------------------------------------------------------------------
+
+import subprocess
+import shutil
+import sys
+import os
+import re
+
+def generate_sealring(width, height, target_dir, force, keep):
+
+ # All files of interest are listed below.
+
+ script = 'generate_gds.tcl'
+ tech = 's8seal_ring.tech'
+ corner = 'seal_ring_corner.mag'
+ abstract = 'seal_ring_corner_abstract.mag'
+ slots = 'sealring_slots.mag'
+ array = 'seal_ring_slots_array.mag'
+ nikon = 'nikon_sealring_shape.mag'
+ polygons = ['sr_polygon00007.mag',
+ 'sr_polygon00027.mag', 'sr_polygon00011.mag', 'sr_polygon00028.mag',
+ 'sr_polygon00001.mag', 'sr_polygon00015.mag', 'sr_polygon00031.mag',
+ 'sr_polygon00002.mag', 'sr_polygon00016.mag', 'sr_polygon00032.mag',
+ 'sr_polygon00003.mag', 'sr_polygon00019.mag', 'sr_polygon00035.mag',
+ 'sr_polygon00004.mag', 'sr_polygon00020.mag', 'sr_polygon00036.mag',
+ 'sr_polygon00005.mag', 'sr_polygon00023.mag', 'sr_polygon00039.mag',
+ 'sr_polygon00006.mag', 'sr_polygon00024.mag']
+
+
+ # Create temporary directory
+ if os.path.exists('temp'):
+ print('temp/ directory exists. Please remove it before running.')
+ sys.exit(0)
+
+ os.makedirs('temp')
+ os.chdir('temp')
+
+ # Copy all .mag files, .magicrc file, and s8seal_ring.tech file to temp/
+ files_to_copy = polygons[:]
+ files_to_copy.append(nikon)
+ files_to_copy.append(slots)
+ files_to_copy.append(array)
+ files_to_copy.append(corner)
+ files_to_copy.append(abstract)
+ files_to_copy.append(tech)
+ files_to_copy.append(script)
+
+ for file in files_to_copy:
+ shutil.copy('../' + file, '.')
+
+ # Seal ring is placed 6um outside of the chip, so add 12um to width and height
+ fwidth = float(width) + 12
+ fheight = float(height) + 12
+
+ dbhwidth = int(fwidth * 100)
+ dbhheight = int(fheight * 100)
+
+ swidth = str(dbhwidth)
+ sheight = str(dbhheight)
+
+ swidthx5 = str(dbhwidth * 5)
+
+ dwidth = str(int(fwidth * 200))
+ dheight = str(int(fheight * 200))
+
+ # Modify every polygon to half width and height
+
+ for file in polygons:
+ with open(file, 'r') as ifile:
+ maglines = ifile.read().splitlines()
+
+ with open(file, 'w') as ofile:
+ for line in maglines:
+ newline = re.sub('51200', swidth, line)
+ newline = re.sub('51210', sheight, newline)
+ # NOTE: polygon 39 is at scale 10, not 2, due to
+ # corner positions of 45 degree angled geometry.
+ newline = re.sub('256000', swidthx5, newline)
+ print(newline, file=ofile)
+
+ # Abstract corner view gets the same treatment
+
+ qwidth = str(int(fwidth * 50))
+ qheight = str(int(fheight * 50))
+
+ with open(abstract, 'r') as ifile:
+ maglines = ifile.read().splitlines()
+
+ with open(abstract, 'w') as ofile:
+ for line in maglines:
+ newline = re.sub('25600', qwidth, line)
+ newline = re.sub('25605', qheight, newline)
+ print(newline, file=ofile)
+
+ # Slots arrays are recalculated to span the width and height
+
+ with open(array, 'r') as ifile:
+ maglines = ifile.read().splitlines()
+
+ slotsX = False
+ with open(array, 'w') as ofile:
+ for line in maglines:
+ newline = line
+ if 'slots_X' in line:
+ slotsX = True
+ elif 'array 0' in line:
+ if slotsX:
+ nslots = int((fwidth - 25.0) / 25.0) - 1
+ newline = 'array 0 ' + str(nslots) + ' 5000 0 0 430'
+ else:
+ nslots = int((fheight - 25.0) / 25.0) - 1
+ newline = 'array 0 ' + str(nslots) + ' 5000 0 0 430'
+
+ print(newline, file=ofile)
+
+ # Corner cell changes bounding boxes to half width and height.
+
+ with open(corner, 'r') as ifile:
+ maglines = ifile.read().splitlines()
+
+ slotsX = False
+ with open(corner, 'w') as ofile:
+ for line in maglines:
+ newline = re.sub('51200', swidth, line)
+ newline = re.sub('51210', sheight, newline)
+ print(newline, file=ofile)
+
+ # Create a new top-level layout called 'advSeal_6um_gen.mag'
+ # Mirrors uses in X and Y, and adds slots arrays at lower left
+ # and upper right
+
+ with open('advSeal_6um_gen.mag', 'w') as ofile:
+ print('magic', file=ofile)
+ print('tech s8seal_ring', file=ofile)
+ print('magscale 1 2', file=ofile)
+ print('timestamp 1584630000', file=ofile)
+
+ # Lower left original
+ print('use seal_ring_corner seal_ring_corner_0', file=ofile)
+ print('timestamp 1584562315', file=ofile)
+ print('transform 1 0 0 0 1 0', file=ofile)
+ print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+ # Mirrored in X
+ print('use seal_ring_corner seal_ring_corner_3', file=ofile)
+ print('timestamp 1584562315', file=ofile)
+ print('transform -1 0 ' + dwidth + ' 0 1 0', file=ofile)
+ print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+ # Mirrored in Y
+ print('use seal_ring_corner seal_ring_corner_1', file=ofile)
+ print('timestamp 1584562315', file=ofile)
+ print('transform 1 0 0 0 -1 ' + dheight, file=ofile)
+ print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+ # Mirrored in both X and Y
+ print('use seal_ring_corner seal_ring_corner_2', file=ofile)
+ print('timestamp 1584562315', file=ofile)
+ print('transform -1 0 ' + dwidth + ' 0 -1 ' + dheight, file=ofile)
+ print('box -30480 -30480 ' + swidth + ' ' + sheight, file=ofile)
+
+ # Lower left slot arrays (bottom and left sides slots)
+ print('use seal_ring_slots_array seal_ring_slots_array_0', file=ofile)
+ print('timestamp 1584629764', file=ofile)
+ print('transform 1 0 0 0 1 0', file=ofile)
+ print('box 285 285 ' + swidth + ' ' + sheight, file=ofile)
+
+ # Upper right slot arrays (top and right sides slots)
+ print('use seal_ring_slots_array seal_ring_slots_array_1', file=ofile)
+ print('timestamp 1584629764', file=ofile)
+ print('transform -1 0 ' + dwidth + ' 0 -1 ' + dheight, file=ofile)
+ print('box 285 285 ' + swidth + ' ' + sheight, file=ofile)
+
+ print('<< end >>', file=ofile)
+
+ # Create a new abstract layout TO BE called 'advSeal_6um_gen.mag'
+ # This is the view in technology EFS8A. Since there is already
+ # a cell with this name that is used to generate GDS, the cell
+ # will be called "seal_ring.mag" and copied to "advSeal_6um_gen.mag"
+ # in the target directory.
+
+ xwidth = str(dbhwidth)
+ xheight = str(dbhheight)
+
+ with open('seal_ring.mag', 'w') as ofile:
+ print('magic', file=ofile)
+ print('tech EFS8A', file=ofile)
+ print('timestamp 1584566829', file=ofile)
+
+ # Lower left original
+ print('use seal_ring_corner_abstract seal_ring_corner_abstract_0', file=ofile)
+ print('timestamp 1584566221', file=ofile)
+ print('transform 1 0 0 0 1 0', file=ofile)
+ print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+ # Mirrored in X
+ print('use seal_ring_corner_abstract seal_ring_corner_abstract_3', file=ofile)
+ print('timestamp 1584566221', file=ofile)
+ print('transform -1 0 ' + xwidth + ' 0 1 0', file=ofile)
+ print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+ # Mirrored in Y
+ print('use seal_ring_corner_abstract seal_ring_corner_abstract_1', file=ofile)
+ print('timestamp 1584566221', file=ofile)
+ print('transform 1 0 0 0 -1 ' + xheight, file=ofile)
+ print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+ # Mirrored in both X and Y
+ print('use seal_ring_corner_abstract seal_ring_corner_abstract_2', file=ofile)
+ print('timestamp 1584566221', file=ofile)
+ print('transform -1 0 ' + xwidth + ' 0 -1 ' + xheight, file=ofile)
+ print('box 0 0 ' + qwidth + ' ' + qheight, file=ofile)
+
+ print('<< properties >>', file=ofile)
+ print('string LEFview no_prefix', file=ofile)
+ print('string GDS_FILE advSeal_6um_gen.gds', file=ofile)
+ print('string GDS_START 0', file=ofile)
+ print('string FIXED_BBOX 0 0 ' + swidth + ' ' + sheight, file=ofile)
+
+ print('<< end >>', file=ofile)
+
+ # Create the GDS of the seal ring
+
+ mproc = subprocess.run(['magic', '-dnull', '-noconsole',
+ 'generate_gds.tcl'],
+ stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE, universal_newlines = True)
+ if mproc.stdout:
+ for line in mproc.stdout.splitlines():
+ print(line)
+ if mproc.stderr:
+ print('Error message output from magic:')
+ for line in mproc.stderr.splitlines():
+ print(line)
+ if mproc.returncode != 0:
+ print('ERROR: Magic exited with status ' + str(mproc.returncode))
+
+ # Copy the GDS file and the abstract view to the target directory
+
+ os.chdir('..')
+
+ if not os.path.exists(target_dir):
+ os.makedirs(target_dir)
+
+ print('Installing files to ' + target_dir)
+ if force or not os.path.exists(target_dir + '/advSeal_6um_gen.gds'):
+ shutil.copy('temp/advSeal_6um_gen.gds', target_dir)
+ else:
+ print('ERROR: advSeal_6um_gen.gds already exists at target! Use -force to overwrite.')
+ if force or not os.path.exists(target_dir + '/advSeal_6um_gen.mag'):
+ shutil.copy('temp/seal_ring.mag', target_dir + '/advSeal_6um_gen.mag')
+ else:
+ print('ERROR: advSeal_6um_gen.mag already exists at target! Use -force to overwrite.')
+ if force or not os.path.exists(target_dir + '/seal_ring_corner_abstract.mag'):
+ shutil.copy('temp/seal_ring_corner_abstract.mag', target_dir)
+ else:
+ print('ERROR: seal_ring_corner_abstract.mag already exists at target! Use -force to overwrite.')
+
+ # Remove the temporary directory and its contents
+
+ if not keep:
+ shutil.rmtree('temp')
+ else:
+ print('Retaining generated files in temp/ directory')
+
+ # Done!
+ print('Done generating files advSeal_6um_gen.gds and advSeal_6um_gen.mag in ' + target_dir)
+ print('Place the seal ring cell in the final layout at (0um, 0um) before generating GDS.')
+ print('The top level layout minus seal ring must have a lower left corner of (6um, 6um)')
+
+# If called as main, run generate_sealring()
+
+if __name__ == '__main__':
+
+ # Divide up command line into options and arguments
+ options = []
+ arguments = []
+ for item in sys.argv[1:]:
+ if item.find('-', 0) == 0:
+ options.append(item)
+ else:
+ arguments.append(item)
+
+ force = True if '-force' in options else False
+ keep = True if '-keep' in options else False
+ outer = True if '-outer' in options else False
+
+ # Need one argument: path to verilog netlist
+ # If two arguments, then 2nd argument is the output file.
+
+ if len(arguments) == 3:
+ width = arguments[0]
+ height = arguments[1]
+ target_dir = arguments[2]
+
+ # Seal ring is 12um thick, so if "outer" option is used, subtract 12um
+ # from both width and height.
+ if outer:
+ width = str(float(width) - 12.0)
+ height = str(float(height) - 12.0)
+
+ generate_sealring(width, height, target_dir, force, keep)
+ else:
+ print("Usage: s8_gen_sealring.py <width> <height> <target_dir> [options]")
+ print("Options:")
+ print(" -outer : Width and height are seal ring outer edge, not chip area")
+ print(" -force : Overwrite any existing files at <target_dir>")
+ print(" -keep : Keep generated files in temp/ directory")
+
+
diff --git a/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech b/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech
new file mode 100644
index 0000000..e5d37f3
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/s8seal_ring.tech
@@ -0,0 +1,506 @@
+tech
+ 30
+ s8seal_ring
+end
+
+version
+ version 0.0
+ description "Auto-generated techfile for unknown GDS read-in"
+end
+
+planes
+ plane11
+ plane20
+ plane21
+ plane22
+ plane23
+ plane25
+ plane27
+ plane28
+ plane30
+ plane32
+ plane34
+ plane35
+ plane36
+ plane37
+ plane39
+ plane40
+ plane41
+ plane43
+ plane44
+ plane46
+ plane48
+ plane49
+ plane50
+ plane51
+ plane56
+ plane58
+ plane59
+ plane61
+ plane65
+ plane81
+ plane88
+ plane96
+ plane97
+ plane98
+end
+
+types
+ plane11 type11
+ plane20 type20
+ plane21 type21
+ plane22 type22
+ plane22 type22_22
+ plane23 type23
+ plane25 type25
+ plane27 type27
+ plane28 type28
+ plane30 type30
+ plane32 type32
+ plane34 type34
+ plane35 type35
+ plane36 type36
+ plane37 type37
+ plane39 type39
+ plane40 type40
+ plane41 type41
+ plane43 type43
+ plane44 type44
+ plane46 type46
+ plane48 type48
+ plane49 type49
+ plane50 type50
+ plane51 type51
+ plane56 type56
+ plane58 type58
+ plane59 type59
+ plane61 type61_20
+ plane65 type65_20
+ plane81 type81_1
+ plane81 type81_51
+ plane81 type81_52
+ plane88 type88
+ plane96 type96
+ plane97 type97
+ plane98 type98
+end
+
+contact
+end
+
+styles
+ styletype mos
+ type11 polysilicon
+ type20 ndiffusion
+ type21 pdiffusion
+ type22 capacitor
+ type22_22 metal1
+ type23 metal2
+ type25 metal3
+ type27 metal4
+ type28 metal5
+ type30 metal6
+ type32 metal7
+ type34 metal8
+ type35 metal9
+ type36 implant1
+ type37 implant2
+ type39 implant3
+ type40 implant4
+ type41 ntransistor
+ type43 ptransistor
+ type44 electrode
+ type46 poly_light
+ type48 mvndiff
+ type49 hvndiff
+ type50 ncontact
+ type51 mvpdiff
+ type56 hvpdiff
+ type58 pcontact
+ type59 poly_resist
+ type61_20 metal10
+ type65_20 mems
+ type81_1 cwell
+ type81_51 cwellnsc
+ type81_52 highvolt_nwell
+ type88 highvolt_pwell
+ type96 nwell
+ type97 pwell
+ type98 poly_light
+end
+
+compose
+end
+
+connect
+end
+
+cifoutput
+style generic
+ scalefactor 1
+
+ layer GDS11 type11
+ labels type11
+ calma 11 0
+
+ layer GDS20 type20
+ labels type20
+ calma 20 0
+
+ layer GDS21 type21
+ labels type21
+ calma 21 0
+
+ layer GDS22 type22
+ labels type22
+ calma 22 0
+
+ layer GDS22_22 type22_22
+ labels type22_22
+ calma 22 22
+
+ layer GDS23 type23
+ labels type23
+ calma 23 0
+
+ layer GDS25 type25
+ labels type25
+ calma 25 0
+
+ layer GDS27 type27
+ labels type27
+ calma 27 0
+
+ layer GDS28 type28
+ labels type28
+ calma 28 0
+
+ layer GDS30 type30
+ labels type30
+ calma 30 0
+
+ layer GDS32 type32
+ labels type32
+ calma 32 0
+
+ layer GDS34 type34
+ labels type34
+ calma 34 0
+
+ layer GDS35 type35
+ labels type35
+ calma 35 0
+
+ layer GDS36 type36
+ labels type36
+ calma 36 0
+
+ layer GDS37 type37
+ labels type37
+ calma 37 0
+
+ layer GDS39 type39
+ labels type39
+ calma 39 0
+
+ layer GDS40 type40
+ labels type40
+ calma 40 0
+
+ layer GDS41 type41
+ labels type41
+ calma 41 0
+
+ layer GDS43 type43
+ labels type43
+ calma 43 0
+
+ layer GDS44 type44
+ labels type44
+ calma 44 0
+
+ layer GDS46 type46
+ labels type46
+ calma 46 0
+
+ layer GDS48 type48
+ labels type48
+ calma 48 0
+
+ layer GDS49 type49
+ labels type49
+ calma 49 0
+
+ layer GDS50 type50
+ labels type50
+ calma 50 0
+
+ layer GDS51 type51
+ labels type51
+ calma 51 0
+
+ layer GDS56 type56
+ labels type56
+ calma 56 0
+
+ layer GDS58 type58
+ labels type58
+ calma 58 0
+
+ layer GDS59 type59
+ labels type59
+ calma 59 0
+
+ layer GDS61_20 type61_20
+ labels type61_20
+ calma 61 20
+
+ layer GDS65_20 type65_20
+ labels type65_20
+ calma 65 20
+
+ layer GDS81_1 type81_1
+ labels type81_1
+ calma 81 1
+
+ layer GDS81_51 type81_51
+ labels type81_51
+ calma 81 51
+
+ layer GDS81_52 type81_52
+ labels type81_52
+ calma 81 52
+
+ layer GDS88 type88
+ labels type88
+ calma 88 0
+
+ layer GDS96 type96
+ labels type96
+ calma 96 0
+
+ layer GDS97 type97
+ labels type97
+ calma 97 0
+
+ layer GDS98 type98
+ labels type98
+ calma 98 0
+
+end
+
+cifinput
+style generic
+ scalefactor 1
+
+ layer type11 GDS11
+ labels GDS11
+
+ layer type20 GDS20
+ labels GDS20
+
+ layer type21 GDS21
+ labels GDS21
+
+ layer type22 GDS22
+ labels GDS22
+
+ layer type22_22 GDS22_22
+ labels GDS22_22
+
+ layer type23 GDS23
+ labels GDS23
+
+ layer type25 GDS25
+ labels GDS25
+
+ layer type27 GDS27
+ labels GDS27
+
+ layer type28 GDS28
+ labels GDS28
+
+ layer type30 GDS30
+ labels GDS30
+
+ layer type32 GDS32
+ labels GDS32
+
+ layer type34 GDS34
+ labels GDS34
+
+ layer type35 GDS35
+ labels GDS35
+
+ layer type36 GDS36
+ labels GDS36
+
+ layer type37 GDS37
+ labels GDS37
+
+ layer type39 GDS39
+ labels GDS39
+
+ layer type40 GDS40
+ labels GDS40
+
+ layer type41 GDS41
+ labels GDS41
+
+ layer type43 GDS43
+ labels GDS43
+
+ layer type44 GDS44
+ labels GDS44
+
+ layer type46 GDS46
+ labels GDS46
+
+ layer type48 GDS48
+ labels GDS48
+
+ layer type49 GDS49
+ labels GDS49
+
+ layer type50 GDS50
+ labels GDS50
+
+ layer type51 GDS51
+ labels GDS51
+
+ layer type56 GDS56
+ labels GDS56
+
+ layer type58 GDS58
+ labels GDS58
+
+ layer type59 GDS59
+ labels GDS59
+
+ layer type61_20 GDS61_20
+ labels GDS61_20
+
+ layer type65_20 GDS65_20
+ labels GDS65_20
+
+ layer type81_1 GDS81_1
+ labels GDS81_1
+
+ layer type81_51 GDS81_51
+ labels GDS81_51
+
+ layer type81_52 GDS81_52
+ labels GDS81_52
+
+ layer type88 GDS88
+ labels GDS88
+
+ layer type96 GDS96
+ labels GDS96
+
+ layer type97 GDS97
+ labels GDS97
+
+ layer type98 GDS98
+ labels GDS98
+
+ calma GDS11 11 0
+ calma GDS20 20 0
+ calma GDS21 21 0
+ calma GDS22 22 0
+ calma GDS22_22 22 22
+ calma GDS23 23 0
+ calma GDS25 25 0
+ calma GDS27 27 0
+ calma GDS28 28 0
+ calma GDS30 30 0
+ calma GDS32 32 0
+ calma GDS34 34 0
+ calma GDS35 35 0
+ calma GDS36 36 0
+ calma GDS37 37 0
+ calma GDS39 39 0
+ calma GDS40 40 0
+ calma GDS41 41 0
+ calma GDS43 43 0
+ calma GDS44 44 0
+ calma GDS46 46 0
+ calma GDS48 48 0
+ calma GDS49 49 0
+ calma GDS50 50 0
+ calma GDS51 51 0
+ calma GDS56 56 0
+ calma GDS58 58 0
+ calma GDS59 59 0
+ calma GDS61_20 61 20
+ calma GDS65_20 65 20
+ calma GDS81_1 81 1
+ calma GDS81_51 81 51
+ calma GDS81_52 81 52
+ calma GDS88 88 0
+ calma GDS96 96 0
+ calma GDS97 97 0
+ calma GDS98 98 0
+end
+
+# mzrouter
+# end
+
+drc
+end
+
+extract
+style generic
+ cscale 1
+ lambda 1
+ step 10
+ sidehalo 0
+
+ planeorder plane11 0
+ planeorder plane20 1
+ planeorder plane21 2
+ planeorder plane22 3
+ planeorder plane23 4
+ planeorder plane25 5
+ planeorder plane27 6
+ planeorder plane28 7
+ planeorder plane30 8
+ planeorder plane32 9
+ planeorder plane34 10
+ planeorder plane35 11
+ planeorder plane36 12
+ planeorder plane37 13
+ planeorder plane39 14
+ planeorder plane40 15
+ planeorder plane41 16
+ planeorder plane43 17
+ planeorder plane44 18
+ planeorder plane46 19
+ planeorder plane48 20
+ planeorder plane49 21
+ planeorder plane50 22
+ planeorder plane51 23
+ planeorder plane56 24
+ planeorder plane58 25
+ planeorder plane59 26
+ planeorder plane61 27
+ planeorder plane65 28
+ planeorder plane81 29
+ planeorder plane88 30
+ planeorder plane96 31
+ planeorder plane97 32
+ planeorder plane98 33
+end
+
+# wiring
+# end
+
+# router
+# end
+
+# plowing
+# end
+
+plot
+ style pnm
+end
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag
new file mode 100644
index 0000000..e15ffc8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner.mag
@@ -0,0 +1,68 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584562315
+<< type81_52 >>
+rect 0 20320 20320 51210
+rect 0 0 51200 20320
+use sr_polygon00028 sr_polygon00028_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 650 2369 710 51210
+use sr_polygon00024 sr_polygon00024_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 530 2319 590 51210
+use sr_polygon00020 sr_polygon00020_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 410 2269 470 51210
+use sr_polygon00016 sr_polygon00016_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 290 2219 350 51210
+use sr_polygon00032 sr_polygon00032_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 2099 1000 51210
+use sr_polygon00031 sr_polygon00031_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 650 650 51200 2394
+use sr_polygon00027 sr_polygon00027_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 530 530 51200 2344
+use sr_polygon00023 sr_polygon00023_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 410 410 51200 2294
+use sr_polygon00019 sr_polygon00019_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 290 290 51200 2244
+use nikon_sealring_shape nikon_sealring_shape_0
+timestamp 1584558468
+transform 1 0 200 0 1 200
+box 0 0 800 800
+use sr_polygon00036 sr_polygon00036_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 1200 51210
+use sr_polygon00015 sr_polygon00015_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box 0 0 2099 2099
+use sr_polygon00035 sr_polygon00035_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 51200 2514
+use sr_polygon00039 sr_polygon00039_0
+timestamp 1584558827
+transform 1 0 0 0 1 0
+box 0 0 51200 2597
+use sr_polygon00011 sr_polygon00011_0
+timestamp 1584558468
+transform 1 0 0 0 1 0
+box -30480 -30480 30480 30480
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag
new file mode 100644
index 0000000..1477b9c
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_corner_abstract.mag
@@ -0,0 +1,27 @@
+magic
+tech EFS8A
+timestamp 1584566221
+<< psubstratepdiff >>
+rect 145 1110 355 25605
+tri 145 900 355 1110 ne
+tri 355 900 652 1197 sw
+tri 355 652 603 900 ne
+rect 603 652 652 900
+tri 652 652 900 900 sw
+tri 603 355 900 652 ne
+tri 900 355 1197 652 sw
+tri 900 145 1110 355 ne
+rect 1110 145 25600 355
+<< locali >>
+tri 100 383 217 500 se
+rect 217 383 383 500
+tri 383 383 500 500 sw
+rect 100 217 500 383
+tri 100 100 217 217 ne
+rect 217 100 383 217
+tri 383 100 500 217 nw
+<< metal1 >>
+rect 275 325 325 420
+rect 180 275 420 325
+rect 275 180 325 275
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag b/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag
new file mode 100644
index 0000000..f38f77c
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/seal_ring_slots_array.mag
@@ -0,0 +1,15 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584629764
+use sealring_slots sealring_slots_Y
+array 0 7 5000 0 0 430
+timestamp 1584628639
+transform 0 -1 1000 1 0 -7000
+box 9500 285 12200 715
+use sealring_slots sealring_slots_X
+array 0 7 5000 0 0 430
+timestamp 1584628639
+transform 1 0 -7000 0 1 0
+box 9500 285 12200 715
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag b/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag
new file mode 100644
index 0000000..c3ee669
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sealring_slots.mag
@@ -0,0 +1,13 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584628639
+<< checkpaint >>
+rect 6900 285 7100 355
+rect 9500 285 9700 355
+<< type22_22 >>
+rect 12000 645 12200 715
+rect 9500 525 9700 595
+rect 12000 405 12200 475
+rect 9500 285 9700 355
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag
new file mode 100644
index 0000000..e7c32b8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00001.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type48 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag
new file mode 100644
index 0000000..51355fa
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00002.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type25 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag
new file mode 100644
index 0000000..7c2dd29
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00003.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type20 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag
new file mode 100644
index 0000000..7721108
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00004.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type39 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag
new file mode 100644
index 0000000..27e8081
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00005.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type11 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag
new file mode 100644
index 0000000..8b44cb9
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00006.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type49 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag
new file mode 100644
index 0000000..89547c6
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00007.mag
@@ -0,0 +1,21 @@
+magic
+tech s8seal_ring
+timestamp 1584558468
+<< type37 >>
+tri 0 283 117 400 se
+rect 117 320 283 400
+rect 117 283 175 320
+rect 0 225 175 283
+rect 225 283 283 320
+tri 283 283 400 400 sw
+rect 225 225 400 283
+rect 0 175 80 225
+rect 320 175 400 225
+rect 0 117 175 175
+tri 0 0 117 117 ne
+rect 117 80 175 117
+rect 225 117 400 175
+rect 225 80 283 117
+rect 117 0 283 80
+tri 283 0 400 117 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag
new file mode 100644
index 0000000..47854ae
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00011.mag
@@ -0,0 +1,99 @@
+magic
+tech s8seal_ring
+magscale 1 10
+timestamp 1584558468
+<< type81_51 >>
+tri -14938 151666 0 152400 se
+tri 0 151666 14938 152400 sw
+tri -29732 149472 -14938 151666 se
+rect -14938 149472 14938 151666
+tri 14938 149472 29732 151666 sw
+tri -44239 145838 -29732 149472 se
+rect -29732 145838 29732 149472
+tri 29732 145838 44239 149472 sw
+tri -58321 140799 -44239 145838 se
+rect -44239 140799 44239 145838
+tri 44239 140799 58321 145838 sw
+tri -71841 134405 -58321 140799 se
+rect -58321 134405 58321 140799
+tri 58321 134405 71841 140799 sw
+tri -84669 126716 -71841 134405 se
+rect -71841 126716 71841 134405
+tri 71841 126716 84669 134405 sw
+tri -96682 117807 -84669 126716 se
+rect -84669 117807 84669 126716
+tri 84669 117807 96682 126716 sw
+tri -107763 107763 -96682 117807 se
+rect -96682 107763 96682 117807
+tri 96682 107763 107763 117807 sw
+tri -117807 96682 -107763 107763 se
+rect -107763 96682 107763 107763
+tri 107763 96682 117807 107763 sw
+tri -126716 84669 -117807 96682 se
+rect -117807 84669 117807 96682
+tri 117807 84669 126716 96682 sw
+tri -134405 71841 -126716 84669 se
+rect -126716 71841 126716 84669
+tri 126716 71841 134405 84669 sw
+tri -140799 58321 -134405 71841 se
+rect -134405 58321 134405 71841
+tri 134405 58321 140799 71841 sw
+tri -145838 44239 -140799 58321 se
+rect -140799 44239 140799 58321
+tri 140799 44239 145838 58321 sw
+tri -149472 29732 -145838 44239 se
+rect -145838 29732 145838 44239
+tri 145838 29732 149472 44239 sw
+tri -151666 14938 -149472 29732 se
+rect -149472 14938 149472 29732
+tri 149472 14938 151666 29732 sw
+tri -152400 0 -151666 14938 se
+tri -152400 -14938 -151666 0 ne
+rect -151666 -14938 151666 14938
+tri 151666 0 152400 14938 sw
+tri 151666 -14938 152400 0 nw
+tri -151666 -29732 -149472 -14938 ne
+rect -149472 -29732 149472 -14938
+tri 149472 -29732 151666 -14938 nw
+tri -149472 -44239 -145838 -29732 ne
+rect -145838 -44239 145838 -29732
+tri 145838 -44239 149472 -29732 nw
+tri -145838 -58321 -140799 -44239 ne
+rect -140799 -58321 140799 -44239
+tri 140799 -58321 145838 -44239 nw
+tri -140799 -71841 -134405 -58321 ne
+rect -134405 -71841 134405 -58321
+tri 134405 -71841 140799 -58321 nw
+tri -134405 -84669 -126716 -71841 ne
+rect -126716 -84669 126716 -71841
+tri 126716 -84669 134405 -71841 nw
+tri -126716 -96682 -117807 -84669 ne
+rect -117807 -96682 117807 -84669
+tri 117807 -96682 126716 -84669 nw
+tri -117807 -107763 -107763 -96682 ne
+rect -107763 -107763 107763 -96682
+tri 107763 -107763 117807 -96682 nw
+tri -107763 -117807 -96682 -107763 ne
+rect -96682 -117807 96682 -107763
+tri 96682 -117807 107763 -107763 nw
+tri -96682 -126716 -84669 -117807 ne
+rect -84669 -126716 84669 -117807
+tri 84669 -126716 96682 -117807 nw
+tri -84669 -134405 -71841 -126716 ne
+rect -71841 -134405 71841 -126716
+tri 71841 -134405 84669 -126716 nw
+tri -71841 -140799 -58321 -134405 ne
+rect -58321 -140799 58321 -134405
+tri 58321 -140799 71841 -134405 nw
+tri -58321 -145838 -44239 -140799 ne
+rect -44239 -145838 44239 -140799
+tri 44239 -145838 58321 -140799 nw
+tri -44239 -149472 -29732 -145838 ne
+rect -29732 -149472 29732 -145838
+tri 29732 -149472 44239 -145838 nw
+tri -29732 -151666 -14938 -149472 ne
+rect -14938 -151666 14938 -149472
+tri 14938 -151666 29732 -149472 nw
+tri -14938 -152400 0 -151666 ne
+tri 0 -152400 14938 -151666 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag
new file mode 100644
index 0000000..d91c7fb
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00015.mag
@@ -0,0 +1,15 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558468
+<< type37 >>
+tri 0 1000 1099 2099 sw
+rect 0 200 200 1000
+tri 200 766 434 1000 nw
+tri 766 766 1000 1000 ne
+tri 200 200 434 434 sw
+tri 766 200 1000 434 se
+rect 1000 200 1099 1000
+rect 0 0 1099 200
+tri 1099 0 2099 1000 sw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag
new file mode 100644
index 0000000..7aa89fc
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00016.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 290 2244 350 51210
+tri 290 2219 350 2244 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag
new file mode 100644
index 0000000..b316735
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00019.mag
@@ -0,0 +1,55 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 290 2219 350 2244 se
+tri 350 2219 375 2244 sw
+tri 290 2134 375 2219 ne
+tri 375 2134 460 2219 sw
+tri 375 2049 460 2134 ne
+tri 460 2049 545 2134 sw
+tri 460 1964 545 2049 ne
+tri 545 1964 630 2049 sw
+tri 545 1879 630 1964 ne
+tri 630 1879 715 1964 sw
+tri 630 1794 715 1879 ne
+tri 715 1794 800 1879 sw
+tri 715 1709 800 1794 ne
+tri 800 1709 885 1794 sw
+tri 800 1624 885 1709 ne
+tri 885 1624 970 1709 sw
+tri 885 1539 970 1624 ne
+tri 970 1539 1055 1624 sw
+tri 970 1454 1055 1539 ne
+tri 1055 1454 1140 1539 sw
+tri 1055 1369 1140 1454 ne
+tri 1140 1369 1225 1454 sw
+tri 1140 1284 1225 1369 ne
+tri 1225 1284 1310 1369 sw
+tri 1225 1199 1310 1284 ne
+tri 1310 1199 1395 1284 sw
+tri 1310 1114 1395 1199 ne
+tri 1395 1114 1480 1199 sw
+tri 1395 1029 1480 1114 ne
+tri 1480 1029 1565 1114 sw
+tri 1480 944 1565 1029 ne
+tri 1565 944 1650 1029 sw
+tri 1565 859 1650 944 ne
+tri 1650 859 1735 944 sw
+tri 1650 774 1735 859 ne
+tri 1735 774 1820 859 sw
+tri 1735 689 1820 774 ne
+tri 1820 689 1905 774 sw
+tri 1820 604 1905 689 ne
+tri 1905 604 1990 689 sw
+tri 1905 519 1990 604 ne
+tri 1990 519 2075 604 sw
+tri 1990 434 2075 519 ne
+tri 2075 434 2160 519 sw
+tri 2075 349 2160 434 ne
+tri 2160 350 2244 434 sw
+rect 2160 349 51200 350
+tri 2160 290 2219 349 ne
+rect 2219 290 51200 349
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag
new file mode 100644
index 0000000..9e328f8
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00020.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 410 2294 470 51210
+tri 410 2269 470 2294 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag
new file mode 100644
index 0000000..fe8335d
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00023.mag
@@ -0,0 +1,54 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 410 2269 470 2294 se
+tri 470 2269 495 2294 sw
+tri 410 2184 495 2269 ne
+tri 495 2184 580 2269 sw
+tri 495 2099 580 2184 ne
+tri 580 2099 665 2184 sw
+tri 580 2014 665 2099 ne
+tri 665 2014 750 2099 sw
+tri 665 1929 750 2014 ne
+tri 750 1929 835 2014 sw
+tri 750 1844 835 1929 ne
+tri 835 1844 920 1929 sw
+tri 835 1759 920 1844 ne
+tri 920 1759 1005 1844 sw
+tri 920 1674 1005 1759 ne
+tri 1005 1674 1090 1759 sw
+tri 1005 1589 1090 1674 ne
+tri 1090 1589 1175 1674 sw
+tri 1090 1504 1175 1589 ne
+tri 1175 1504 1260 1589 sw
+tri 1175 1419 1260 1504 ne
+tri 1260 1419 1345 1504 sw
+tri 1260 1334 1345 1419 ne
+tri 1345 1334 1430 1419 sw
+tri 1345 1249 1430 1334 ne
+tri 1430 1249 1515 1334 sw
+tri 1430 1164 1515 1249 ne
+tri 1515 1164 1600 1249 sw
+tri 1515 1079 1600 1164 ne
+tri 1600 1079 1685 1164 sw
+tri 1600 994 1685 1079 ne
+tri 1685 994 1770 1079 sw
+tri 1685 909 1770 994 ne
+tri 1770 909 1855 994 sw
+tri 1770 824 1855 909 ne
+tri 1855 824 1940 909 sw
+tri 1855 739 1940 824 ne
+tri 1940 739 2025 824 sw
+tri 1940 654 2025 739 ne
+tri 2025 654 2110 739 sw
+tri 2025 569 2110 654 ne
+tri 2110 569 2195 654 sw
+tri 2110 484 2195 569 ne
+tri 2195 484 2280 569 sw
+tri 2195 410 2269 484 ne
+rect 2269 470 2280 484
+tri 2280 470 2294 484 sw
+rect 2269 410 51200 470
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag
new file mode 100644
index 0000000..eb9f364
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00024.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 530 2344 590 51210
+tri 530 2319 590 2344 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag
new file mode 100644
index 0000000..c6d2ad1
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00027.mag
@@ -0,0 +1,53 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 530 2319 590 2344 se
+tri 590 2319 615 2344 sw
+tri 530 2234 615 2319 ne
+tri 615 2234 700 2319 sw
+tri 615 2149 700 2234 ne
+tri 700 2149 785 2234 sw
+tri 700 2064 785 2149 ne
+tri 785 2064 870 2149 sw
+tri 785 1979 870 2064 ne
+tri 870 1979 955 2064 sw
+tri 870 1894 955 1979 ne
+tri 955 1894 1040 1979 sw
+tri 955 1809 1040 1894 ne
+tri 1040 1809 1125 1894 sw
+tri 1040 1724 1125 1809 ne
+tri 1125 1724 1210 1809 sw
+tri 1125 1639 1210 1724 ne
+tri 1210 1639 1295 1724 sw
+tri 1210 1554 1295 1639 ne
+tri 1295 1554 1380 1639 sw
+tri 1295 1469 1380 1554 ne
+tri 1380 1469 1465 1554 sw
+tri 1380 1384 1465 1469 ne
+tri 1465 1384 1550 1469 sw
+tri 1465 1299 1550 1384 ne
+tri 1550 1299 1635 1384 sw
+tri 1550 1214 1635 1299 ne
+tri 1635 1214 1720 1299 sw
+tri 1635 1129 1720 1214 ne
+tri 1720 1129 1805 1214 sw
+tri 1720 1044 1805 1129 ne
+tri 1805 1044 1890 1129 sw
+tri 1805 959 1890 1044 ne
+tri 1890 959 1975 1044 sw
+tri 1890 874 1975 959 ne
+tri 1975 874 2060 959 sw
+tri 1975 789 2060 874 ne
+tri 2060 789 2145 874 sw
+tri 2060 704 2145 789 ne
+tri 2145 704 2230 789 sw
+tri 2145 619 2230 704 ne
+tri 2230 619 2315 704 sw
+tri 2230 534 2315 619 ne
+tri 2315 590 2344 619 sw
+rect 2315 534 51200 590
+tri 2315 530 2319 534 ne
+rect 2319 530 51200 534
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag
new file mode 100644
index 0000000..3db918a
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00028.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+rect 650 2394 710 51210
+tri 650 2369 710 2394 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag
new file mode 100644
index 0000000..1eb8648
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00031.mag
@@ -0,0 +1,51 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type65_20 >>
+tri 650 2369 710 2394 se
+tri 710 2369 735 2394 sw
+tri 650 2284 735 2369 ne
+tri 735 2284 820 2369 sw
+tri 735 2199 820 2284 ne
+tri 820 2199 905 2284 sw
+tri 820 2114 905 2199 ne
+tri 905 2114 990 2199 sw
+tri 905 2029 990 2114 ne
+tri 990 2029 1075 2114 sw
+tri 990 1944 1075 2029 ne
+tri 1075 1944 1160 2029 sw
+tri 1075 1859 1160 1944 ne
+tri 1160 1859 1245 1944 sw
+tri 1160 1774 1245 1859 ne
+tri 1245 1774 1330 1859 sw
+tri 1245 1689 1330 1774 ne
+tri 1330 1689 1415 1774 sw
+tri 1330 1604 1415 1689 ne
+tri 1415 1604 1500 1689 sw
+tri 1415 1519 1500 1604 ne
+tri 1500 1519 1585 1604 sw
+tri 1500 1434 1585 1519 ne
+tri 1585 1434 1670 1519 sw
+tri 1585 1349 1670 1434 ne
+tri 1670 1349 1755 1434 sw
+tri 1670 1264 1755 1349 ne
+tri 1755 1264 1840 1349 sw
+tri 1755 1179 1840 1264 ne
+tri 1840 1179 1925 1264 sw
+tri 1840 1094 1925 1179 ne
+tri 1925 1094 2010 1179 sw
+tri 1925 1009 2010 1094 ne
+tri 2010 1009 2095 1094 sw
+tri 2010 924 2095 1009 ne
+tri 2095 924 2180 1009 sw
+tri 2095 839 2180 924 ne
+tri 2180 839 2265 924 sw
+tri 2180 754 2265 839 ne
+tri 2265 754 2350 839 sw
+tri 2265 669 2350 754 ne
+tri 2350 710 2394 754 sw
+rect 2350 669 51200 710
+tri 2350 650 2369 669 ne
+rect 2369 650 51200 669
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag
new file mode 100644
index 0000000..395db17
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00032.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type61_20 >>
+rect 0 2514 1000 51210
+tri 0 2099 1000 2514 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag
new file mode 100644
index 0000000..934e4e1
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00035.mag
@@ -0,0 +1,13 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type61_20 >>
+tri 0 2099 1000 2514 se
+tri 1000 2099 1415 2514 sw
+tri 0 684 1415 2099 ne
+tri 1415 1000 2514 2099 sw
+rect 1415 684 51200 1000
+tri 1415 0 2099 684 ne
+rect 2099 0 51200 684
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag
new file mode 100644
index 0000000..7e944a4
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00036.mag
@@ -0,0 +1,8 @@
+magic
+tech s8seal_ring
+magscale 1 2
+timestamp 1584558827
+<< type81_1 >>
+rect 0 2597 1200 51210
+tri 0 0 1200 2597 nw
+<< end >>
diff --git a/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag b/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag
new file mode 100644
index 0000000..24dfe83
--- /dev/null
+++ b/sky130/custom/scripts/seal_ring_generator/sr_polygon00039.mag
@@ -0,0 +1,10 @@
+magic
+tech s8seal_ring
+magscale 1 10
+timestamp 1584558827
+<< type81_1 >>
+tri 2772 6000 6000 12985 se
+tri 6000 6000 12985 12985 sw
+tri 0 0 2772 5999 se
+rect 2772 0 256000 6000
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/README b/sky130/custom/sky130_fd_io/README
new file mode 100644
index 0000000..edffb27
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/README
@@ -0,0 +1,20 @@
+This directory contains standard format files for "power_pads_lib",
+which is an efabless addendum to the SkyWater I/O library "s8iom0".
+
+power_pads_lib does the following:
+
+(1) Changes the orientation of the corner pad from upper-right to
+ lower-left with a wrapper cell called "s8iom0_corner_pad". Also
+ extends the power buses to make the dimensions of the corner pad
+ multiples of 1um.
+
+(2) Adds a 1um-wide spacer cell to complement the existing 5um-wide
+ spacer cell.
+
+(3) Adds wrappers for all the combinations of power pad base cell +
+ power pad overlay, to create all 12 combinations, for pads with
+ either high- or low-voltage clamps, connecting to one of the six
+ power domains vddio, vdda, vccd, vssio, vssa, or vssd.
+
+"power_pads_lib" is open source copyright 2019 efabless, Inc.
+Released under Apache 2.0 license
diff --git a/sky130/custom/sky130_fd_io/cdl/power_pads_lib.cdl b/sky130/custom/sky130_fd_io/cdl/power_pads_lib.cdl
new file mode 100644
index 0000000..538405f
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/cdl/power_pads_lib.cdl
@@ -0,0 +1,92 @@
+* Power pads library (s8 power pads + overlays)
+* Includes corner and fill cell subcircuits
+
+.SUBCKT s8iom0_vdda_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vdda_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vddio_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vddio_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vccd_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vccd_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssa_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssa_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssio_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssio_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssd_hvc_pad
++ amuxbus_a amuxbus_b drn_hvc src_bdy_hvc
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_vssd_lvc_pad
++ amuxbus_a amuxbus_b drn_lvc1 drn_lvc2 src_bdy_lvc1 src_bdy_lvc2
++ bdy2_b2b vssi
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_corner_pad
++ amuxbus_a amuxbus_b
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0s8_com_bus_slice
++ amuxbus_a amuxbus_b
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0s8_com_bus_slice_1um
++ amuxbus_a amuxbus_b
++ vssa vdda vswitch vddio_q vcchib vddio vccd vssio vssd vssio_q
+.ENDS
+
+.SUBCKT s8iom0_gpiov2_pad
++ in_h pad_a_noesd_h pad_a_esd_0_h pad_a_esd_1_h
++ pad dm<2> dm<1> dm<0> hld_h_n in inp_dis ib_mode_sel enable_h enable_vdda_h
++ enable_inp_h oe_n tie_hi_esd tie_lo_esd slow vtrip_sel hld_ovr
++ analog_en analog_sel enable_vddio enable_vswitch_h analog_pol out
++ amuxbus_a amuxbus_b vssa vdda vswitch vddio_q vcchib vddio vccd vssio
++ vssd vssio_q
+.ENDS
diff --git a/sky130/custom/sky130_fd_io/gds/power_pads_lib.gds b/sky130/custom/sky130_fd_io/gds/power_pads_lib.gds
new file mode 100644
index 0000000..da0dc4d
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/gds/power_pads_lib.gds
Binary files differ
diff --git a/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef b/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef
new file mode 100644
index 0000000..1ff3c03
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/lef/power_pads_lib.lef
@@ -0,0 +1,5391 @@
+VERSION 5.3 ;
+ NAMESCASESENSITIVE ON ;
+ NOWIREEXTENSIONATPIN ON ;
+ DIVIDERCHAR "/" ;
+ BUSBITCHARS "[]" ;
+UNITS
+ DATABASE MICRONS 1000 ;
+END UNITS
+
+MACRO s8iom0_gpiov2_pad
+ CLASS PAD INOUT ;
+ FOREIGN s8iom0_gpiov2_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 80.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 36.4400 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 38.7600 51.0900 80.0000 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 52.1450 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 54.4650 46.3300 80.0000 49.3100 ;
+ END
+ END amuxbus_b
+ PIN analog_en
+ PORT
+ LAYER met1 ;
+ RECT 62.4300 -2.0350 62.6900 -0.7300 ;
+ END
+ END analog_en
+ PIN analog_pol
+ PORT
+ LAYER met3 ;
+ RECT 45.8650 -2.0350 46.1950 34.7700 ;
+ END
+ END analog_pol
+ PIN analog_sel
+ PORT
+ LAYER met2 ;
+ RECT 30.7500 -2.0350 31.0100 0.2300 ;
+ END
+ END analog_sel
+ PIN dm<2>
+ PORT
+ LAYER met2 ;
+ RECT 28.4900 -2.0350 28.7500 2.0350 ;
+ END
+ END dm<2>
+ PIN dm<1>
+ PORT
+ LAYER met2 ;
+ RECT 66.8350 -2.0350 67.0950 -0.8400 ;
+ END
+ END dm<1>
+ PIN dm<0>
+ PORT
+ LAYER met2 ;
+ RECT 49.8550 -2.0350 50.1150 -1.4900 ;
+ END
+ END dm<0>
+ PIN enable_h
+ PORT
+ LAYER met2 ;
+ RECT 35.4600 -2.0350 35.7200 -0.4850 ;
+ END
+ END enable_h
+ PIN enable_inp_h
+ PORT
+ LAYER met2 ;
+ RECT 38.3900 -2.0350 38.6500 1.0550 ;
+ END
+ END enable_inp_h
+ PIN enable_vdda_h
+ PORT
+ LAYER met2 ;
+ RECT 12.7550 -2.0350 13.0150 3.3150 ;
+ END
+ END enable_vdda_h
+ PIN enable_vddio
+ PORT
+ LAYER met3 ;
+ RECT 78.5800 -2.0350 78.9100 182.7400 ;
+ END
+ END enable_vddio
+ PIN enable_vswitch_h
+ PORT
+ LAYER met2 ;
+ RECT 16.3100 -2.0350 16.5700 0.2850 ;
+ END
+ END enable_vswitch_h
+ PIN hld_h_n
+ PORT
+ LAYER met2 ;
+ RECT 31.8150 -2.0350 32.0750 1.3050 ;
+ END
+ END hld_h_n
+ PIN hld_ovr
+ PORT
+ LAYER met2 ;
+ RECT 26.6000 -2.0350 26.8600 0.6700 ;
+ END
+ END hld_ovr
+ PIN ib_mode_sel
+ PORT
+ LAYER met2 ;
+ RECT 5.4200 -2.0350 5.6500 2.4400 ;
+ END
+ END ib_mode_sel
+ PIN in
+ PORT
+ LAYER met3 ;
+ RECT 79.2400 -2.0350 79.5700 187.5250 ;
+ END
+ END in
+ PIN in_h
+ PORT
+ LAYER met3 ;
+ RECT 0.4000 -2.0350 1.0200 176.4500 ;
+ END
+ END in_h
+ PIN inp_dis
+ PORT
+ LAYER met2 ;
+ RECT 45.2450 -2.0350 45.5050 3.0550 ;
+ END
+ END inp_dis
+ PIN oe_n
+ PORT
+ LAYER met2 ;
+ RECT 3.3750 -2.0350 3.6050 2.4400 ;
+ END
+ END oe_n
+ PIN out
+ PORT
+ LAYER met2 ;
+ RECT 22.3550 -2.0350 22.6150 4.3900 ;
+ END
+ END out
+ PIN pad
+ PORT
+ LAYER met5 ;
+ RECT 11.2000 102.5250 73.8000 164.9750 ;
+ END
+ END pad
+ PIN pad_a_esd_0_h
+ PORT
+ LAYER met2 ;
+ RECT 76.2800 -2.0350 76.9200 0.0200 ;
+ END
+ END pad_a_esd_0_h
+ PIN pad_a_esd_1_h
+ PORT
+ LAYER met2 ;
+ RECT 68.2750 -2.0350 68.9250 0.2350 ;
+ END
+ END pad_a_esd_1_h
+ PIN pad_a_noesd_h
+ PORT
+ LAYER met3 ;
+ RECT 62.8200 -2.0350 63.8900 7.6700 ;
+ END
+ END pad_a_noesd_h
+ PIN slow
+ PORT
+ LAYER met2 ;
+ RECT 77.6100 -2.0350 77.8700 -0.8500 ;
+ END
+ END slow
+ PIN tie_hi_esd
+ PORT
+ LAYER met2 ;
+ RECT 78.7050 -2.0350 78.9050 -0.8200 ;
+ END
+ END tie_hi_esd
+ PIN tie_lo_esd
+ PORT
+ LAYER met2 ;
+ RECT 79.7150 -2.0350 79.9150 175.8350 ;
+ END
+ END tie_lo_esd
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 6.9500 80.0000 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 6.8500 80.0000 11.5000 ;
+ END
+ END vccd
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 0.1000 80.0000 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 0.0000 80.0000 5.4500 ;
+ END
+ END vcchib
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.9700 13.0000 80.0000 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.9700 12.9000 80.0000 16.3500 ;
+ END
+ END vdda
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 68.0000 80.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 17.8500 80.0000 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 17.7500 80.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 68.0000 80.0000 92.9650 ;
+ END
+ END vddio
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 62.1500 80.0000 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 62.0500 80.0000 66.5000 ;
+ END
+ END vddio_q
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 2.6100 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 2.6100 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 45.7000 80.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 34.8050 80.0000 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 49.6100 80.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 47.0900 54.3700 80.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 47.0900 45.7000 80.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 34.7000 80.0000 38.1500 ;
+ END
+ END vssa
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 39.6500 80.0000 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 39.5500 80.0000 44.2000 ;
+ END
+ END vssd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 0.8100 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.9700 173.7500 80.0000 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 23.9000 80.0000 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 23.8000 80.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 173.7500 80.0000 197.9650 ;
+ END
+ END vssio
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 56.3000 80.0000 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 56.2000 80.0000 60.6500 ;
+ END
+ END vssio_q
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 78.7300 29.9500 80.0000 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 78.7300 29.8500 80.0000 33.3000 ;
+ END
+ END vswitch
+ PIN vtrip_sel
+ PORT
+ LAYER met2 ;
+ RECT 6.1300 -2.0350 6.3900 -0.4850 ;
+ END
+ END vtrip_sel
+ OBS
+ LAYER li1 ;
+ RECT -0.1600 -1.8050 80.1600 197.6700 ;
+ LAYER met1 ;
+ RECT -0.1450 -0.4500 80.1450 197.9650 ;
+ RECT -0.1450 -1.7750 62.1500 -0.4500 ;
+ RECT 62.9700 -1.7750 80.1450 -0.4500 ;
+ LAYER met2 ;
+ RECT 0.2100 176.1150 79.9150 197.9650 ;
+ RECT 0.2100 4.6700 79.4350 176.1150 ;
+ RECT 0.2100 3.5950 22.0750 4.6700 ;
+ RECT 0.2100 2.7200 12.4750 3.5950 ;
+ RECT 0.2100 -1.7850 3.0950 2.7200 ;
+ RECT 3.8850 -1.7850 5.1400 2.7200 ;
+ RECT 5.9300 -0.2050 12.4750 2.7200 ;
+ RECT 6.6700 -1.7850 12.4750 -0.2050 ;
+ RECT 13.2950 0.5650 22.0750 3.5950 ;
+ RECT 13.2950 -1.7850 16.0300 0.5650 ;
+ RECT 16.8500 -1.7850 22.0750 0.5650 ;
+ RECT 22.8950 3.3350 79.4350 4.6700 ;
+ RECT 22.8950 2.3150 44.9650 3.3350 ;
+ RECT 22.8950 0.9500 28.2100 2.3150 ;
+ RECT 22.8950 -1.7850 26.3200 0.9500 ;
+ RECT 27.1400 -1.7850 28.2100 0.9500 ;
+ RECT 29.0300 1.5850 44.9650 2.3150 ;
+ RECT 29.0300 0.5100 31.5350 1.5850 ;
+ RECT 29.0300 -1.7850 30.4700 0.5100 ;
+ RECT 31.2900 -1.7850 31.5350 0.5100 ;
+ RECT 32.3550 1.3350 44.9650 1.5850 ;
+ RECT 32.3550 -0.2050 38.1100 1.3350 ;
+ RECT 32.3550 -1.7850 35.1800 -0.2050 ;
+ RECT 36.0000 -1.7850 38.1100 -0.2050 ;
+ RECT 38.9300 -1.7850 44.9650 1.3350 ;
+ RECT 45.7850 0.5150 79.4350 3.3350 ;
+ RECT 45.7850 -0.5600 67.9950 0.5150 ;
+ RECT 45.7850 -1.2100 66.5550 -0.5600 ;
+ RECT 45.7850 -1.7850 49.5750 -1.2100 ;
+ RECT 50.3950 -1.7850 66.5550 -1.2100 ;
+ RECT 67.3750 -1.7850 67.9950 -0.5600 ;
+ RECT 69.2050 0.3000 79.4350 0.5150 ;
+ RECT 69.2050 -1.7850 76.0000 0.3000 ;
+ RECT 77.2000 -0.5400 79.4350 0.3000 ;
+ RECT 77.2000 -0.5700 78.4250 -0.5400 ;
+ RECT 77.2000 -1.7850 77.3300 -0.5700 ;
+ RECT 78.1500 -1.7850 78.4250 -0.5700 ;
+ RECT 79.1850 -1.7850 79.4350 -0.5400 ;
+ LAYER met3 ;
+ RECT 0.4000 187.9250 79.5700 197.9650 ;
+ RECT 0.4000 183.1400 78.8400 187.9250 ;
+ RECT 0.4000 176.8500 78.1800 183.1400 ;
+ RECT 1.4200 35.1700 78.1800 176.8500 ;
+ RECT 1.4200 -1.7900 45.4650 35.1700 ;
+ RECT 46.5950 8.0700 78.1800 35.1700 ;
+ RECT 46.5950 -1.7900 62.4200 8.0700 ;
+ RECT 64.2900 -1.7900 78.1800 8.0700 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 78.3300 197.9650 ;
+ RECT 0.9650 93.3650 78.9700 173.3500 ;
+ RECT 1.6700 67.6000 78.3300 93.3650 ;
+ RECT 0.9650 66.9000 78.9700 67.6000 ;
+ RECT 1.6700 61.6500 78.3300 66.9000 ;
+ RECT 0.9650 61.0500 78.9700 61.6500 ;
+ RECT 1.6700 55.8000 78.3300 61.0500 ;
+ RECT 0.9650 55.1000 78.9700 55.8000 ;
+ RECT 3.0100 54.4700 46.6900 55.1000 ;
+ RECT 36.8400 50.6900 38.3600 54.4700 ;
+ RECT 1.6700 49.7100 78.3300 50.6900 ;
+ RECT 52.5450 46.4300 54.0650 49.7100 ;
+ RECT 3.0100 45.3000 46.6900 45.9300 ;
+ RECT 0.9650 44.6000 78.9700 45.3000 ;
+ RECT 1.6700 39.1500 78.3300 44.6000 ;
+ RECT 0.9650 38.5500 78.9700 39.1500 ;
+ RECT 1.6700 34.3000 78.3300 38.5500 ;
+ RECT 0.9650 33.7000 78.9700 34.3000 ;
+ RECT 1.6700 29.4500 78.3300 33.7000 ;
+ RECT 0.9650 28.8500 78.9700 29.4500 ;
+ RECT 1.6700 23.4000 78.3300 28.8500 ;
+ RECT 0.9650 22.8000 78.9700 23.4000 ;
+ RECT 1.6700 17.3500 78.3300 22.8000 ;
+ RECT 0.9650 16.7500 78.9700 17.3500 ;
+ RECT 1.3650 12.5000 78.5700 16.7500 ;
+ RECT 0.9650 11.9000 78.9700 12.5000 ;
+ RECT 1.6700 6.4500 78.3300 11.9000 ;
+ RECT 0.9650 5.8500 78.9700 6.4500 ;
+ RECT 1.6700 -0.4000 78.3300 5.8500 ;
+ RECT 0.9650 -1.5000 78.9700 -0.4000 ;
+ LAYER met5 ;
+ RECT 0.0000 166.5750 80.0000 197.9650 ;
+ RECT 0.0000 100.9250 9.6000 166.5750 ;
+ RECT 75.4000 100.9250 80.0000 166.5750 ;
+ RECT 0.0000 94.5500 80.0000 100.9250 ;
+ RECT 2.8700 16.2500 77.1300 94.5500 ;
+ RECT 2.5650 13.0000 77.3700 16.2500 ;
+ RECT 2.8700 0.1000 77.1300 13.0000 ;
+ END
+END s8iom0_gpiov2_pad
+MACRO s8iom0_vddio_lvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vddio_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 17.7650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 17.7650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.4900 3.9050 74.7000 194.3950 ;
+ RECT 0.4900 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.4900 23.2650 74.7000 189.4800 ;
+ RECT 0.4900 20.5850 37.9800 23.2650 ;
+ RECT 0.4900 18.1650 25.6000 20.5850 ;
+ RECT 24.9000 0.0000 25.6000 18.1650 ;
+ RECT 37.2800 0.0000 37.9800 20.5850 ;
+ RECT 49.6550 18.1650 74.7000 23.2650 ;
+ RECT 49.6550 0.0000 50.3550 18.1650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vddio_lvc_pad
+MACRO s8iom0_vddio_hvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vddio_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 88.1500 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 30.4800 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 88.5500 74.2900 197.9650 ;
+ RECT 0.2400 30.8800 49.9900 88.5500 ;
+ RECT 24.7950 10.7900 49.9900 30.8800 ;
+ RECT 24.7950 10.3450 25.4950 10.7900 ;
+ RECT 37.2950 10.7450 49.9900 10.7900 ;
+ RECT 37.2950 10.3450 37.4900 10.7450 ;
+ RECT 49.2900 10.3450 49.9900 10.7450 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vddio_hvc_pad
+MACRO s8iom0_vccd_hvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vccd_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 6.8650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 6.8650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 10.7900 74.2900 197.9650 ;
+ RECT 0.2400 7.2650 25.4950 10.7900 ;
+ RECT 24.7950 6.8650 25.4950 7.2650 ;
+ RECT 37.2950 10.7450 74.2900 10.7900 ;
+ RECT 37.2950 6.8650 37.4900 10.7450 ;
+ RECT 49.2900 7.2650 74.2900 10.7450 ;
+ RECT 49.2900 6.8650 49.9900 7.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vccd_hvc_pad
+MACRO s8iom0_vccd_lvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vccd_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 6.8650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 6.8650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.4900 3.9050 74.7000 194.3950 ;
+ RECT 0.4900 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.4900 23.2650 74.7000 189.4800 ;
+ RECT 0.4900 20.5850 37.9800 23.2650 ;
+ RECT 0.4900 7.2650 25.6000 20.5850 ;
+ RECT 24.9000 0.0000 25.6000 7.2650 ;
+ RECT 37.2800 0.0000 37.9800 20.5850 ;
+ RECT 49.6550 7.2650 74.7000 23.2650 ;
+ RECT 49.6550 0.0000 50.3550 7.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vccd_lvc_pad
+MACRO s8iom0_vdda_hvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vdda_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 6.8650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 6.8650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.6300 189.5650 0.6400 189.5750 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.3600 189.5650 74.3700 189.5750 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 10.7900 74.6550 197.9650 ;
+ RECT 0.2400 7.2650 25.4950 10.7900 ;
+ RECT 24.7950 6.8550 25.4950 7.2650 ;
+ RECT 37.2950 10.7450 74.6550 10.7900 ;
+ RECT 37.2950 6.8550 37.4900 10.7450 ;
+ RECT 49.2900 7.2650 74.6550 10.7450 ;
+ RECT 49.2900 6.8550 49.9900 7.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vdda_hvc_pad
+MACRO s8iom0_vdda_lvc_pad
+ CLASS PAD POWER ;
+ FOREIGN s8iom0_vdda_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 12.9250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 12.9250 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.4900 3.9050 74.7000 194.3950 ;
+ RECT 0.4900 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.4900 23.2650 74.7000 189.4800 ;
+ RECT 0.4900 20.5850 37.9800 23.2650 ;
+ RECT 0.4900 13.3250 25.6000 20.5850 ;
+ RECT 24.9000 0.0000 25.6000 13.3250 ;
+ RECT 37.2800 0.0000 37.9800 20.5850 ;
+ RECT 49.6550 13.3250 74.7000 23.2650 ;
+ RECT 49.6550 0.0000 50.3550 13.3250 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vdda_lvc_pad
+MACRO s8iom0s8_com_bus_slice_1um
+ CLASS PAD SPACER ;
+ FOREIGN s8iom0s8_com_bus_slice_1um ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 1.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.0000 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.0000 49.3100 ;
+ END
+ END amuxbus_b
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.0000 46.0300 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8000 1.0000 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.0000 50.7900 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 1.0000 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 1.0000 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.0000 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.0000 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.0000 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.0000 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.0000 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.0000 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.0000 92.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.0000 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.0000 22.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.0000 92.9500 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.0000 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.0000 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.0000 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.0000 28.4500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 173.7500 1.0000 197.9650 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.0000 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.0000 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.0000 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.0000 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.0000 197.9650 ;
+ END
+END s8iom0s8_com_bus_slice_1um
+MACRO s8iom0_vssio_hvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssio_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.6300 189.5650 0.6400 189.5750 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.2500 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 23.8150 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 23.8150 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 24.2150 74.2900 197.9650 ;
+ RECT 24.7950 10.7900 49.9900 24.2150 ;
+ RECT 24.7950 10.3450 25.4950 10.7900 ;
+ RECT 37.2950 10.7450 49.9900 10.7900 ;
+ RECT 37.2950 10.3450 37.4900 10.7450 ;
+ RECT 49.2900 10.3450 49.9900 10.7450 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssio_hvc_pad
+MACRO s8iom0_corner_pad
+ CLASS ENDCAP TOPRIGHT ;
+ FOREIGN s8iom0_corner_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 200.0000 BY 204.0000 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 57.1250 22.9100 60.1050 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 53.1250 0.0000 56.1050 26.9100 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 52.3650 20.9350 55.3450 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 48.3650 0.0000 51.3450 20.8750 ;
+ END
+ END amuxbus_b
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 51.7350 23.1550 60.7350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.6300 56.0200 0.6400 56.0300 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 40.8350 1.3350 44.0850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.7350 19.5750 52.0650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 40.7350 1.3350 44.1850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 55.6450 21.5500 56.8250 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 60.4050 23.1750 60.7350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 36.8400 0.0000 40.0850 1.2700 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 47.7350 0.0000 56.7350 27.1550 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 51.2850 0.6300 51.2950 0.6400 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 56.4050 0.0000 56.7350 27.1750 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 51.6450 0.0000 52.8250 21.5550 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 36.7350 0.0000 40.1850 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 47.7350 0.0000 48.0650 23.5750 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 19.0350 1.4700 22.2850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 18.9350 1.4700 22.3850 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 15.0350 0.0000 18.2850 1.2550 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 14.9350 0.0000 18.3850 1.2550 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 35.9850 1.3850 39.2350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 35.8850 1.3850 39.3350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 31.9850 0.0000 35.2350 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 31.8850 0.0000 35.3350 1.2700 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.1850 1.4800 72.4350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0850 1.4800 72.5350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 64.1850 0.0000 68.4350 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 64.0850 0.0000 68.5350 1.2700 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.1350 2.3500 11.3850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.0350 2.3500 11.4850 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 2.1350 0.0000 7.3850 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 2.0350 0.0000 7.4850 1.2700 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 74.0350 2.6450 98.9850 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.8850 1.5250 28.3350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.7850 1.5250 28.4350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 74.0350 2.6450 99.0000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 19.8850 0.0000 24.3350 1.2700 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 70.0350 0.0000 94.9850 1.8550 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 70.0350 0.0000 95.0000 1.8550 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 19.7850 0.0000 24.4350 1.2700 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 12.9850 3.7850 17.4350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.8850 3.7850 17.5350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 8.9850 0.0000 13.4350 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 8.8850 0.0000 13.5350 1.2700 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9350 1.6000 34.3850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8350 1.6000 34.4850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 179.7850 1.4350 204.0000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.6300 194.8650 0.6400 194.8750 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 25.9350 0.0000 30.3850 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 25.8350 0.0000 30.4850 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 175.7850 0.0000 200.0000 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 190.8650 0.6300 190.8750 0.6400 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.6850 1.4750 50.1350 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.5850 1.4750 50.2350 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 41.6850 0.0000 46.1350 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 41.5850 0.0000 46.2350 1.2700 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.3350 1.6250 66.5850 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.2350 1.6250 66.6850 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 58.3350 0.0000 62.5850 1.2700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 58.2350 0.0000 62.6850 1.2700 ;
+ END
+ END vssio_q
+ OBS
+ LAYER met4 ;
+ RECT 1.8350 179.3850 200.0000 204.0000 ;
+ RECT 0.0000 99.4000 200.0000 179.3850 ;
+ RECT 3.0450 73.6350 200.0000 99.4000 ;
+ RECT 0.0000 72.9350 200.0000 73.6350 ;
+ RECT 1.8800 67.6850 200.0000 72.9350 ;
+ RECT 0.0000 67.0850 200.0000 67.6850 ;
+ RECT 2.0250 61.8350 200.0000 67.0850 ;
+ RECT 0.0000 61.1350 200.0000 61.8350 ;
+ RECT 23.5750 60.0050 200.0000 61.1350 ;
+ RECT 23.3100 56.7250 200.0000 60.0050 ;
+ RECT 21.9500 55.2450 200.0000 56.7250 ;
+ RECT 21.3350 51.9650 200.0000 55.2450 ;
+ RECT 19.9750 51.3350 200.0000 51.9650 ;
+ RECT 0.0000 50.6350 200.0000 51.3350 ;
+ RECT 1.8750 45.1850 200.0000 50.6350 ;
+ RECT 0.0000 44.5850 200.0000 45.1850 ;
+ RECT 1.7350 40.3350 200.0000 44.5850 ;
+ RECT 0.0000 39.7350 200.0000 40.3350 ;
+ RECT 1.7850 35.4850 200.0000 39.7350 ;
+ RECT 0.0000 34.8850 200.0000 35.4850 ;
+ RECT 2.0000 29.4350 200.0000 34.8850 ;
+ RECT 0.0000 28.8350 200.0000 29.4350 ;
+ RECT 1.9250 27.5750 200.0000 28.8350 ;
+ RECT 1.9250 27.3100 56.0050 27.5750 ;
+ RECT 1.9250 23.9750 52.7250 27.3100 ;
+ RECT 1.9250 23.3850 47.3350 23.9750 ;
+ RECT 0.0000 22.7850 47.3350 23.3850 ;
+ RECT 1.8700 18.5350 47.3350 22.7850 ;
+ RECT 48.4650 21.9550 52.7250 23.9750 ;
+ RECT 48.4650 21.2750 51.2450 21.9550 ;
+ RECT 0.0000 17.9350 47.3350 18.5350 ;
+ RECT 4.1850 12.4850 47.3350 17.9350 ;
+ RECT 0.0000 11.8850 47.3350 12.4850 ;
+ RECT 2.7500 5.6350 47.3350 11.8850 ;
+ RECT 0.0000 1.6700 47.3350 5.6350 ;
+ RECT 0.0000 1.2550 1.6350 1.6700 ;
+ RECT 7.8850 1.2550 8.4850 1.6700 ;
+ RECT 13.9350 1.6550 19.3850 1.6700 ;
+ RECT 13.9350 1.2550 14.5350 1.6550 ;
+ RECT 18.7850 1.2550 19.3850 1.6550 ;
+ RECT 24.8350 1.2550 25.4350 1.6700 ;
+ RECT 30.8850 1.2550 31.4850 1.6700 ;
+ RECT 35.7350 1.2550 36.3350 1.6700 ;
+ RECT 40.5850 1.2550 41.1850 1.6700 ;
+ RECT 46.6350 1.2550 47.3350 1.6700 ;
+ RECT 57.1350 2.2550 200.0000 27.5750 ;
+ RECT 57.1350 1.6700 69.6350 2.2550 ;
+ RECT 57.1350 1.2550 57.8350 1.6700 ;
+ RECT 63.0850 1.2550 63.6850 1.6700 ;
+ RECT 68.9350 1.2550 69.6350 1.6700 ;
+ RECT 95.4000 1.6700 200.0000 2.2550 ;
+ RECT 95.4000 1.2550 175.3850 1.6700 ;
+ LAYER met5 ;
+ RECT 0.0000 100.5850 200.0000 204.0000 ;
+ RECT 4.2450 72.4350 200.0000 100.5850 ;
+ RECT 3.0800 68.1850 200.0000 72.4350 ;
+ RECT 3.2250 62.3350 200.0000 68.1850 ;
+ RECT 24.7550 50.1350 200.0000 62.3350 ;
+ RECT 3.0750 44.0850 200.0000 50.1350 ;
+ RECT 2.9350 40.8350 200.0000 44.0850 ;
+ RECT 2.9850 35.9850 200.0000 40.8350 ;
+ RECT 3.2000 28.7550 200.0000 35.9850 ;
+ RECT 3.2000 28.3350 46.1350 28.7550 ;
+ RECT 3.1250 22.2850 46.1350 28.3350 ;
+ RECT 3.0700 19.0350 46.1350 22.2850 ;
+ RECT 5.3850 11.3850 46.1350 19.0350 ;
+ RECT 3.9500 4.5350 46.1350 11.3850 ;
+ RECT 0.0000 2.8700 46.1350 4.5350 ;
+ RECT 58.3350 3.4550 200.0000 28.7550 ;
+ RECT 58.3350 2.8700 68.4350 3.4550 ;
+ RECT 0.0000 0.0000 0.5350 2.8700 ;
+ RECT 15.0350 2.8550 18.2850 2.8700 ;
+ RECT 96.5850 0.0000 200.0000 3.4550 ;
+ END
+END s8iom0_corner_pad
+MACRO s8iom0_vssio_lvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssio_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 23.8150 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 23.8150 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.5000 3.9050 74.7000 194.3950 ;
+ RECT 0.5000 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.4900 24.2150 74.7000 197.9650 ;
+ RECT 24.9000 23.2650 50.3550 24.2150 ;
+ RECT 24.9000 20.5850 37.9800 23.2650 ;
+ RECT 24.9000 1.6950 25.6000 20.5850 ;
+ RECT 37.2800 1.6950 37.9800 20.5850 ;
+ RECT 49.6550 1.6950 50.3550 23.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssio_lvc_pad
+MACRO s8iom0_vssa_lvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssa_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 51.0900 75.0000 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 46.3300 75.0000 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8000 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8000 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 34.7250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 34.7250 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.5000 3.9050 74.7000 194.3950 ;
+ RECT 0.5000 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.4900 35.1250 74.7000 189.4800 ;
+ RECT 24.9000 23.2650 50.3550 35.1250 ;
+ RECT 24.9000 20.5850 37.9800 23.2650 ;
+ RECT 24.9000 1.5450 25.6000 20.5850 ;
+ RECT 37.2800 1.5450 37.9800 20.5850 ;
+ RECT 49.6550 1.5450 50.3550 23.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssa_lvc_pad
+MACRO s8iom0_vssa_hvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssa_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 30.4800 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 34.7250 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 74.3600 189.5650 74.3700 189.5750 ;
+ END
+ END vssio
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 35.1250 74.2900 193.0650 ;
+ RECT 0.2400 30.8800 49.9900 35.1250 ;
+ RECT 24.7950 10.7900 49.9900 30.8800 ;
+ RECT 24.7950 10.3450 25.4950 10.7900 ;
+ RECT 37.2950 10.7450 49.9900 10.7900 ;
+ RECT 37.2950 10.3450 37.4900 10.7450 ;
+ RECT 49.2900 10.3450 49.9900 10.7450 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 54.4700 73.3300 55.1000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 1.6700 45.3000 73.3300 45.9300 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssa_hvc_pad
+MACRO s8iom0_vssd_hvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssd_hvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_hvc
+ PORT
+ LAYER met2 ;
+ RECT 50.3900 -2.0350 74.2900 23.6250 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 37.8900 -2.0350 48.8900 10.3450 ;
+ END
+ END drn_hvc
+ PIN src_bdy_hvc
+ PORT
+ LAYER met2 ;
+ RECT 0.4950 -2.0350 24.3950 0.0200 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 25.8950 -2.0350 36.8950 10.3900 ;
+ END
+ END src_bdy_hvc
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 6.1000 101.9750 68.8000 164.5900 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.4950 -2.0350 24.3950 30.4800 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.3900 -2.0350 74.2900 39.5650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 1.0700 -1.0350 72.7750 197.6600 ;
+ LAYER met1 ;
+ RECT 0.1850 -1.0650 73.6200 197.6900 ;
+ LAYER met2 ;
+ RECT 0.2650 23.9050 74.2900 193.0400 ;
+ RECT 0.2650 0.3000 50.1100 23.9050 ;
+ RECT 24.6750 -2.0350 50.1100 0.3000 ;
+ LAYER met3 ;
+ RECT 0.2400 39.9650 74.2900 193.0650 ;
+ RECT 0.2400 30.8800 49.9900 39.9650 ;
+ RECT 24.7950 10.7900 49.9900 30.8800 ;
+ RECT 24.7950 10.3450 25.4950 10.7900 ;
+ RECT 37.2950 10.7450 49.9900 10.7900 ;
+ RECT 37.2950 10.3450 37.4900 10.7450 ;
+ RECT 49.2900 10.3450 49.9900 10.7450 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 166.1900 75.0000 197.9650 ;
+ RECT 0.0000 100.3750 4.5000 166.1900 ;
+ RECT 70.4000 100.3750 75.0000 166.1900 ;
+ RECT 0.0000 94.5500 75.0000 100.3750 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssd_hvc_pad
+MACRO s8iom0_vssd_lvc_pad
+ CLASS PAD GROUND ;
+ FOREIGN s8iom0_vssd_lvc_pad ;
+ ORIGIN -0.0000 -0.0000 ;
+ SIZE 75.0000 BY 197.9650 ;
+ PIN amuxbus_a
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 75.0000 54.0700 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 51.0900 1.2700 54.0700 ;
+ END
+ END amuxbus_a
+ PIN amuxbus_b
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 75.0000 49.3100 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 46.3300 1.2700 49.3100 ;
+ END
+ END amuxbus_b
+ PIN drn_lvc1
+ PORT
+ LAYER met3 ;
+ RECT 26.0000 -0.0350 36.8800 20.1850 ;
+ END
+ END drn_lvc1
+ PIN drn_lvc2
+ PORT
+ LAYER met3 ;
+ RECT 38.3800 -0.0350 49.2550 22.8650 ;
+ END
+ END drn_lvc2
+ PIN src_bdy_lvc1
+ PORT
+ LAYER met2 ;
+ RECT 0.5000 -0.0350 20.4950 1.4500 ;
+ END
+ END src_bdy_lvc1
+ PIN src_bdy_lvc2
+ PORT
+ LAYER met2 ;
+ RECT 54.7150 -0.0350 74.7000 3.6250 ;
+ END
+ END src_bdy_lvc2
+ PIN bdy2_b2b
+ PORT
+ LAYER met2 ;
+ RECT 34.4400 -0.0350 44.4400 0.2900 ;
+ END
+ END bdy2_b2b
+ PIN vssi
+ PORT
+ LAYER met1 ;
+ RECT 34.3350 0.4750 35.3350 0.9750 ;
+ END
+ END vssi
+ PIN vssa
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 45.7000 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 34.8050 75.0000 38.0500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 45.7000 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 34.8050 1.2700 38.0500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 49.6100 75.0000 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 75.0000 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 75.0000 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 34.7000 75.0000 38.1500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 45.7000 1.2700 46.0300 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 49.6100 1.2700 50.7900 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 54.3700 1.2700 54.7000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 34.7000 1.2700 38.1500 ;
+ END
+ END vssa
+ PIN vdda
+ PORT
+ LAYER met5 ;
+ RECT 74.0350 13.0000 75.0000 16.2500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 13.0000 0.9650 16.2500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 74.0350 12.9000 75.0000 16.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 12.9000 0.9650 16.3500 ;
+ END
+ END vdda
+ PIN vswitch
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 29.9500 75.0000 33.2000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 29.9500 1.2700 33.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 29.8500 75.0000 33.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 29.8500 1.2700 33.3000 ;
+ END
+ END vswitch
+ PIN vddio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 62.1500 75.0000 66.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 62.1500 1.2700 66.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 62.0500 75.0000 66.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 62.0500 1.2700 66.5000 ;
+ END
+ END vddio_q
+ PIN vcchib
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 0.1000 75.0000 5.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 0.1000 1.2700 5.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 0.0000 75.0000 5.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 0.0000 1.2700 5.4500 ;
+ END
+ END vcchib
+ PIN vddio
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 68.0000 75.0000 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 17.8500 75.0000 22.3000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 68.0000 1.2700 92.9500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 17.8500 1.2700 22.3000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 17.7500 75.0000 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 68.0000 75.0000 92.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 17.7500 1.2700 22.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 68.0000 1.2700 92.9650 ;
+ END
+ END vddio
+ PIN vccd
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 6.9500 75.0000 11.4000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 6.9500 1.2700 11.4000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 6.8500 75.0000 11.5000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 6.8500 1.2700 11.5000 ;
+ END
+ END vccd
+ PIN vssio
+ PORT
+ LAYER met4 ;
+ RECT 74.2250 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2050 197.9650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 23.9000 75.0000 28.3500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 23.9000 1.2700 28.3500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 23.8000 75.0000 28.4500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 173.7500 75.0000 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 173.7500 1.2700 197.9650 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 23.8000 1.2700 28.4500 ;
+ END
+ END vssio
+ PIN vssd
+ PORT
+ LAYER met5 ;
+ RECT 9.3150 100.1050 65.9550 167.5350 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 50.7550 -0.0350 74.7000 39.5650 ;
+ END
+ PORT
+ LAYER met3 ;
+ RECT 0.5000 -0.0350 24.5000 39.5650 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 39.6500 75.0000 44.1000 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 39.6500 1.2700 44.1000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 39.5500 75.0000 44.2000 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 39.5500 1.2700 44.2000 ;
+ END
+ END vssd
+ PIN vssio_q
+ PORT
+ LAYER met5 ;
+ RECT 73.7300 56.3000 75.0000 60.5500 ;
+ END
+ PORT
+ LAYER met5 ;
+ RECT 0.0000 56.3000 1.2700 60.5500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 73.7300 56.2000 75.0000 60.6500 ;
+ END
+ PORT
+ LAYER met4 ;
+ RECT 0.0000 56.2000 1.2700 60.6500 ;
+ END
+ END vssio_q
+ OBS
+ LAYER li1 ;
+ RECT 0.2400 0.9850 74.7550 197.7450 ;
+ LAYER met1 ;
+ RECT 0.1200 1.2550 74.7850 197.8050 ;
+ RECT 0.1200 0.1950 34.0550 1.2550 ;
+ RECT 35.6150 0.1950 74.7850 1.2550 ;
+ RECT 0.1200 -0.0350 74.7850 0.1950 ;
+ LAYER met2 ;
+ RECT 0.5000 3.9050 74.7000 194.3950 ;
+ RECT 0.5000 1.7300 54.4350 3.9050 ;
+ RECT 20.7750 0.5700 54.4350 1.7300 ;
+ RECT 20.7750 -0.0350 34.1600 0.5700 ;
+ RECT 44.7200 -0.0350 54.4350 0.5700 ;
+ LAYER met3 ;
+ RECT 0.5000 39.9650 74.7000 189.4800 ;
+ RECT 24.9000 23.2650 50.3550 39.9650 ;
+ RECT 24.9000 20.5850 37.9800 23.2650 ;
+ RECT 24.9000 17.7550 25.6000 20.5850 ;
+ RECT 37.2800 17.7550 37.9800 20.5850 ;
+ RECT 49.6550 17.7550 50.3550 23.2650 ;
+ LAYER met4 ;
+ RECT 1.6700 173.3500 73.3300 197.9650 ;
+ RECT 0.9650 93.3650 74.0350 173.3500 ;
+ RECT 1.6700 67.6000 73.3300 93.3650 ;
+ RECT 0.9650 66.9000 74.0350 67.6000 ;
+ RECT 1.6700 61.6500 73.3300 66.9000 ;
+ RECT 0.9650 61.0500 74.0350 61.6500 ;
+ RECT 1.6700 55.8000 73.3300 61.0500 ;
+ RECT 0.9650 55.1000 74.0350 55.8000 ;
+ RECT 1.6700 49.7100 73.3300 50.6900 ;
+ RECT 0.9650 44.6000 74.0350 45.3000 ;
+ RECT 1.6700 39.1500 73.3300 44.6000 ;
+ RECT 0.9650 38.5500 74.0350 39.1500 ;
+ RECT 1.6700 34.3000 73.3300 38.5500 ;
+ RECT 0.9650 33.7000 74.0350 34.3000 ;
+ RECT 1.6700 29.4500 73.3300 33.7000 ;
+ RECT 0.9650 28.8500 74.0350 29.4500 ;
+ RECT 1.6700 23.4000 73.3300 28.8500 ;
+ RECT 0.9650 22.8000 74.0350 23.4000 ;
+ RECT 1.6700 17.3500 73.3300 22.8000 ;
+ RECT 0.9650 16.7500 74.0350 17.3500 ;
+ RECT 1.3650 12.5000 73.6350 16.7500 ;
+ RECT 0.9650 11.9000 74.0350 12.5000 ;
+ RECT 1.6700 6.4500 73.3300 11.9000 ;
+ RECT 0.9650 5.8500 74.0350 6.4500 ;
+ RECT 1.6700 0.0000 73.3300 5.8500 ;
+ LAYER met5 ;
+ RECT 0.0000 169.1350 75.0000 197.9650 ;
+ RECT 0.0000 98.5050 7.7150 169.1350 ;
+ RECT 67.5550 98.5050 75.0000 169.1350 ;
+ RECT 0.0000 94.5500 75.0000 98.5050 ;
+ RECT 2.8700 16.2500 72.1300 94.5500 ;
+ RECT 2.5650 13.0000 72.4350 16.2500 ;
+ RECT 2.8700 0.1000 72.1300 13.0000 ;
+ END
+END s8iom0_vssd_lvc_pad
+END LIBRARY ;
diff --git a/sky130/custom/sky130_fd_io/mag/all_pads_test.mag b/sky130/custom/sky130_fd_io/mag/all_pads_test.mag
new file mode 100644
index 0000000..54d9f7a
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/all_pads_test.mag
@@ -0,0 +1,8491 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584383567
+<< error_s >>
+rect 119603 132136 121521 132218
+rect 98716 131466 98782 131482
+rect 800 131078 866 131094
+rect 1823 129308 1824 129332
+rect 1904 129308 1905 129332
+rect 2377 129308 2378 129332
+rect 2458 129308 2459 129332
+rect 2931 129308 2932 129332
+rect 3012 129308 3013 129332
+rect 3485 129308 3486 129332
+rect 3566 129308 3567 129332
+rect 4039 129308 4040 129332
+rect 4120 129308 4121 129332
+rect 4593 129308 4594 129332
+rect 4674 129308 4675 129332
+rect 5147 129308 5148 129332
+rect 5228 129308 5229 129332
+rect 5701 129308 5702 129332
+rect 5782 129308 5783 129332
+rect 6255 129308 6256 129332
+rect 6336 129308 6337 129332
+rect 6809 129308 6810 129332
+rect 6890 129308 6891 129332
+rect 7363 129308 7364 129332
+rect 7444 129308 7445 129332
+rect 7917 129308 7918 129332
+rect 7998 129308 7999 129332
+rect 8471 129308 8472 129332
+rect 8552 129308 8553 129332
+rect 9025 129308 9026 129332
+rect 9106 129308 9107 129332
+rect 9579 129308 9580 129332
+rect 9660 129308 9661 129332
+rect 10133 129308 10134 129332
+rect 10214 129308 10215 129332
+rect 10687 129308 10688 129332
+rect 10768 129308 10769 129332
+rect 11241 129308 11242 129332
+rect 11322 129308 11323 129332
+rect 11795 129308 11796 129332
+rect 11876 129308 11877 129332
+rect 12349 129308 12350 129332
+rect 12430 129308 12431 129332
+rect 1847 129284 1881 129296
+rect 2401 129284 2435 129296
+rect 2955 129284 2989 129296
+rect 3509 129284 3543 129296
+rect 4063 129284 4097 129296
+rect 4617 129284 4651 129296
+rect 5171 129284 5205 129296
+rect 5725 129284 5759 129296
+rect 6279 129284 6313 129296
+rect 6833 129284 6867 129296
+rect 7387 129284 7421 129296
+rect 7941 129284 7975 129296
+rect 8495 129284 8529 129296
+rect 9049 129284 9083 129296
+rect 9603 129284 9637 129296
+rect 10157 129284 10191 129296
+rect 10711 129284 10745 129296
+rect 11265 129284 11299 129296
+rect 11819 129284 11853 129296
+rect 12373 129284 12407 129296
+rect 22784 129100 22856 131100
+rect 23055 129133 23173 131027
+rect 23444 129100 23504 131100
+rect 23704 129100 23776 131100
+rect 23975 129133 24093 131027
+rect 24364 129100 24424 131100
+rect 24624 129100 24696 131100
+rect 24895 129133 25013 131027
+rect 25284 129100 25344 131100
+rect 25544 129100 25616 131100
+rect 25815 129133 25933 131027
+rect 26204 129100 26264 131100
+rect 26464 129100 26536 131100
+rect 26735 129133 26853 131027
+rect 27124 129100 27184 131100
+rect 27384 129100 27456 131100
+rect 27655 129133 27773 131027
+rect 28044 129100 28104 131100
+rect 28304 129100 28376 131100
+rect 28575 129133 28693 131027
+rect 28964 129100 29024 131100
+rect 29224 129100 29296 131100
+rect 29495 129133 29613 131027
+rect 29884 129100 29944 131100
+rect 30144 129100 30216 131100
+rect 30415 129133 30533 131027
+rect 30804 129100 30864 131100
+rect 31064 129100 31136 131100
+rect 31335 129133 31453 131027
+rect 31724 129100 31784 131100
+rect 31984 129100 32056 131100
+rect 32255 129133 32373 131027
+rect 32644 129100 32704 131100
+rect 119390 131001 119472 132035
+rect 119682 131171 119764 131865
+rect 119904 131854 121210 131936
+rect 120072 131660 121014 131710
+rect 119941 131617 119967 131628
+rect 119957 131577 120051 131617
+rect 120963 131577 121057 131617
+rect 119957 131417 120051 131457
+rect 120963 131417 121057 131457
+rect 119941 131406 119967 131417
+rect 120072 131316 121014 131366
+rect 119904 131102 121210 131184
+rect 121250 131171 121332 131865
+rect 121542 131001 121624 132035
+rect 122443 131134 122493 132134
+rect 122593 131134 122721 132134
+rect 122749 131134 122799 132134
+rect 122865 131134 122915 132134
+rect 123075 131134 123131 132134
+rect 123291 131134 123347 132134
+rect 123447 131134 123575 132134
+rect 123603 131134 123653 132134
+rect 123769 131134 123819 132134
+rect 123979 131134 124035 132134
+rect 124135 131134 124263 132134
+rect 124291 131134 124347 132134
+rect 124447 131134 124575 132134
+rect 124603 131134 124659 132134
+rect 124759 131134 124809 132134
+rect 124875 131134 124925 131734
+rect 125025 131134 125075 131734
+rect 125141 131134 125191 132134
+rect 125291 131134 125347 132134
+rect 125447 131134 125497 132134
+rect 126387 131130 126445 131164
+rect 127227 131142 127277 132142
+rect 127377 131142 127505 132142
+rect 127533 131142 127661 132142
+rect 127689 131142 127817 132142
+rect 127845 131142 127973 132142
+rect 128001 131142 128051 132142
+rect 128117 131142 128167 132142
+rect 128267 131142 128323 132142
+rect 128423 131142 128473 132142
+rect 128539 131142 128589 132142
+rect 128689 131142 128817 132142
+rect 128845 131142 128901 132142
+rect 129001 131142 129129 132142
+rect 129157 131142 129207 132142
+rect 129273 131142 129323 132142
+rect 129423 131142 129551 132142
+rect 129579 131142 129635 132142
+rect 129735 131142 129863 132142
+rect 129891 131514 129941 132142
+rect 129891 131442 129944 131514
+rect 129891 131142 129941 131442
+rect 130004 131142 130016 131442
+rect 133592 130979 134592 131029
+rect 39774 130302 39840 130318
+rect 40797 128532 40798 128556
+rect 40878 128532 40879 128556
+rect 41351 128532 41352 128556
+rect 41432 128532 41433 128556
+rect 41905 128532 41906 128556
+rect 41986 128532 41987 128556
+rect 42459 128532 42460 128556
+rect 42540 128532 42541 128556
+rect 43013 128532 43014 128556
+rect 43094 128532 43095 128556
+rect 43567 128532 43568 128556
+rect 43648 128532 43649 128556
+rect 44121 128532 44122 128556
+rect 44202 128532 44203 128556
+rect 44675 128532 44676 128556
+rect 44756 128532 44757 128556
+rect 45229 128532 45230 128556
+rect 45310 128532 45311 128556
+rect 45783 128532 45784 128556
+rect 45864 128532 45865 128556
+rect 46337 128532 46338 128556
+rect 46418 128532 46419 128556
+rect 46891 128532 46892 128556
+rect 46972 128532 46973 128556
+rect 47445 128532 47446 128556
+rect 47526 128532 47527 128556
+rect 47999 128532 48000 128556
+rect 48080 128532 48081 128556
+rect 48553 128532 48554 128556
+rect 48634 128532 48635 128556
+rect 49107 128532 49108 128556
+rect 49188 128532 49189 128556
+rect 49661 128532 49662 128556
+rect 49742 128532 49743 128556
+rect 50215 128532 50216 128556
+rect 50296 128532 50297 128556
+rect 50769 128532 50770 128556
+rect 50850 128532 50851 128556
+rect 51323 128532 51324 128556
+rect 51404 128532 51405 128556
+rect 40821 128508 40855 128520
+rect 41375 128508 41409 128520
+rect 41929 128508 41963 128520
+rect 42483 128508 42517 128520
+rect 43037 128508 43071 128520
+rect 43591 128508 43625 128520
+rect 44145 128508 44179 128520
+rect 44699 128508 44733 128520
+rect 45253 128508 45287 128520
+rect 45807 128508 45841 128520
+rect 46361 128508 46395 128520
+rect 46915 128508 46949 128520
+rect 47469 128508 47503 128520
+rect 48023 128508 48057 128520
+rect 48577 128508 48611 128520
+rect 49131 128508 49165 128520
+rect 49685 128508 49719 128520
+rect 50239 128508 50273 128520
+rect 50793 128508 50827 128520
+rect 51347 128508 51381 128520
+rect 2377 127308 2378 127332
+rect 2458 127308 2459 127332
+rect 2931 127308 2932 127332
+rect 3012 127308 3013 127332
+rect 3485 127308 3486 127332
+rect 3566 127308 3567 127332
+rect 4039 127308 4040 127332
+rect 4120 127308 4121 127332
+rect 4593 127308 4594 127332
+rect 4674 127308 4675 127332
+rect 5147 127308 5148 127332
+rect 5228 127308 5229 127332
+rect 5701 127308 5702 127332
+rect 5782 127308 5783 127332
+rect 6255 127308 6256 127332
+rect 6336 127308 6337 127332
+rect 6809 127308 6810 127332
+rect 6890 127308 6891 127332
+rect 7363 127308 7364 127332
+rect 7444 127308 7445 127332
+rect 7917 127308 7918 127332
+rect 7998 127308 7999 127332
+rect 8471 127308 8472 127332
+rect 8552 127308 8553 127332
+rect 9025 127308 9026 127332
+rect 9106 127308 9107 127332
+rect 9579 127308 9580 127332
+rect 9660 127308 9661 127332
+rect 10133 127308 10134 127332
+rect 10214 127308 10215 127332
+rect 10687 127308 10688 127332
+rect 10768 127308 10769 127332
+rect 11241 127308 11242 127332
+rect 11322 127308 11323 127332
+rect 11795 127308 11796 127332
+rect 11876 127308 11877 127332
+rect 12349 127308 12350 127332
+rect 12430 127308 12431 127332
+rect 2401 127284 2435 127296
+rect 2955 127284 2989 127296
+rect 3509 127284 3543 127296
+rect 4063 127284 4097 127296
+rect 4617 127284 4651 127296
+rect 5171 127284 5205 127296
+rect 5725 127284 5759 127296
+rect 6279 127284 6313 127296
+rect 6833 127284 6867 127296
+rect 7387 127284 7421 127296
+rect 7941 127284 7975 127296
+rect 8495 127284 8529 127296
+rect 9049 127284 9083 127296
+rect 9603 127284 9637 127296
+rect 10157 127284 10191 127296
+rect 10711 127284 10745 127296
+rect 11265 127284 11299 127296
+rect 11819 127284 11853 127296
+rect 12373 127284 12407 127296
+rect 2317 125308 2318 125332
+rect 2398 125308 2399 125332
+rect 3153 125308 3154 125332
+rect 3234 125308 3235 125332
+rect 3989 125308 3990 125332
+rect 4070 125308 4071 125332
+rect 4825 125308 4826 125332
+rect 4906 125308 4907 125332
+rect 5661 125308 5662 125332
+rect 5742 125308 5743 125332
+rect 6497 125308 6498 125332
+rect 6578 125308 6579 125332
+rect 7333 125308 7334 125332
+rect 7414 125308 7415 125332
+rect 8169 125308 8170 125332
+rect 8250 125308 8251 125332
+rect 9005 125308 9006 125332
+rect 9086 125308 9087 125332
+rect 9841 125308 9842 125332
+rect 9922 125308 9923 125332
+rect 10677 125308 10678 125332
+rect 10758 125308 10759 125332
+rect 11513 125308 11514 125332
+rect 11594 125308 11595 125332
+rect 12349 125308 12350 125332
+rect 12430 125308 12431 125332
+rect 2341 125284 2375 125296
+rect 3177 125284 3211 125296
+rect 4013 125284 4047 125296
+rect 4849 125284 4883 125296
+rect 5685 125284 5719 125296
+rect 6521 125284 6555 125296
+rect 7357 125284 7391 125296
+rect 8193 125284 8227 125296
+rect 9029 125284 9063 125296
+rect 9865 125284 9899 125296
+rect 10701 125284 10735 125296
+rect 11537 125284 11571 125296
+rect 12373 125284 12407 125296
+rect 22784 124500 22856 128500
+rect 23055 124533 23173 128467
+rect 23444 124500 23504 128500
+rect 23704 124500 23776 128500
+rect 23975 124533 24093 128467
+rect 24364 124500 24424 128500
+rect 24624 124500 24696 128500
+rect 24895 124533 25013 128467
+rect 25284 124500 25344 128500
+rect 25544 124500 25616 128500
+rect 25815 124533 25933 128467
+rect 26204 124500 26264 128500
+rect 26464 124500 26536 128500
+rect 26735 124533 26853 128467
+rect 27124 124500 27184 128500
+rect 27384 124500 27456 128500
+rect 27655 124533 27773 128467
+rect 28044 124500 28104 128500
+rect 28304 124500 28376 128500
+rect 28575 124533 28693 128467
+rect 28964 124500 29024 128500
+rect 29224 124500 29296 128500
+rect 29495 124533 29613 128467
+rect 29884 124500 29944 128500
+rect 30144 124500 30216 128500
+rect 30415 124533 30533 128467
+rect 30804 124500 30864 128500
+rect 31064 124500 31136 128500
+rect 31335 124533 31453 128467
+rect 31724 124500 31784 128500
+rect 31984 124500 32056 128500
+rect 32255 124533 32373 128467
+rect 32644 124500 32704 128500
+rect 59624 127964 59696 129964
+rect 59895 127997 60013 129891
+rect 60284 127964 60344 129964
+rect 60544 127964 60616 129964
+rect 60815 127997 60933 129891
+rect 61204 127964 61264 129964
+rect 61464 127964 61536 129964
+rect 61735 127997 61853 129891
+rect 62124 127964 62184 129964
+rect 62384 127964 62456 129964
+rect 62655 127997 62773 129891
+rect 63044 127964 63104 129964
+rect 63304 127964 63376 129964
+rect 63575 127997 63693 129891
+rect 63964 127964 64024 129964
+rect 64224 127964 64296 129964
+rect 64495 127997 64613 129891
+rect 64884 127964 64944 129964
+rect 65144 127964 65216 129964
+rect 65415 127997 65533 129891
+rect 65804 127964 65864 129964
+rect 66064 127964 66136 129964
+rect 66335 127997 66453 129891
+rect 66724 127964 66784 129964
+rect 66984 127964 67056 129964
+rect 67255 127997 67373 129891
+rect 67644 127964 67704 129964
+rect 67904 127964 67976 129964
+rect 68175 127997 68293 129891
+rect 68564 127964 68624 129964
+rect 68824 127964 68896 129964
+rect 69095 127997 69213 129891
+rect 69484 127964 69544 129964
+rect 80176 128934 80248 130934
+rect 80447 128967 80565 130861
+rect 80836 128934 80896 130934
+rect 81096 128934 81168 130934
+rect 81367 128967 81485 130861
+rect 81756 128934 81816 130934
+rect 82016 128934 82088 130934
+rect 82287 128967 82405 130861
+rect 82676 128934 82736 130934
+rect 82936 128934 83008 130934
+rect 83207 128967 83325 130861
+rect 83596 128934 83656 130934
+rect 83856 128934 83928 130934
+rect 84127 128967 84245 130861
+rect 84516 128934 84576 130934
+rect 84776 128934 84848 130934
+rect 85047 128967 85165 130861
+rect 85436 128934 85496 130934
+rect 85696 128934 85768 130934
+rect 85967 128967 86085 130861
+rect 86356 128934 86416 130934
+rect 86616 128934 86688 130934
+rect 86887 128967 87005 130861
+rect 87276 128934 87336 130934
+rect 87536 128934 87608 130934
+rect 87807 128967 87925 130861
+rect 88196 128934 88256 130934
+rect 88456 128934 88528 130934
+rect 88727 128967 88845 130861
+rect 89116 128934 89176 130934
+rect 89376 128934 89448 130934
+rect 89647 128967 89765 130861
+rect 90036 128934 90096 130934
+rect 121650 130927 121653 130928
+rect 121650 130926 121651 130927
+rect 121652 130926 121653 130927
+rect 121650 130925 121653 130926
+rect 119603 130817 121521 130899
+rect 133592 130823 134592 130951
+rect 121650 130790 121653 130791
+rect 121650 130789 121651 130790
+rect 121652 130789 121653 130790
+rect 121650 130788 121653 130789
+rect 99739 129696 99740 129720
+rect 99820 129696 99821 129720
+rect 100293 129696 100294 129720
+rect 100374 129696 100375 129720
+rect 100847 129696 100848 129720
+rect 100928 129696 100929 129720
+rect 101401 129696 101402 129720
+rect 101482 129696 101483 129720
+rect 101955 129696 101956 129720
+rect 102036 129696 102037 129720
+rect 102509 129696 102510 129720
+rect 102590 129696 102591 129720
+rect 103063 129696 103064 129720
+rect 103144 129696 103145 129720
+rect 103617 129696 103618 129720
+rect 103698 129696 103699 129720
+rect 104171 129696 104172 129720
+rect 104252 129696 104253 129720
+rect 104725 129696 104726 129720
+rect 104806 129696 104807 129720
+rect 105279 129696 105280 129720
+rect 105360 129696 105361 129720
+rect 105833 129696 105834 129720
+rect 105914 129696 105915 129720
+rect 106387 129696 106388 129720
+rect 106468 129696 106469 129720
+rect 106941 129696 106942 129720
+rect 107022 129696 107023 129720
+rect 107495 129696 107496 129720
+rect 107576 129696 107577 129720
+rect 108049 129696 108050 129720
+rect 108130 129696 108131 129720
+rect 108603 129696 108604 129720
+rect 108684 129696 108685 129720
+rect 109157 129696 109158 129720
+rect 109238 129696 109239 129720
+rect 109711 129696 109712 129720
+rect 109792 129696 109793 129720
+rect 110265 129696 110266 129720
+rect 110346 129696 110347 129720
+rect 99763 129672 99797 129684
+rect 100317 129672 100351 129684
+rect 100871 129672 100905 129684
+rect 101425 129672 101459 129684
+rect 101979 129672 102013 129684
+rect 102533 129672 102567 129684
+rect 103087 129672 103121 129684
+rect 103641 129672 103675 129684
+rect 104195 129672 104229 129684
+rect 104749 129672 104783 129684
+rect 105303 129672 105337 129684
+rect 105857 129672 105891 129684
+rect 106411 129672 106445 129684
+rect 106965 129672 106999 129684
+rect 107519 129672 107553 129684
+rect 108073 129672 108107 129684
+rect 108627 129672 108661 129684
+rect 109181 129672 109215 129684
+rect 109735 129672 109769 129684
+rect 110289 129672 110323 129684
+rect 119390 129681 119472 130715
+rect 119682 129851 119764 130545
+rect 119904 130532 121210 130614
+rect 120072 130350 121014 130400
+rect 119941 130299 119967 130310
+rect 119957 130259 120051 130299
+rect 120963 130259 121057 130299
+rect 119957 130099 120051 130139
+rect 120963 130099 121057 130139
+rect 119941 130088 119967 130099
+rect 120072 130006 121014 130056
+rect 119904 129780 121210 129862
+rect 121250 129851 121332 130545
+rect 121542 129681 121624 130715
+rect 127486 130689 128486 130739
+rect 128882 130689 129482 130739
+rect 127486 130533 128486 130661
+rect 131226 130629 132226 130679
+rect 133592 130673 134592 130723
+rect 128882 130533 129482 130589
+rect 127486 130377 128486 130505
+rect 128882 130377 129482 130433
+rect 131226 130413 132226 130541
+rect 127486 130227 128486 130277
+rect 128882 130221 129482 130277
+rect 131226 130203 132226 130253
+rect 128882 130071 129482 130121
+rect 119603 129498 121521 129580
+rect 120316 129443 120486 129498
+rect 121550 129443 121719 129511
+rect 120384 129363 120385 129443
+rect 120418 129403 120486 129443
+rect 120418 129363 120485 129403
+rect 120384 129362 120485 129363
+rect 121618 129363 121619 129443
+rect 121652 129363 121719 129443
+rect 121618 129362 121719 129363
+rect 120693 129142 121293 129192
+rect 120693 128892 121293 128942
+rect 122413 128467 122463 129467
+rect 122623 128467 122751 129467
+rect 122839 128467 122967 129467
+rect 123055 128467 123183 129467
+rect 123271 128467 123399 129467
+rect 123487 128467 123543 129467
+rect 123703 128467 123759 129467
+rect 123919 128467 124047 129467
+rect 124135 128467 124263 129467
+rect 124351 128467 124479 129467
+rect 124567 128467 124695 129467
+rect 124783 128467 124839 129467
+rect 124999 128467 125127 129467
+rect 125215 128467 125343 129467
+rect 125431 128467 125559 129467
+rect 125647 128467 125697 129467
+rect 125763 128467 125813 129467
+rect 125973 128467 126023 129467
+rect 126089 128467 126139 129467
+rect 126299 128467 126349 129467
+rect 126415 128467 126465 129467
+rect 126625 128467 126675 129467
+rect 126738 129282 126750 129482
+rect 126741 128467 126791 129067
+rect 126991 128467 127047 129067
+rect 127147 128467 127275 129067
+rect 127303 128467 127359 129067
+rect 127459 128467 127587 129067
+rect 127615 128467 127665 129067
+rect 127731 128467 127781 129467
+rect 127881 128467 127937 129467
+rect 128037 128467 128087 129467
+rect 128165 128467 128215 129467
+rect 128315 128467 128443 129467
+rect 128471 128467 128599 129467
+rect 128627 128467 128683 129467
+rect 128783 128467 128911 129467
+rect 128939 128467 129067 129467
+rect 129095 128467 129223 129467
+rect 129251 128467 129301 129467
+rect 129367 128467 129417 129467
+rect 129517 128467 129645 129467
+rect 129673 128467 129801 129467
+rect 129829 128467 129957 129467
+rect 129985 128467 130041 129467
+rect 130141 128467 130269 129467
+rect 130297 128467 130425 129467
+rect 130453 128467 130509 129467
+rect 130609 128467 130659 129467
+rect 131880 129267 131933 129467
+rect 131883 128467 131933 129267
+rect 132093 128467 132221 129467
+rect 132309 128467 132365 129467
+rect 132525 128467 132653 129467
+rect 132741 128467 132791 129467
+rect 132857 128467 132907 129467
+rect 133067 128467 133117 129467
+rect 130604 128380 130640 128391
+rect 130756 128380 133080 128391
+rect 130604 128358 133080 128380
+rect 130604 128357 130640 128358
+rect 130756 128357 133080 128358
+rect 41351 126532 41352 126556
+rect 41432 126532 41433 126556
+rect 41905 126532 41906 126556
+rect 41986 126532 41987 126556
+rect 42459 126532 42460 126556
+rect 42540 126532 42541 126556
+rect 43013 126532 43014 126556
+rect 43094 126532 43095 126556
+rect 43567 126532 43568 126556
+rect 43648 126532 43649 126556
+rect 44121 126532 44122 126556
+rect 44202 126532 44203 126556
+rect 44675 126532 44676 126556
+rect 44756 126532 44757 126556
+rect 45229 126532 45230 126556
+rect 45310 126532 45311 126556
+rect 45783 126532 45784 126556
+rect 45864 126532 45865 126556
+rect 46337 126532 46338 126556
+rect 46418 126532 46419 126556
+rect 46891 126532 46892 126556
+rect 46972 126532 46973 126556
+rect 47445 126532 47446 126556
+rect 47526 126532 47527 126556
+rect 47999 126532 48000 126556
+rect 48080 126532 48081 126556
+rect 48553 126532 48554 126556
+rect 48634 126532 48635 126556
+rect 49107 126532 49108 126556
+rect 49188 126532 49189 126556
+rect 49661 126532 49662 126556
+rect 49742 126532 49743 126556
+rect 50215 126532 50216 126556
+rect 50296 126532 50297 126556
+rect 50769 126532 50770 126556
+rect 50850 126532 50851 126556
+rect 51323 126532 51324 126556
+rect 51404 126532 51405 126556
+rect 41375 126508 41409 126520
+rect 41929 126508 41963 126520
+rect 42483 126508 42517 126520
+rect 43037 126508 43071 126520
+rect 43591 126508 43625 126520
+rect 44145 126508 44179 126520
+rect 44699 126508 44733 126520
+rect 45253 126508 45287 126520
+rect 45807 126508 45841 126520
+rect 46361 126508 46395 126520
+rect 46915 126508 46949 126520
+rect 47469 126508 47503 126520
+rect 48023 126508 48057 126520
+rect 48577 126508 48611 126520
+rect 49131 126508 49165 126520
+rect 49685 126508 49719 126520
+rect 50239 126508 50273 126520
+rect 50793 126508 50827 126520
+rect 51347 126508 51381 126520
+rect 41291 124532 41292 124556
+rect 41372 124532 41373 124556
+rect 42127 124532 42128 124556
+rect 42208 124532 42209 124556
+rect 42963 124532 42964 124556
+rect 43044 124532 43045 124556
+rect 43799 124532 43800 124556
+rect 43880 124532 43881 124556
+rect 44635 124532 44636 124556
+rect 44716 124532 44717 124556
+rect 45471 124532 45472 124556
+rect 45552 124532 45553 124556
+rect 46307 124532 46308 124556
+rect 46388 124532 46389 124556
+rect 47143 124532 47144 124556
+rect 47224 124532 47225 124556
+rect 47979 124532 47980 124556
+rect 48060 124532 48061 124556
+rect 48815 124532 48816 124556
+rect 48896 124532 48897 124556
+rect 49651 124532 49652 124556
+rect 49732 124532 49733 124556
+rect 50487 124532 50488 124556
+rect 50568 124532 50569 124556
+rect 51323 124532 51324 124556
+rect 51404 124532 51405 124556
+rect 41315 124508 41349 124520
+rect 42151 124508 42185 124520
+rect 42987 124508 43021 124520
+rect 43823 124508 43857 124520
+rect 44659 124508 44693 124520
+rect 45495 124508 45529 124520
+rect 46331 124508 46365 124520
+rect 47167 124508 47201 124520
+rect 48003 124508 48037 124520
+rect 48839 124508 48873 124520
+rect 49675 124508 49709 124520
+rect 50511 124508 50545 124520
+rect 51347 124508 51381 124520
+rect 2317 123308 2318 123332
+rect 2398 123308 2399 123332
+rect 3153 123308 3154 123332
+rect 3234 123308 3235 123332
+rect 3989 123308 3990 123332
+rect 4070 123308 4071 123332
+rect 4825 123308 4826 123332
+rect 4906 123308 4907 123332
+rect 5661 123308 5662 123332
+rect 5742 123308 5743 123332
+rect 6497 123308 6498 123332
+rect 6578 123308 6579 123332
+rect 7333 123308 7334 123332
+rect 7414 123308 7415 123332
+rect 8169 123308 8170 123332
+rect 8250 123308 8251 123332
+rect 9005 123308 9006 123332
+rect 9086 123308 9087 123332
+rect 9841 123308 9842 123332
+rect 9922 123308 9923 123332
+rect 10677 123308 10678 123332
+rect 10758 123308 10759 123332
+rect 11513 123308 11514 123332
+rect 11594 123308 11595 123332
+rect 12349 123308 12350 123332
+rect 12430 123308 12431 123332
+rect 2341 123284 2375 123296
+rect 3177 123284 3211 123296
+rect 4013 123284 4047 123296
+rect 4849 123284 4883 123296
+rect 5685 123284 5719 123296
+rect 6521 123284 6555 123296
+rect 7357 123284 7391 123296
+rect 8193 123284 8227 123296
+rect 9029 123284 9063 123296
+rect 9865 123284 9899 123296
+rect 10701 123284 10735 123296
+rect 11537 123284 11571 123296
+rect 12373 123284 12407 123296
+rect 2317 121308 2318 121332
+rect 2398 121308 2399 121332
+rect 3153 121308 3154 121332
+rect 3234 121308 3235 121332
+rect 3989 121308 3990 121332
+rect 4070 121308 4071 121332
+rect 4825 121308 4826 121332
+rect 4906 121308 4907 121332
+rect 5661 121308 5662 121332
+rect 5742 121308 5743 121332
+rect 6497 121308 6498 121332
+rect 6578 121308 6579 121332
+rect 7333 121308 7334 121332
+rect 7414 121308 7415 121332
+rect 8169 121308 8170 121332
+rect 8250 121308 8251 121332
+rect 9005 121308 9006 121332
+rect 9086 121308 9087 121332
+rect 9841 121308 9842 121332
+rect 9922 121308 9923 121332
+rect 10677 121308 10678 121332
+rect 10758 121308 10759 121332
+rect 11513 121308 11514 121332
+rect 11594 121308 11595 121332
+rect 12349 121308 12350 121332
+rect 12430 121308 12431 121332
+rect 2341 121284 2375 121296
+rect 3177 121284 3211 121296
+rect 4013 121284 4047 121296
+rect 4849 121284 4883 121296
+rect 5685 121284 5719 121296
+rect 6521 121284 6555 121296
+rect 7357 121284 7391 121296
+rect 8193 121284 8227 121296
+rect 9029 121284 9063 121296
+rect 9865 121284 9899 121296
+rect 10701 121284 10735 121296
+rect 11537 121284 11571 121296
+rect 12373 121284 12407 121296
+rect 22784 119900 22856 123900
+rect 23055 119933 23173 123867
+rect 23444 119900 23504 123900
+rect 23704 119900 23776 123900
+rect 23975 119933 24093 123867
+rect 24364 119900 24424 123900
+rect 24624 119900 24696 123900
+rect 24895 119933 25013 123867
+rect 25284 119900 25344 123900
+rect 25544 119900 25616 123900
+rect 25815 119933 25933 123867
+rect 26204 119900 26264 123900
+rect 26464 119900 26536 123900
+rect 26735 119933 26853 123867
+rect 27124 119900 27184 123900
+rect 27384 119900 27456 123900
+rect 27655 119933 27773 123867
+rect 28044 119900 28104 123900
+rect 28304 119900 28376 123900
+rect 28575 119933 28693 123867
+rect 28964 119900 29024 123900
+rect 29224 119900 29296 123900
+rect 29495 119933 29613 123867
+rect 29884 119900 29944 123900
+rect 30144 119900 30216 123900
+rect 30415 119933 30533 123867
+rect 30804 119900 30864 123900
+rect 31064 119900 31136 123900
+rect 31335 119933 31453 123867
+rect 31724 119900 31784 123900
+rect 31984 119900 32056 123900
+rect 32255 119933 32373 123867
+rect 32644 119900 32704 123900
+rect 59624 123364 59696 127364
+rect 59895 123397 60013 127331
+rect 60284 123364 60344 127364
+rect 60544 123364 60616 127364
+rect 60815 123397 60933 127331
+rect 61204 123364 61264 127364
+rect 61464 123364 61536 127364
+rect 61735 123397 61853 127331
+rect 62124 123364 62184 127364
+rect 62384 123364 62456 127364
+rect 62655 123397 62773 127331
+rect 63044 123364 63104 127364
+rect 63304 123364 63376 127364
+rect 63575 123397 63693 127331
+rect 63964 123364 64024 127364
+rect 64224 123364 64296 127364
+rect 64495 123397 64613 127331
+rect 64884 123364 64944 127364
+rect 65144 123364 65216 127364
+rect 65415 123397 65533 127331
+rect 65804 123364 65864 127364
+rect 66064 123364 66136 127364
+rect 66335 123397 66453 127331
+rect 66724 123364 66784 127364
+rect 66984 123364 67056 127364
+rect 67255 123397 67373 127331
+rect 67644 123364 67704 127364
+rect 67904 123364 67976 127364
+rect 68175 123397 68293 127331
+rect 68564 123364 68624 127364
+rect 68824 123364 68896 127364
+rect 69095 123397 69213 127331
+rect 69484 123364 69544 127364
+rect 80176 124334 80248 128334
+rect 80447 124367 80565 128301
+rect 80836 124334 80896 128334
+rect 81096 124334 81168 128334
+rect 81367 124367 81485 128301
+rect 81756 124334 81816 128334
+rect 82016 124334 82088 128334
+rect 82287 124367 82405 128301
+rect 82676 124334 82736 128334
+rect 82936 124334 83008 128334
+rect 83207 124367 83325 128301
+rect 83596 124334 83656 128334
+rect 83856 124334 83928 128334
+rect 84127 124367 84245 128301
+rect 84516 124334 84576 128334
+rect 84776 124334 84848 128334
+rect 85047 124367 85165 128301
+rect 85436 124334 85496 128334
+rect 85696 124334 85768 128334
+rect 85967 124367 86085 128301
+rect 86356 124334 86416 128334
+rect 86616 124334 86688 128334
+rect 86887 124367 87005 128301
+rect 87276 124334 87336 128334
+rect 87536 124334 87608 128334
+rect 87807 124367 87925 128301
+rect 88196 124334 88256 128334
+rect 88456 124334 88528 128334
+rect 88727 124367 88845 128301
+rect 89116 124334 89176 128334
+rect 89376 124334 89448 128334
+rect 89647 124367 89765 128301
+rect 90036 124334 90096 128334
+rect 100293 127696 100294 127720
+rect 100374 127696 100375 127720
+rect 100847 127696 100848 127720
+rect 100928 127696 100929 127720
+rect 101401 127696 101402 127720
+rect 101482 127696 101483 127720
+rect 101955 127696 101956 127720
+rect 102036 127696 102037 127720
+rect 102509 127696 102510 127720
+rect 102590 127696 102591 127720
+rect 103063 127696 103064 127720
+rect 103144 127696 103145 127720
+rect 103617 127696 103618 127720
+rect 103698 127696 103699 127720
+rect 104171 127696 104172 127720
+rect 104252 127696 104253 127720
+rect 104725 127696 104726 127720
+rect 104806 127696 104807 127720
+rect 105279 127696 105280 127720
+rect 105360 127696 105361 127720
+rect 105833 127696 105834 127720
+rect 105914 127696 105915 127720
+rect 106387 127696 106388 127720
+rect 106468 127696 106469 127720
+rect 106941 127696 106942 127720
+rect 107022 127696 107023 127720
+rect 107495 127696 107496 127720
+rect 107576 127696 107577 127720
+rect 108049 127696 108050 127720
+rect 108130 127696 108131 127720
+rect 108603 127696 108604 127720
+rect 108684 127696 108685 127720
+rect 109157 127696 109158 127720
+rect 109238 127696 109239 127720
+rect 109711 127696 109712 127720
+rect 109792 127696 109793 127720
+rect 110265 127696 110266 127720
+rect 110346 127696 110347 127720
+rect 100317 127672 100351 127684
+rect 100871 127672 100905 127684
+rect 101425 127672 101459 127684
+rect 101979 127672 102013 127684
+rect 102533 127672 102567 127684
+rect 103087 127672 103121 127684
+rect 103641 127672 103675 127684
+rect 104195 127672 104229 127684
+rect 104749 127672 104783 127684
+rect 105303 127672 105337 127684
+rect 105857 127672 105891 127684
+rect 106411 127672 106445 127684
+rect 106965 127672 106999 127684
+rect 107519 127672 107553 127684
+rect 108073 127672 108107 127684
+rect 108627 127672 108661 127684
+rect 109181 127672 109215 127684
+rect 109735 127672 109769 127684
+rect 110289 127672 110323 127684
+rect 125666 127148 125736 127180
+rect 125770 127148 125805 127180
+rect 125839 127148 125874 127180
+rect 125908 127148 125942 127180
+rect 125976 127148 126010 127180
+rect 126044 127148 126078 127180
+rect 126112 127148 126146 127180
+rect 126180 127148 126214 127180
+rect 126248 127148 126282 127180
+rect 126316 127148 126350 127180
+rect 126384 127148 126418 127180
+rect 126452 127148 126486 127180
+rect 126520 127148 126554 127180
+rect 126588 127148 126622 127180
+rect 126656 127148 126690 127180
+rect 126724 127148 126758 127180
+rect 126792 127148 126826 127180
+rect 126860 127148 126894 127180
+rect 126928 127148 126962 127180
+rect 126996 127148 127030 127180
+rect 127064 127148 127098 127180
+rect 127132 127148 127166 127180
+rect 127200 127148 127234 127180
+rect 127268 127148 127302 127180
+rect 127336 127148 127370 127180
+rect 127404 127148 127438 127180
+rect 127472 127148 127506 127180
+rect 127540 127148 127574 127180
+rect 127608 127148 127642 127180
+rect 127676 127148 127710 127180
+rect 127744 127148 127778 127180
+rect 127812 127148 127846 127180
+rect 127880 127148 127914 127180
+rect 127948 127148 127982 127180
+rect 128016 127148 128050 127180
+rect 128084 127148 128118 127180
+rect 128152 127148 128186 127180
+rect 128220 127148 128254 127180
+rect 128288 127148 128322 127180
+rect 128356 127148 128390 127180
+rect 128424 127148 128458 127180
+rect 128492 127148 128526 127180
+rect 128560 127148 128594 127180
+rect 128628 127148 128662 127180
+rect 128696 127148 128730 127180
+rect 128764 127148 128798 127180
+rect 128832 127148 128866 127180
+rect 128900 127148 128934 127180
+rect 128968 127148 129002 127180
+rect 129036 127148 129070 127180
+rect 129104 127148 129138 127180
+rect 129172 127148 129206 127180
+rect 129240 127148 129274 127180
+rect 129308 127148 129342 127180
+rect 129376 127148 129410 127180
+rect 129444 127148 129478 127180
+rect 129512 127148 129546 127180
+rect 129580 127148 129614 127180
+rect 129648 127148 129682 127180
+rect 129716 127148 129750 127180
+rect 129784 127148 129818 127180
+rect 129852 127148 129886 127180
+rect 129920 127148 129954 127180
+rect 129988 127148 130022 127180
+rect 130056 127148 130090 127180
+rect 130124 127148 130158 127180
+rect 130192 127148 130226 127180
+rect 130260 127148 130294 127180
+rect 130328 127148 130362 127180
+rect 130396 127148 130430 127180
+rect 130464 127148 130498 127180
+rect 130532 127148 130566 127180
+rect 130600 127148 130634 127180
+rect 130668 127148 130702 127180
+rect 130736 127148 130770 127180
+rect 130804 127148 130838 127180
+rect 130872 127148 130906 127180
+rect 130940 127148 130974 127180
+rect 131008 127148 131042 127180
+rect 131076 127148 131110 127180
+rect 131144 127148 131178 127180
+rect 131212 127148 131246 127180
+rect 131280 127148 131314 127180
+rect 131348 127148 131382 127180
+rect 131416 127148 131450 127180
+rect 131484 127148 131518 127180
+rect 131552 127148 131586 127180
+rect 131620 127148 131654 127180
+rect 131688 127148 131722 127180
+rect 131756 127148 131790 127180
+rect 131824 127148 131858 127180
+rect 131892 127148 131926 127180
+rect 131960 127148 131994 127180
+rect 132028 127148 132062 127180
+rect 132096 127148 132130 127180
+rect 132164 127148 132198 127180
+rect 132232 127148 132266 127180
+rect 132300 127148 132334 127180
+rect 132368 127148 132402 127180
+rect 132436 127148 132470 127180
+rect 132504 127148 132538 127180
+rect 132572 127148 132606 127180
+rect 132640 127148 132680 127180
+rect 132777 127148 132848 127216
+rect 134612 127174 134626 127180
+rect 125736 127126 125770 127148
+rect 125805 127126 125839 127148
+rect 125874 127126 125908 127148
+rect 125942 127126 125976 127148
+rect 126010 127126 126044 127148
+rect 126078 127126 126112 127148
+rect 126146 127126 126180 127148
+rect 126214 127126 126248 127148
+rect 126282 127126 126316 127148
+rect 126350 127126 126384 127148
+rect 126418 127126 126452 127148
+rect 126486 127126 126520 127148
+rect 126554 127126 126588 127148
+rect 126622 127126 126656 127148
+rect 126690 127126 126724 127148
+rect 126758 127126 126792 127148
+rect 126826 127126 126860 127148
+rect 126894 127126 126928 127148
+rect 126962 127126 126996 127148
+rect 127030 127126 127064 127148
+rect 127098 127126 127132 127148
+rect 127166 127126 127200 127148
+rect 127234 127126 127268 127148
+rect 127302 127126 127336 127148
+rect 127370 127126 127404 127148
+rect 127438 127126 127472 127148
+rect 127506 127126 127540 127148
+rect 127574 127126 127608 127148
+rect 127642 127126 127676 127148
+rect 127710 127126 127744 127148
+rect 127778 127126 127812 127148
+rect 127846 127126 127880 127148
+rect 127914 127126 127948 127148
+rect 127982 127126 128016 127148
+rect 128050 127126 128084 127148
+rect 128118 127126 128152 127148
+rect 128186 127126 128220 127148
+rect 128254 127126 128288 127148
+rect 128322 127126 128356 127148
+rect 128390 127126 128424 127148
+rect 128458 127126 128492 127148
+rect 128526 127126 128560 127148
+rect 128594 127126 128628 127148
+rect 128662 127126 128696 127148
+rect 128730 127126 128764 127148
+rect 128798 127126 128832 127148
+rect 128866 127126 128900 127148
+rect 128934 127126 128968 127148
+rect 129002 127126 129036 127148
+rect 129070 127126 129104 127148
+rect 129138 127126 129172 127148
+rect 129206 127126 129240 127148
+rect 129274 127126 129308 127148
+rect 129342 127126 129376 127148
+rect 129410 127126 129444 127148
+rect 129478 127126 129512 127148
+rect 129546 127126 129580 127148
+rect 129614 127126 129648 127148
+rect 129682 127126 129716 127148
+rect 129750 127126 129784 127148
+rect 129818 127126 129852 127148
+rect 129886 127126 129920 127148
+rect 129954 127126 129988 127148
+rect 130022 127126 130056 127148
+rect 130090 127126 130124 127148
+rect 130158 127126 130192 127148
+rect 130226 127126 130260 127148
+rect 130294 127126 130328 127148
+rect 130362 127126 130396 127148
+rect 130430 127126 130464 127148
+rect 130498 127126 130532 127148
+rect 130566 127126 130600 127148
+rect 130634 127126 130668 127148
+rect 130702 127126 130736 127148
+rect 130770 127126 130804 127148
+rect 130838 127126 130872 127148
+rect 130906 127126 130940 127148
+rect 130974 127126 131008 127148
+rect 131042 127126 131076 127148
+rect 131110 127126 131144 127148
+rect 131178 127126 131212 127148
+rect 131246 127126 131280 127148
+rect 131314 127126 131348 127148
+rect 131382 127126 131416 127148
+rect 131450 127126 131484 127148
+rect 131518 127126 131552 127148
+rect 131586 127126 131620 127148
+rect 131654 127126 131688 127148
+rect 131722 127126 131756 127148
+rect 131790 127126 131824 127148
+rect 131858 127126 131892 127148
+rect 131926 127126 131960 127148
+rect 131994 127126 132028 127148
+rect 132062 127126 132096 127148
+rect 132130 127126 132164 127148
+rect 132198 127126 132232 127148
+rect 132266 127126 132300 127148
+rect 132334 127126 132368 127148
+rect 132402 127126 132436 127148
+rect 132470 127126 132504 127148
+rect 132538 127126 132572 127148
+rect 132606 127126 132640 127148
+rect 132680 127127 132777 127148
+rect 132780 127127 132848 127148
+rect 132680 127126 132848 127127
+rect 125666 127094 132680 127126
+rect 120992 126779 121992 126829
+rect 122102 126779 123102 126829
+rect 123223 126779 124223 126829
+rect 124344 126779 125344 126829
+rect 125901 126779 126901 126829
+rect 127022 126779 128022 126829
+rect 128143 126779 129143 126829
+rect 129253 126779 130253 126829
+rect 130374 126779 131374 126829
+rect 131495 126779 132495 126829
+rect 120992 126609 121992 126659
+rect 122102 126609 123102 126659
+rect 123223 126609 124223 126659
+rect 124344 126609 125344 126659
+rect 125901 126609 126901 126659
+rect 127022 126609 128022 126659
+rect 128143 126609 129143 126659
+rect 129253 126609 130253 126659
+rect 130374 126609 131374 126659
+rect 131495 126609 132495 126659
+rect 132777 126350 132848 126380
+rect 134572 126350 134612 127174
+rect 120597 126346 120732 126350
+rect 125606 126346 125640 126350
+rect 120597 126312 132680 126346
+rect 132777 126336 134612 126350
+rect 132777 126322 134602 126336
+rect 132777 126312 132848 126322
+rect 120596 126296 120597 126312
+rect 132680 126297 132777 126312
+rect 132780 126297 132848 126312
+rect 132680 126296 132848 126297
+rect 134626 126296 134666 127174
+rect 120597 126258 132680 126296
+rect 132820 126282 134666 126296
+rect 132820 126268 134656 126282
+rect 100233 125696 100234 125720
+rect 100314 125696 100315 125720
+rect 101069 125696 101070 125720
+rect 101150 125696 101151 125720
+rect 101905 125696 101906 125720
+rect 101986 125696 101987 125720
+rect 102741 125696 102742 125720
+rect 102822 125696 102823 125720
+rect 103577 125696 103578 125720
+rect 103658 125696 103659 125720
+rect 104413 125696 104414 125720
+rect 104494 125696 104495 125720
+rect 105249 125696 105250 125720
+rect 105330 125696 105331 125720
+rect 106085 125696 106086 125720
+rect 106166 125696 106167 125720
+rect 106921 125696 106922 125720
+rect 107002 125696 107003 125720
+rect 107757 125696 107758 125720
+rect 107838 125696 107839 125720
+rect 108593 125696 108594 125720
+rect 108674 125696 108675 125720
+rect 109429 125696 109430 125720
+rect 109510 125696 109511 125720
+rect 110265 125696 110266 125720
+rect 110346 125696 110347 125720
+rect 100257 125672 100291 125684
+rect 101093 125672 101127 125684
+rect 101929 125672 101963 125684
+rect 102765 125672 102799 125684
+rect 103601 125672 103635 125684
+rect 104437 125672 104471 125684
+rect 105273 125672 105307 125684
+rect 106109 125672 106143 125684
+rect 106945 125672 106979 125684
+rect 107781 125672 107815 125684
+rect 108617 125672 108651 125684
+rect 109453 125672 109487 125684
+rect 110289 125672 110323 125684
+rect 121219 124928 121429 124964
+rect 133481 124928 133594 124964
+rect 134043 124928 134325 124964
+rect 120808 123928 120886 124928
+rect 121008 123928 121080 124928
+rect 121231 123928 121255 124928
+rect 121296 123928 121352 124928
+rect 121393 123928 121429 124928
+rect 121654 123928 121714 124928
+rect 121914 123928 121986 124928
+rect 122216 123928 122272 124928
+rect 122288 123928 122344 124928
+rect 122646 123928 122706 124928
+rect 122906 123928 122978 124928
+rect 123208 123928 123264 124928
+rect 123280 123928 123336 124928
+rect 123638 123928 123698 124928
+rect 123898 123928 123970 124928
+rect 124200 123928 124256 124928
+rect 124272 123928 124328 124928
+rect 124630 123928 124690 124928
+rect 124890 123928 124962 124928
+rect 125192 123928 125248 124928
+rect 125264 123928 125320 124928
+rect 125622 123928 125682 124928
+rect 125882 123928 125954 124928
+rect 126184 123928 126240 124928
+rect 126256 123928 126312 124928
+rect 126614 123928 126674 124928
+rect 126874 123928 126946 124928
+rect 127176 123928 127232 124928
+rect 127248 123928 127304 124928
+rect 127606 123928 127666 124928
+rect 127866 123928 127938 124928
+rect 128168 123928 128224 124928
+rect 128240 123928 128296 124928
+rect 128598 123928 128658 124928
+rect 128858 123928 128930 124928
+rect 129160 123928 129216 124928
+rect 129232 123928 129288 124928
+rect 129590 123928 129650 124928
+rect 129850 123928 129922 124928
+rect 130152 123928 130208 124928
+rect 130224 123928 130280 124928
+rect 130582 123928 130642 124928
+rect 130842 123928 130914 124928
+rect 131144 123928 131200 124928
+rect 131216 123928 131272 124928
+rect 131574 123928 131634 124928
+rect 131834 123928 131906 124928
+rect 132136 123928 132192 124928
+rect 132208 123928 132264 124928
+rect 132566 123928 132626 124928
+rect 132826 123928 132898 124928
+rect 133128 123928 133184 124928
+rect 133200 123928 133256 124928
+rect 133481 123928 133517 124928
+rect 133558 123928 133594 124928
+rect 133818 123928 133890 124928
+rect 134043 123928 134079 124928
+rect 134120 123928 134176 124928
+rect 134192 123928 134248 124928
+rect 134289 123928 134325 124928
+rect 134536 123928 134596 124928
+rect 134632 123928 134736 124928
+rect 140710 124063 140788 125063
+rect 140910 124063 140982 125063
+rect 161216 124211 161280 124247
+rect 121219 123892 121429 123928
+rect 133481 123892 133594 123928
+rect 134043 123892 134325 123928
+rect 41291 122532 41292 122556
+rect 41372 122532 41373 122556
+rect 42127 122532 42128 122556
+rect 42208 122532 42209 122556
+rect 42963 122532 42964 122556
+rect 43044 122532 43045 122556
+rect 43799 122532 43800 122556
+rect 43880 122532 43881 122556
+rect 44635 122532 44636 122556
+rect 44716 122532 44717 122556
+rect 45471 122532 45472 122556
+rect 45552 122532 45553 122556
+rect 46307 122532 46308 122556
+rect 46388 122532 46389 122556
+rect 47143 122532 47144 122556
+rect 47224 122532 47225 122556
+rect 47979 122532 47980 122556
+rect 48060 122532 48061 122556
+rect 48815 122532 48816 122556
+rect 48896 122532 48897 122556
+rect 49651 122532 49652 122556
+rect 49732 122532 49733 122556
+rect 50487 122532 50488 122556
+rect 50568 122532 50569 122556
+rect 51323 122532 51324 122556
+rect 51404 122532 51405 122556
+rect 41315 122508 41349 122520
+rect 42151 122508 42185 122520
+rect 42987 122508 43021 122520
+rect 43823 122508 43857 122520
+rect 44659 122508 44693 122520
+rect 45495 122508 45529 122520
+rect 46331 122508 46365 122520
+rect 47167 122508 47201 122520
+rect 48003 122508 48037 122520
+rect 48839 122508 48873 122520
+rect 49675 122508 49709 122520
+rect 50511 122508 50545 122520
+rect 51347 122508 51381 122520
+rect 41291 120532 41292 120556
+rect 41372 120532 41373 120556
+rect 42127 120532 42128 120556
+rect 42208 120532 42209 120556
+rect 42963 120532 42964 120556
+rect 43044 120532 43045 120556
+rect 43799 120532 43800 120556
+rect 43880 120532 43881 120556
+rect 44635 120532 44636 120556
+rect 44716 120532 44717 120556
+rect 45471 120532 45472 120556
+rect 45552 120532 45553 120556
+rect 46307 120532 46308 120556
+rect 46388 120532 46389 120556
+rect 47143 120532 47144 120556
+rect 47224 120532 47225 120556
+rect 47979 120532 47980 120556
+rect 48060 120532 48061 120556
+rect 48815 120532 48816 120556
+rect 48896 120532 48897 120556
+rect 49651 120532 49652 120556
+rect 49732 120532 49733 120556
+rect 50487 120532 50488 120556
+rect 50568 120532 50569 120556
+rect 51323 120532 51324 120556
+rect 51404 120532 51405 120556
+rect 41315 120508 41349 120520
+rect 42151 120508 42185 120520
+rect 42987 120508 43021 120520
+rect 43823 120508 43857 120520
+rect 44659 120508 44693 120520
+rect 45495 120508 45529 120520
+rect 46331 120508 46365 120520
+rect 47167 120508 47201 120520
+rect 48003 120508 48037 120520
+rect 48839 120508 48873 120520
+rect 49675 120508 49709 120520
+rect 50511 120508 50545 120520
+rect 51347 120508 51381 120520
+rect 3989 119308 3990 119332
+rect 4070 119308 4071 119332
+rect 4825 119308 4826 119332
+rect 4906 119308 4907 119332
+rect 5661 119308 5662 119332
+rect 5742 119308 5743 119332
+rect 6497 119308 6498 119332
+rect 6578 119308 6579 119332
+rect 7333 119308 7334 119332
+rect 7414 119308 7415 119332
+rect 8169 119308 8170 119332
+rect 8250 119308 8251 119332
+rect 9005 119308 9006 119332
+rect 9086 119308 9087 119332
+rect 9841 119308 9842 119332
+rect 9922 119308 9923 119332
+rect 10677 119308 10678 119332
+rect 10758 119308 10759 119332
+rect 11513 119308 11514 119332
+rect 11594 119308 11595 119332
+rect 12349 119308 12350 119332
+rect 12430 119308 12431 119332
+rect 4013 119284 4047 119296
+rect 4849 119284 4883 119296
+rect 5685 119284 5719 119296
+rect 6521 119284 6555 119296
+rect 7357 119284 7391 119296
+rect 8193 119284 8227 119296
+rect 9029 119284 9063 119296
+rect 9865 119284 9899 119296
+rect 10701 119284 10735 119296
+rect 11537 119284 11571 119296
+rect 12373 119284 12407 119296
+rect 3989 117687 3990 117711
+rect 4070 117687 4071 117711
+rect 4825 117687 4826 117711
+rect 4906 117687 4907 117711
+rect 5661 117687 5662 117711
+rect 5742 117687 5743 117711
+rect 6497 117687 6498 117711
+rect 6578 117687 6579 117711
+rect 7333 117687 7334 117711
+rect 7414 117687 7415 117711
+rect 8169 117687 8170 117711
+rect 8250 117687 8251 117711
+rect 9005 117687 9006 117711
+rect 9086 117687 9087 117711
+rect 9841 117687 9842 117711
+rect 9922 117687 9923 117711
+rect 10677 117687 10678 117711
+rect 10758 117687 10759 117711
+rect 11513 117687 11514 117711
+rect 11594 117687 11595 117711
+rect 12349 117687 12350 117711
+rect 12430 117687 12431 117711
+rect 4013 117663 4047 117675
+rect 4849 117663 4883 117675
+rect 5685 117663 5719 117675
+rect 6521 117663 6555 117675
+rect 7357 117663 7391 117675
+rect 8193 117663 8227 117675
+rect 9029 117663 9063 117675
+rect 9865 117663 9899 117675
+rect 10701 117663 10735 117675
+rect 11537 117663 11571 117675
+rect 12373 117663 12407 117675
+rect 24624 115300 24696 119300
+rect 24895 115333 25013 119267
+rect 25284 115300 25344 119300
+rect 25544 115300 25616 119300
+rect 25815 115333 25933 119267
+rect 26204 115300 26264 119300
+rect 26464 115300 26536 119300
+rect 26735 115333 26853 119267
+rect 27124 115300 27184 119300
+rect 27384 115300 27456 119300
+rect 27655 115333 27773 119267
+rect 28044 115300 28104 119300
+rect 28304 115300 28376 119300
+rect 28575 115333 28693 119267
+rect 28964 115300 29024 119300
+rect 29224 115300 29296 119300
+rect 29495 115333 29613 119267
+rect 29884 115300 29944 119300
+rect 30144 115300 30216 119300
+rect 30415 115333 30533 119267
+rect 30804 115300 30864 119300
+rect 31064 115300 31136 119300
+rect 31335 115333 31453 119267
+rect 31724 115300 31784 119300
+rect 31984 115300 32056 119300
+rect 32255 115333 32373 119267
+rect 32644 115300 32704 119300
+rect 59624 118764 59696 122764
+rect 59895 118797 60013 122731
+rect 60284 118764 60344 122764
+rect 60544 118764 60616 122764
+rect 60815 118797 60933 122731
+rect 61204 118764 61264 122764
+rect 61464 118764 61536 122764
+rect 61735 118797 61853 122731
+rect 62124 118764 62184 122764
+rect 62384 118764 62456 122764
+rect 62655 118797 62773 122731
+rect 63044 118764 63104 122764
+rect 63304 118764 63376 122764
+rect 63575 118797 63693 122731
+rect 63964 118764 64024 122764
+rect 64224 118764 64296 122764
+rect 64495 118797 64613 122731
+rect 64884 118764 64944 122764
+rect 65144 118764 65216 122764
+rect 65415 118797 65533 122731
+rect 65804 118764 65864 122764
+rect 66064 118764 66136 122764
+rect 66335 118797 66453 122731
+rect 66724 118764 66784 122764
+rect 66984 118764 67056 122764
+rect 67255 118797 67373 122731
+rect 67644 118764 67704 122764
+rect 67904 118764 67976 122764
+rect 68175 118797 68293 122731
+rect 68564 118764 68624 122764
+rect 68824 118764 68896 122764
+rect 69095 118797 69213 122731
+rect 69484 118764 69544 122764
+rect 80176 119734 80248 123734
+rect 80447 119767 80565 123701
+rect 80836 119734 80896 123734
+rect 81096 119734 81168 123734
+rect 81367 119767 81485 123701
+rect 81756 119734 81816 123734
+rect 82016 119734 82088 123734
+rect 82287 119767 82405 123701
+rect 82676 119734 82736 123734
+rect 82936 119734 83008 123734
+rect 83207 119767 83325 123701
+rect 83596 119734 83656 123734
+rect 83856 119734 83928 123734
+rect 84127 119767 84245 123701
+rect 84516 119734 84576 123734
+rect 84776 119734 84848 123734
+rect 85047 119767 85165 123701
+rect 85436 119734 85496 123734
+rect 85696 119734 85768 123734
+rect 85967 119767 86085 123701
+rect 86356 119734 86416 123734
+rect 86616 119734 86688 123734
+rect 86887 119767 87005 123701
+rect 87276 119734 87336 123734
+rect 87536 119734 87608 123734
+rect 87807 119767 87925 123701
+rect 88196 119734 88256 123734
+rect 88456 119734 88528 123734
+rect 88727 119767 88845 123701
+rect 89116 119734 89176 123734
+rect 89376 119734 89448 123734
+rect 89647 119767 89765 123701
+rect 90036 119734 90096 123734
+rect 100233 123696 100234 123720
+rect 100314 123696 100315 123720
+rect 101069 123696 101070 123720
+rect 101150 123696 101151 123720
+rect 101905 123696 101906 123720
+rect 101986 123696 101987 123720
+rect 102741 123696 102742 123720
+rect 102822 123696 102823 123720
+rect 103577 123696 103578 123720
+rect 103658 123696 103659 123720
+rect 104413 123696 104414 123720
+rect 104494 123696 104495 123720
+rect 105249 123696 105250 123720
+rect 105330 123696 105331 123720
+rect 106085 123696 106086 123720
+rect 106166 123696 106167 123720
+rect 106921 123696 106922 123720
+rect 107002 123696 107003 123720
+rect 107757 123696 107758 123720
+rect 107838 123696 107839 123720
+rect 108593 123696 108594 123720
+rect 108674 123696 108675 123720
+rect 109429 123696 109430 123720
+rect 109510 123696 109511 123720
+rect 110265 123696 110266 123720
+rect 110346 123696 110347 123720
+rect 100257 123672 100291 123684
+rect 101093 123672 101127 123684
+rect 101929 123672 101963 123684
+rect 102765 123672 102799 123684
+rect 103601 123672 103635 123684
+rect 104437 123672 104471 123684
+rect 105273 123672 105307 123684
+rect 106109 123672 106143 123684
+rect 106945 123672 106979 123684
+rect 107781 123672 107815 123684
+rect 108617 123672 108651 123684
+rect 109453 123672 109487 123684
+rect 110289 123672 110323 123684
+rect 121219 123327 121429 123363
+rect 133481 123327 133594 123363
+rect 134043 123327 134325 123363
+rect 120808 122327 120912 123327
+rect 121008 122327 121080 123327
+rect 121254 122327 121255 123327
+rect 121296 122327 121352 123327
+rect 121393 122327 121394 123327
+rect 121654 122327 121714 123327
+rect 121914 122327 121986 123327
+rect 122216 122327 122272 123327
+rect 122288 122327 122344 123327
+rect 122646 122327 122706 123327
+rect 122906 122327 122978 123327
+rect 123208 122327 123264 123327
+rect 123280 122327 123336 123327
+rect 123638 122327 123698 123327
+rect 123898 122327 123970 123327
+rect 124200 122327 124256 123327
+rect 124272 122327 124328 123327
+rect 124630 122327 124690 123327
+rect 124890 122327 124962 123327
+rect 125192 122327 125248 123327
+rect 125264 122327 125320 123327
+rect 125622 122327 125682 123327
+rect 125882 122327 125954 123327
+rect 126184 122327 126240 123327
+rect 126256 122327 126312 123327
+rect 126614 122327 126674 123327
+rect 126874 122327 126946 123327
+rect 127176 122327 127232 123327
+rect 127248 122327 127304 123327
+rect 127606 122327 127666 123327
+rect 127866 122327 127938 123327
+rect 128168 122327 128224 123327
+rect 128240 122327 128296 123327
+rect 128598 122327 128658 123327
+rect 128858 122327 128930 123327
+rect 129160 122327 129216 123327
+rect 129232 122327 129288 123327
+rect 129590 122327 129650 123327
+rect 129850 122327 129922 123327
+rect 130152 122327 130208 123327
+rect 130224 122327 130280 123327
+rect 130582 122327 130642 123327
+rect 130842 122327 130914 123327
+rect 131144 122327 131200 123327
+rect 131216 122327 131272 123327
+rect 131574 122327 131634 123327
+rect 131834 122327 131906 123327
+rect 132136 122327 132192 123327
+rect 132208 122327 132264 123327
+rect 132566 122327 132626 123327
+rect 132826 122327 132898 123327
+rect 133128 122327 133184 123327
+rect 133200 122327 133256 123327
+rect 133481 122327 133517 123327
+rect 133558 122327 133594 123327
+rect 133818 122327 133890 123327
+rect 134043 122327 134079 123327
+rect 134120 122327 134176 123327
+rect 134192 122327 134248 123327
+rect 134289 122327 134325 123327
+rect 134536 122327 134596 123327
+rect 134632 122327 134736 123327
+rect 140710 122462 140814 123462
+rect 140910 122462 140982 123462
+rect 121219 122291 121429 122327
+rect 133481 122291 133594 122327
+rect 134043 122291 134325 122327
+rect 100233 121696 100234 121720
+rect 100314 121696 100315 121720
+rect 101069 121696 101070 121720
+rect 101150 121696 101151 121720
+rect 101905 121696 101906 121720
+rect 101986 121696 101987 121720
+rect 102741 121696 102742 121720
+rect 102822 121696 102823 121720
+rect 103577 121696 103578 121720
+rect 103658 121696 103659 121720
+rect 104413 121696 104414 121720
+rect 104494 121696 104495 121720
+rect 105249 121696 105250 121720
+rect 105330 121696 105331 121720
+rect 106085 121696 106086 121720
+rect 106166 121696 106167 121720
+rect 106921 121696 106922 121720
+rect 107002 121696 107003 121720
+rect 107757 121696 107758 121720
+rect 107838 121696 107839 121720
+rect 108593 121696 108594 121720
+rect 108674 121696 108675 121720
+rect 109429 121696 109430 121720
+rect 109510 121696 109511 121720
+rect 110265 121696 110266 121720
+rect 110346 121696 110347 121720
+rect 100257 121672 100291 121684
+rect 101093 121672 101127 121684
+rect 101929 121672 101963 121684
+rect 102765 121672 102799 121684
+rect 103601 121672 103635 121684
+rect 104437 121672 104471 121684
+rect 105273 121672 105307 121684
+rect 106109 121672 106143 121684
+rect 106945 121672 106979 121684
+rect 107781 121672 107815 121684
+rect 108617 121672 108651 121684
+rect 109453 121672 109487 121684
+rect 110289 121672 110323 121684
+rect 140661 119964 140677 120030
+rect 120631 119824 120647 119890
+rect 122655 119824 122671 119890
+rect 128822 119758 128838 119774
+rect 101905 119696 101906 119720
+rect 101986 119696 101987 119720
+rect 102741 119696 102742 119720
+rect 102822 119696 102823 119720
+rect 103577 119696 103578 119720
+rect 103658 119696 103659 119720
+rect 104413 119696 104414 119720
+rect 104494 119696 104495 119720
+rect 105249 119696 105250 119720
+rect 105330 119696 105331 119720
+rect 106085 119696 106086 119720
+rect 106166 119696 106167 119720
+rect 106921 119696 106922 119720
+rect 107002 119696 107003 119720
+rect 107757 119696 107758 119720
+rect 107838 119696 107839 119720
+rect 108593 119696 108594 119720
+rect 108674 119696 108675 119720
+rect 109429 119696 109430 119720
+rect 109510 119696 109511 119720
+rect 110265 119696 110266 119720
+rect 110346 119696 110347 119720
+rect 101929 119672 101963 119684
+rect 102765 119672 102799 119684
+rect 103601 119672 103635 119684
+rect 104437 119672 104471 119684
+rect 105273 119672 105307 119684
+rect 106109 119672 106143 119684
+rect 106945 119672 106979 119684
+rect 107781 119672 107815 119684
+rect 108617 119672 108651 119684
+rect 109453 119672 109487 119684
+rect 110289 119672 110323 119684
+rect 128720 119452 128838 119758
+rect 128822 119436 128838 119452
+rect 131010 119758 131026 119774
+rect 131010 119452 131128 119758
+rect 131010 119436 131026 119452
+rect 42963 118532 42964 118556
+rect 43044 118532 43045 118556
+rect 43799 118532 43800 118556
+rect 43880 118532 43881 118556
+rect 44635 118532 44636 118556
+rect 44716 118532 44717 118556
+rect 45471 118532 45472 118556
+rect 45552 118532 45553 118556
+rect 46307 118532 46308 118556
+rect 46388 118532 46389 118556
+rect 47143 118532 47144 118556
+rect 47224 118532 47225 118556
+rect 47979 118532 47980 118556
+rect 48060 118532 48061 118556
+rect 48815 118532 48816 118556
+rect 48896 118532 48897 118556
+rect 49651 118532 49652 118556
+rect 49732 118532 49733 118556
+rect 50487 118532 50488 118556
+rect 50568 118532 50569 118556
+rect 51323 118532 51324 118556
+rect 51404 118532 51405 118556
+rect 42987 118508 43021 118520
+rect 43823 118508 43857 118520
+rect 44659 118508 44693 118520
+rect 45495 118508 45529 118520
+rect 46331 118508 46365 118520
+rect 47167 118508 47201 118520
+rect 48003 118508 48037 118520
+rect 48839 118508 48873 118520
+rect 49675 118508 49709 118520
+rect 50511 118508 50545 118520
+rect 51347 118508 51381 118520
+rect 42963 116911 42964 116935
+rect 43044 116911 43045 116935
+rect 43799 116911 43800 116935
+rect 43880 116911 43881 116935
+rect 44635 116911 44636 116935
+rect 44716 116911 44717 116935
+rect 45471 116911 45472 116935
+rect 45552 116911 45553 116935
+rect 46307 116911 46308 116935
+rect 46388 116911 46389 116935
+rect 47143 116911 47144 116935
+rect 47224 116911 47225 116935
+rect 47979 116911 47980 116935
+rect 48060 116911 48061 116935
+rect 48815 116911 48816 116935
+rect 48896 116911 48897 116935
+rect 49651 116911 49652 116935
+rect 49732 116911 49733 116935
+rect 50487 116911 50488 116935
+rect 50568 116911 50569 116935
+rect 51323 116911 51324 116935
+rect 51404 116911 51405 116935
+rect 42987 116887 43021 116899
+rect 43823 116887 43857 116899
+rect 44659 116887 44693 116899
+rect 45495 116887 45529 116899
+rect 46331 116887 46365 116899
+rect 47167 116887 47201 116899
+rect 48003 116887 48037 116899
+rect 48839 116887 48873 116899
+rect 49675 116887 49709 116899
+rect 50511 116887 50545 116899
+rect 51347 116887 51381 116899
+rect 24624 110700 24696 114700
+rect 24895 110733 25013 114667
+rect 25284 110700 25344 114700
+rect 25544 110700 25616 114700
+rect 25815 110733 25933 114667
+rect 26204 110700 26264 114700
+rect 26464 110700 26536 114700
+rect 26735 110733 26853 114667
+rect 27124 110700 27184 114700
+rect 27384 110700 27456 114700
+rect 27655 110733 27773 114667
+rect 28044 110700 28104 114700
+rect 28304 110700 28376 114700
+rect 28575 110733 28693 114667
+rect 28964 110700 29024 114700
+rect 29224 110700 29296 114700
+rect 29495 110733 29613 114667
+rect 29884 110700 29944 114700
+rect 30144 110700 30216 114700
+rect 30415 110733 30533 114667
+rect 30804 110700 30864 114700
+rect 31064 110700 31136 114700
+rect 31335 110733 31453 114667
+rect 31724 110700 31784 114700
+rect 31984 110700 32056 114700
+rect 32255 110733 32373 114667
+rect 32644 110700 32704 114700
+rect 61464 114164 61536 118164
+rect 61735 114197 61853 118131
+rect 62124 114164 62184 118164
+rect 62384 114164 62456 118164
+rect 62655 114197 62773 118131
+rect 63044 114164 63104 118164
+rect 63304 114164 63376 118164
+rect 63575 114197 63693 118131
+rect 63964 114164 64024 118164
+rect 64224 114164 64296 118164
+rect 64495 114197 64613 118131
+rect 64884 114164 64944 118164
+rect 65144 114164 65216 118164
+rect 65415 114197 65533 118131
+rect 65804 114164 65864 118164
+rect 66064 114164 66136 118164
+rect 66335 114197 66453 118131
+rect 66724 114164 66784 118164
+rect 66984 114164 67056 118164
+rect 67255 114197 67373 118131
+rect 67644 114164 67704 118164
+rect 67904 114164 67976 118164
+rect 68175 114197 68293 118131
+rect 68564 114164 68624 118164
+rect 68824 114164 68896 118164
+rect 69095 114197 69213 118131
+rect 69484 114164 69544 118164
+rect 82016 115134 82088 119134
+rect 82287 115167 82405 119101
+rect 82676 115134 82736 119134
+rect 82936 115134 83008 119134
+rect 83207 115167 83325 119101
+rect 83596 115134 83656 119134
+rect 83856 115134 83928 119134
+rect 84127 115167 84245 119101
+rect 84516 115134 84576 119134
+rect 84776 115134 84848 119134
+rect 85047 115167 85165 119101
+rect 85436 115134 85496 119134
+rect 85696 115134 85768 119134
+rect 85967 115167 86085 119101
+rect 86356 115134 86416 119134
+rect 86616 115134 86688 119134
+rect 86887 115167 87005 119101
+rect 87276 115134 87336 119134
+rect 87536 115134 87608 119134
+rect 87807 115167 87925 119101
+rect 88196 115134 88256 119134
+rect 88456 115134 88528 119134
+rect 88727 115167 88845 119101
+rect 89116 115134 89176 119134
+rect 89376 115134 89448 119134
+rect 89647 115167 89765 119101
+rect 90036 115134 90096 119134
+rect 101905 118075 101906 118099
+rect 101986 118075 101987 118099
+rect 102741 118075 102742 118099
+rect 102822 118075 102823 118099
+rect 103577 118075 103578 118099
+rect 103658 118075 103659 118099
+rect 104413 118075 104414 118099
+rect 104494 118075 104495 118099
+rect 105249 118075 105250 118099
+rect 105330 118075 105331 118099
+rect 106085 118075 106086 118099
+rect 106166 118075 106167 118099
+rect 106921 118075 106922 118099
+rect 107002 118075 107003 118099
+rect 107757 118075 107758 118099
+rect 107838 118075 107839 118099
+rect 108593 118075 108594 118099
+rect 108674 118075 108675 118099
+rect 109429 118075 109430 118099
+rect 109510 118075 109511 118099
+rect 110265 118075 110266 118099
+rect 110346 118075 110347 118099
+rect 101929 118051 101963 118063
+rect 102765 118051 102799 118063
+rect 103601 118051 103635 118063
+rect 104437 118051 104471 118063
+rect 105273 118051 105307 118063
+rect 106109 118051 106143 118063
+rect 106945 118051 106979 118063
+rect 107781 118051 107815 118063
+rect 108617 118051 108651 118063
+rect 109453 118051 109487 118063
+rect 110289 118051 110323 118063
+rect 120254 117573 120278 118362
+rect 24624 106100 24696 110100
+rect 24895 106133 25013 110067
+rect 25284 106100 25344 110100
+rect 25544 106100 25616 110100
+rect 25815 106133 25933 110067
+rect 26204 106100 26264 110100
+rect 26464 106100 26536 110100
+rect 26735 106133 26853 110067
+rect 27124 106100 27184 110100
+rect 27384 106100 27456 110100
+rect 27655 106133 27773 110067
+rect 28044 106100 28104 110100
+rect 28304 106100 28376 110100
+rect 28575 106133 28693 110067
+rect 28964 106100 29024 110100
+rect 29224 106100 29296 110100
+rect 29495 106133 29613 110067
+rect 29884 106100 29944 110100
+rect 30144 106100 30216 110100
+rect 30415 106133 30533 110067
+rect 30804 106100 30864 110100
+rect 31064 106100 31136 110100
+rect 31335 106133 31453 110067
+rect 31724 106100 31784 110100
+rect 31984 106100 32056 110100
+rect 32255 106133 32373 110067
+rect 32644 106100 32704 110100
+rect 61464 109564 61536 113564
+rect 61735 109597 61853 113531
+rect 62124 109564 62184 113564
+rect 62384 109564 62456 113564
+rect 62655 109597 62773 113531
+rect 63044 109564 63104 113564
+rect 63304 109564 63376 113564
+rect 63575 109597 63693 113531
+rect 63964 109564 64024 113564
+rect 64224 109564 64296 113564
+rect 64495 109597 64613 113531
+rect 64884 109564 64944 113564
+rect 65144 109564 65216 113564
+rect 65415 109597 65533 113531
+rect 65804 109564 65864 113564
+rect 66064 109564 66136 113564
+rect 66335 109597 66453 113531
+rect 66724 109564 66784 113564
+rect 66984 109564 67056 113564
+rect 67255 109597 67373 113531
+rect 67644 109564 67704 113564
+rect 67904 109564 67976 113564
+rect 68175 109597 68293 113531
+rect 68564 109564 68624 113564
+rect 68824 109564 68896 113564
+rect 69095 109597 69213 113531
+rect 69484 109564 69544 113564
+rect 82016 110534 82088 114534
+rect 82287 110567 82405 114501
+rect 82676 110534 82736 114534
+rect 82936 110534 83008 114534
+rect 83207 110567 83325 114501
+rect 83596 110534 83656 114534
+rect 83856 110534 83928 114534
+rect 84127 110567 84245 114501
+rect 84516 110534 84576 114534
+rect 84776 110534 84848 114534
+rect 85047 110567 85165 114501
+rect 85436 110534 85496 114534
+rect 85696 110534 85768 114534
+rect 85967 110567 86085 114501
+rect 86356 110534 86416 114534
+rect 86616 110534 86688 114534
+rect 86887 110567 87005 114501
+rect 87276 110534 87336 114534
+rect 87536 110534 87608 114534
+rect 87807 110567 87925 114501
+rect 88196 110534 88256 114534
+rect 88456 110534 88528 114534
+rect 88727 110567 88845 114501
+rect 89116 110534 89176 114534
+rect 89376 110534 89448 114534
+rect 89647 110567 89765 114501
+rect 90036 110534 90096 114534
+rect 120123 112827 120130 117570
+rect 121583 116639 121695 116665
+rect 121783 116639 121869 116665
+rect 122575 116639 122687 116665
+rect 122775 116639 122861 116665
+rect 123567 116639 123679 116665
+rect 123767 116639 123853 116665
+rect 124559 116639 124671 116665
+rect 124759 116639 124845 116665
+rect 125551 116639 125663 116665
+rect 125751 116639 125837 116665
+rect 126543 116639 126655 116665
+rect 126743 116639 126829 116665
+rect 127535 116639 127647 116665
+rect 127735 116639 127821 116665
+rect 128527 116639 128639 116665
+rect 128727 116639 128813 116665
+rect 129519 116639 129631 116665
+rect 129719 116639 129805 116665
+rect 130511 116639 130623 116665
+rect 130711 116639 130797 116665
+rect 131503 116639 131615 116665
+rect 131703 116639 131789 116665
+rect 132495 116639 132607 116665
+rect 132695 116639 132781 116665
+rect 133487 116639 133599 116665
+rect 133687 116639 133773 116665
+rect 120918 115639 120968 116639
+rect 121179 115639 121235 116639
+rect 121251 115639 121307 116639
+rect 121609 115675 121695 116639
+rect 121809 115717 121810 116639
+rect 121869 115717 122021 116639
+rect 121809 115675 122021 115717
+rect 121596 115651 121695 115675
+rect 121800 115651 122021 115675
+rect 121609 115639 121695 115651
+rect 121809 115639 122021 115651
+rect 122171 115639 122227 116639
+rect 122243 115639 122299 116639
+rect 122601 115675 122687 116639
+rect 122801 115717 122802 116639
+rect 122861 115717 123013 116639
+rect 122801 115675 123013 115717
+rect 122588 115651 122687 115675
+rect 122792 115651 123013 115675
+rect 122601 115639 122687 115651
+rect 122801 115639 123013 115651
+rect 123163 115639 123219 116639
+rect 123235 115639 123291 116639
+rect 123593 115675 123679 116639
+rect 123793 115717 123794 116639
+rect 123853 115717 124005 116639
+rect 123793 115675 124005 115717
+rect 123580 115651 123679 115675
+rect 123784 115651 124005 115675
+rect 123593 115639 123679 115651
+rect 123793 115639 124005 115651
+rect 124155 115639 124211 116639
+rect 124227 115639 124283 116639
+rect 124585 115675 124671 116639
+rect 124785 115717 124786 116639
+rect 124845 115717 124997 116639
+rect 124785 115675 124997 115717
+rect 124572 115651 124671 115675
+rect 124776 115651 124997 115675
+rect 124585 115639 124671 115651
+rect 124785 115639 124997 115651
+rect 125147 115639 125203 116639
+rect 125219 115639 125275 116639
+rect 125577 115675 125663 116639
+rect 125777 115717 125778 116639
+rect 125837 115717 125989 116639
+rect 125777 115675 125989 115717
+rect 125564 115651 125663 115675
+rect 125768 115651 125989 115675
+rect 125577 115639 125663 115651
+rect 125777 115639 125989 115651
+rect 126139 115639 126195 116639
+rect 126211 115639 126267 116639
+rect 126569 115675 126655 116639
+rect 126769 115717 126770 116639
+rect 126829 115717 126981 116639
+rect 126769 115675 126981 115717
+rect 126556 115651 126655 115675
+rect 126760 115651 126981 115675
+rect 126569 115639 126655 115651
+rect 126769 115639 126981 115651
+rect 127131 115639 127187 116639
+rect 127203 115639 127259 116639
+rect 127561 115675 127647 116639
+rect 127761 115717 127762 116639
+rect 127821 115717 127973 116639
+rect 127761 115675 127973 115717
+rect 127548 115651 127647 115675
+rect 127752 115651 127973 115675
+rect 127561 115639 127647 115651
+rect 127761 115639 127973 115651
+rect 128123 115639 128179 116639
+rect 128195 115639 128251 116639
+rect 128553 115675 128639 116639
+rect 128753 115717 128754 116639
+rect 128813 115717 128965 116639
+rect 128753 115675 128965 115717
+rect 128540 115651 128639 115675
+rect 128744 115651 128965 115675
+rect 128553 115639 128639 115651
+rect 128753 115639 128965 115651
+rect 129115 115639 129171 116639
+rect 129187 115639 129243 116639
+rect 129545 115675 129631 116639
+rect 129745 115717 129746 116639
+rect 129805 115717 129957 116639
+rect 129745 115675 129957 115717
+rect 129532 115651 129631 115675
+rect 129736 115651 129957 115675
+rect 129545 115639 129631 115651
+rect 129745 115639 129957 115651
+rect 130107 115639 130163 116639
+rect 130179 115639 130235 116639
+rect 130537 115675 130623 116639
+rect 130737 115717 130738 116639
+rect 130797 115717 130949 116639
+rect 130737 115675 130949 115717
+rect 130524 115651 130623 115675
+rect 130728 115651 130949 115675
+rect 130537 115639 130623 115651
+rect 130737 115639 130949 115651
+rect 131099 115639 131155 116639
+rect 131171 115639 131227 116639
+rect 131529 115675 131615 116639
+rect 131729 115717 131730 116639
+rect 131789 115717 131941 116639
+rect 131729 115675 131941 115717
+rect 131516 115651 131615 115675
+rect 131720 115651 131941 115675
+rect 131529 115639 131615 115651
+rect 131729 115639 131941 115651
+rect 132091 115639 132147 116639
+rect 132163 115639 132219 116639
+rect 132521 115675 132607 116639
+rect 132721 115717 132722 116639
+rect 132781 115717 132933 116639
+rect 132721 115675 132933 115717
+rect 132508 115651 132607 115675
+rect 132712 115651 132933 115675
+rect 132521 115639 132607 115651
+rect 132721 115639 132933 115651
+rect 133083 115639 133139 116639
+rect 133155 115639 133211 116639
+rect 133513 115675 133599 116639
+rect 133713 115717 133714 116639
+rect 133773 115717 133925 116639
+rect 133713 115675 133925 115717
+rect 133500 115651 133599 115675
+rect 133704 115651 133925 115675
+rect 133513 115639 133599 115651
+rect 133713 115639 133925 115651
+rect 134034 115639 134106 116639
+rect 134172 115639 134189 116639
+rect 134359 115639 134392 116639
+rect 140248 116622 140282 116646
+rect 134515 116447 134583 116473
+rect 134515 116413 134549 116439
+rect 121620 115627 121654 115639
+rect 121824 115627 121858 115639
+rect 122612 115627 122646 115639
+rect 122816 115627 122850 115639
+rect 123604 115627 123638 115639
+rect 123808 115627 123842 115639
+rect 124596 115627 124630 115639
+rect 124800 115627 124834 115639
+rect 125588 115627 125622 115639
+rect 125792 115627 125826 115639
+rect 126580 115627 126614 115639
+rect 126784 115627 126818 115639
+rect 127572 115627 127606 115639
+rect 127776 115627 127810 115639
+rect 128564 115627 128598 115639
+rect 128768 115627 128802 115639
+rect 129556 115627 129590 115639
+rect 129760 115627 129794 115639
+rect 130548 115627 130582 115639
+rect 130752 115627 130786 115639
+rect 131540 115627 131574 115639
+rect 131744 115627 131778 115639
+rect 132532 115627 132566 115639
+rect 132736 115627 132770 115639
+rect 133524 115627 133558 115639
+rect 133728 115627 133762 115639
+rect 121628 115113 121850 115191
+rect 122620 115113 122842 115191
+rect 123612 115113 123834 115191
+rect 124604 115113 124826 115191
+rect 125596 115113 125818 115191
+rect 126588 115113 126810 115191
+rect 127580 115113 127802 115191
+rect 128572 115113 128794 115191
+rect 129564 115113 129786 115191
+rect 130556 115113 130778 115191
+rect 131548 115113 131770 115191
+rect 132540 115113 132762 115191
+rect 133532 115113 133754 115191
+rect 121583 115039 121695 115065
+rect 121783 115039 121869 115065
+rect 122575 115039 122687 115065
+rect 122775 115039 122861 115065
+rect 123567 115039 123679 115065
+rect 123767 115039 123853 115065
+rect 124559 115039 124671 115065
+rect 124759 115039 124845 115065
+rect 125551 115039 125663 115065
+rect 125751 115039 125837 115065
+rect 126543 115039 126655 115065
+rect 126743 115039 126829 115065
+rect 127535 115039 127647 115065
+rect 127735 115039 127821 115065
+rect 128527 115039 128639 115065
+rect 128727 115039 128813 115065
+rect 129519 115039 129631 115065
+rect 129719 115039 129805 115065
+rect 130511 115039 130623 115065
+rect 130711 115039 130797 115065
+rect 131503 115039 131615 115065
+rect 131703 115039 131789 115065
+rect 132495 115039 132607 115065
+rect 132695 115039 132781 115065
+rect 133487 115039 133599 115065
+rect 133687 115039 133773 115065
+rect 120918 114039 120968 115039
+rect 121179 114039 121235 115039
+rect 121251 114039 121307 115039
+rect 121609 115027 121695 115039
+rect 121809 115027 121810 115039
+rect 121596 115003 121695 115027
+rect 121800 115003 121810 115027
+rect 121609 114039 121695 115003
+rect 121809 114040 121810 115003
+rect 121869 114040 122021 115039
+rect 121809 114039 122021 114040
+rect 122171 114039 122227 115039
+rect 122243 114039 122299 115039
+rect 122601 115027 122687 115039
+rect 122801 115027 122802 115039
+rect 122588 115003 122687 115027
+rect 122792 115003 122802 115027
+rect 122601 114039 122687 115003
+rect 122801 114040 122802 115003
+rect 122861 114040 123013 115039
+rect 122801 114039 123013 114040
+rect 123163 114039 123219 115039
+rect 123235 114039 123291 115039
+rect 123593 115027 123679 115039
+rect 123793 115027 123794 115039
+rect 123580 115003 123679 115027
+rect 123784 115003 123794 115027
+rect 123593 114039 123679 115003
+rect 123793 114040 123794 115003
+rect 123853 114040 124005 115039
+rect 123793 114039 124005 114040
+rect 124155 114039 124211 115039
+rect 124227 114039 124283 115039
+rect 124585 115027 124671 115039
+rect 124785 115027 124786 115039
+rect 124572 115003 124671 115027
+rect 124776 115003 124786 115027
+rect 124585 114039 124671 115003
+rect 124785 114040 124786 115003
+rect 124845 114040 124997 115039
+rect 124785 114039 124997 114040
+rect 125147 114039 125203 115039
+rect 125219 114039 125275 115039
+rect 125577 115027 125663 115039
+rect 125777 115027 125778 115039
+rect 125564 115003 125663 115027
+rect 125768 115003 125778 115027
+rect 125577 114039 125663 115003
+rect 125777 114040 125778 115003
+rect 125837 114040 125989 115039
+rect 125777 114039 125989 114040
+rect 126139 114039 126195 115039
+rect 126211 114039 126267 115039
+rect 126569 115027 126655 115039
+rect 126769 115027 126770 115039
+rect 126556 115003 126655 115027
+rect 126760 115003 126770 115027
+rect 126569 114039 126655 115003
+rect 126769 114040 126770 115003
+rect 126829 114040 126981 115039
+rect 126769 114039 126981 114040
+rect 127131 114039 127187 115039
+rect 127203 114039 127259 115039
+rect 127561 115027 127647 115039
+rect 127761 115027 127762 115039
+rect 127548 115003 127647 115027
+rect 127752 115003 127762 115027
+rect 127561 114039 127647 115003
+rect 127761 114040 127762 115003
+rect 127821 114040 127973 115039
+rect 127761 114039 127973 114040
+rect 128123 114039 128179 115039
+rect 128195 114039 128251 115039
+rect 128553 115027 128639 115039
+rect 128753 115027 128754 115039
+rect 128540 115003 128639 115027
+rect 128744 115003 128754 115027
+rect 128553 114039 128639 115003
+rect 128753 114040 128754 115003
+rect 128813 114040 128965 115039
+rect 128753 114039 128965 114040
+rect 129115 114039 129171 115039
+rect 129187 114039 129243 115039
+rect 129545 115027 129631 115039
+rect 129745 115027 129746 115039
+rect 129532 115003 129631 115027
+rect 129736 115003 129746 115027
+rect 129545 114039 129631 115003
+rect 129745 114040 129746 115003
+rect 129805 114040 129957 115039
+rect 129745 114039 129957 114040
+rect 130107 114039 130163 115039
+rect 130179 114039 130235 115039
+rect 130537 115027 130623 115039
+rect 130737 115027 130738 115039
+rect 130524 115003 130623 115027
+rect 130728 115003 130738 115027
+rect 130537 114039 130623 115003
+rect 130737 114040 130738 115003
+rect 130797 114040 130949 115039
+rect 130737 114039 130949 114040
+rect 131099 114039 131155 115039
+rect 131171 114039 131227 115039
+rect 131529 115027 131615 115039
+rect 131729 115027 131730 115039
+rect 131516 115003 131615 115027
+rect 131720 115003 131730 115027
+rect 131529 114039 131615 115003
+rect 131729 114040 131730 115003
+rect 131789 114040 131941 115039
+rect 131729 114039 131941 114040
+rect 132091 114039 132147 115039
+rect 132163 114039 132219 115039
+rect 132521 115027 132607 115039
+rect 132721 115027 132722 115039
+rect 132508 115003 132607 115027
+rect 132712 115003 132722 115027
+rect 132521 114039 132607 115003
+rect 132721 114040 132722 115003
+rect 132781 114040 132933 115039
+rect 132721 114039 132933 114040
+rect 133083 114039 133139 115039
+rect 133155 114039 133211 115039
+rect 133513 115027 133599 115039
+rect 133713 115027 133714 115039
+rect 133500 115003 133599 115027
+rect 133704 115003 133714 115027
+rect 133513 114039 133599 115003
+rect 133713 114040 133714 115003
+rect 133773 114040 133925 115039
+rect 133713 114039 133925 114040
+rect 134034 114039 134106 115039
+rect 134172 114039 134189 115039
+rect 134359 114039 134392 115039
+rect 140288 112935 140316 116622
+rect 140960 115574 141010 116574
+rect 161216 116425 161255 124211
+rect 161216 116369 161256 116425
+rect 161270 116369 161280 124211
+rect 161216 116333 161280 116369
+rect 140960 113974 141010 114974
+rect 140194 112931 140316 112935
+rect 140194 112911 140288 112931
+rect 140194 112905 140197 112911
+rect 120123 112801 120278 112827
+rect 120368 112801 127264 112837
+rect 140224 112834 140227 112905
+rect 120278 112770 120404 112801
+rect 120425 112770 120459 112794
+rect 120493 112770 120527 112794
+rect 120561 112770 120595 112794
+rect 120629 112770 120663 112794
+rect 120697 112770 120731 112794
+rect 120765 112770 120799 112794
+rect 120833 112770 120867 112794
+rect 120901 112770 120935 112794
+rect 120969 112770 121003 112794
+rect 121037 112770 121071 112794
+rect 121105 112770 121139 112794
+rect 121173 112770 121207 112794
+rect 121241 112770 121275 112794
+rect 121309 112770 121343 112794
+rect 121377 112770 121411 112794
+rect 121445 112770 121479 112794
+rect 121513 112770 121547 112794
+rect 121581 112770 121615 112794
+rect 121649 112770 121683 112794
+rect 121717 112770 121751 112794
+rect 121785 112770 121819 112794
+rect 121853 112770 121887 112794
+rect 121921 112770 121955 112794
+rect 121989 112770 122023 112794
+rect 122057 112770 122091 112794
+rect 122125 112770 122159 112794
+rect 122193 112770 122227 112794
+rect 122261 112770 122295 112794
+rect 122329 112770 122363 112794
+rect 122397 112770 122431 112794
+rect 122465 112770 122499 112794
+rect 122533 112770 122567 112794
+rect 122601 112770 122635 112794
+rect 122669 112770 122703 112794
+rect 122737 112770 122771 112794
+rect 122805 112770 122839 112794
+rect 122873 112770 122907 112794
+rect 122941 112770 122975 112794
+rect 123009 112770 123043 112794
+rect 123077 112770 123111 112794
+rect 123145 112770 123179 112794
+rect 123213 112770 123247 112794
+rect 123281 112770 123315 112794
+rect 123349 112770 123383 112794
+rect 123417 112770 123451 112794
+rect 123485 112770 123519 112794
+rect 123553 112770 123587 112794
+rect 123621 112770 123655 112794
+rect 123689 112770 123723 112794
+rect 123787 112770 123821 112794
+rect 123855 112770 123889 112794
+rect 123923 112770 123957 112794
+rect 123991 112770 124025 112794
+rect 124059 112770 124093 112794
+rect 124127 112770 124161 112794
+rect 124195 112770 124229 112794
+rect 124263 112770 124297 112794
+rect 124331 112770 124365 112794
+rect 124399 112770 124433 112794
+rect 124467 112770 124501 112794
+rect 124535 112770 124569 112794
+rect 124603 112770 124637 112794
+rect 124671 112770 124705 112794
+rect 124739 112770 124773 112794
+rect 124807 112770 124841 112794
+rect 124875 112770 124909 112794
+rect 124943 112770 124977 112794
+rect 125011 112770 125045 112794
+rect 125079 112770 125113 112794
+rect 125147 112770 125181 112794
+rect 125215 112770 125249 112794
+rect 125283 112770 125317 112794
+rect 125351 112770 125385 112794
+rect 125419 112770 125453 112794
+rect 125487 112770 125521 112794
+rect 125555 112770 125589 112794
+rect 125623 112770 125657 112794
+rect 125691 112770 125725 112794
+rect 125759 112770 125793 112794
+rect 125827 112770 125861 112794
+rect 125895 112770 125929 112794
+rect 125963 112770 125997 112794
+rect 126031 112770 126065 112794
+rect 126099 112770 126133 112794
+rect 126167 112770 126201 112794
+rect 126235 112770 126269 112794
+rect 126303 112770 126337 112794
+rect 126371 112770 126405 112794
+rect 126439 112770 126473 112794
+rect 126507 112770 126541 112794
+rect 126575 112770 126609 112794
+rect 126643 112770 126677 112794
+rect 126711 112770 126745 112794
+rect 126779 112770 126813 112794
+rect 126847 112770 126881 112794
+rect 126915 112770 126949 112794
+rect 126983 112770 127017 112794
+rect 127051 112770 127085 112794
+rect 127119 112770 127153 112794
+rect 127228 112770 127264 112801
+rect 120368 112747 127264 112770
+rect 120368 112734 120425 112747
+rect 120459 112734 120493 112747
+rect 120527 112734 120561 112747
+rect 120595 112734 120629 112747
+rect 120663 112734 120697 112747
+rect 120731 112734 120765 112747
+rect 120799 112734 120833 112747
+rect 120867 112734 120901 112747
+rect 120935 112734 120969 112747
+rect 121003 112734 121037 112747
+rect 121071 112734 121105 112747
+rect 121139 112734 121173 112747
+rect 121207 112734 121241 112747
+rect 121275 112734 121309 112747
+rect 121343 112734 121377 112747
+rect 121411 112734 121445 112747
+rect 121479 112734 121513 112747
+rect 121547 112734 121581 112747
+rect 121615 112734 121649 112747
+rect 121683 112734 121717 112747
+rect 121751 112734 121785 112747
+rect 121819 112734 121853 112747
+rect 121887 112734 121921 112747
+rect 121955 112734 121989 112747
+rect 122023 112734 122057 112747
+rect 122091 112734 122125 112747
+rect 122159 112734 122193 112747
+rect 122227 112734 122261 112747
+rect 122295 112734 122329 112747
+rect 122363 112734 122397 112747
+rect 122431 112734 122465 112747
+rect 122499 112734 122533 112747
+rect 122567 112734 122601 112747
+rect 122635 112734 122669 112747
+rect 122703 112734 122737 112747
+rect 122771 112734 122805 112747
+rect 122839 112734 122873 112747
+rect 122907 112734 122941 112747
+rect 122975 112734 123009 112747
+rect 123043 112734 123077 112747
+rect 123111 112734 123145 112747
+rect 123179 112734 123213 112747
+rect 123247 112734 123281 112747
+rect 123315 112734 123349 112747
+rect 123383 112734 123417 112747
+rect 123451 112734 123485 112747
+rect 123519 112734 123553 112747
+rect 123587 112734 123621 112747
+rect 123655 112734 123689 112747
+rect 123723 112734 123787 112747
+rect 123821 112734 123855 112747
+rect 123889 112734 123923 112747
+rect 123957 112734 123991 112747
+rect 124025 112734 124059 112747
+rect 124093 112734 124127 112747
+rect 124161 112734 124195 112747
+rect 124229 112734 124263 112747
+rect 124297 112734 124331 112747
+rect 124365 112734 124399 112747
+rect 124433 112734 124467 112747
+rect 124501 112734 124535 112747
+rect 124569 112734 124603 112747
+rect 124637 112734 124671 112747
+rect 124705 112734 124739 112747
+rect 124773 112734 124807 112747
+rect 124841 112734 124875 112747
+rect 124909 112734 124943 112747
+rect 124977 112734 125011 112747
+rect 125045 112734 125079 112747
+rect 125113 112734 125147 112747
+rect 125181 112734 125215 112747
+rect 125249 112734 125283 112747
+rect 125317 112734 125351 112747
+rect 125385 112734 125419 112747
+rect 125453 112734 125487 112747
+rect 125521 112734 125555 112747
+rect 125589 112734 125623 112747
+rect 125657 112734 125691 112747
+rect 125725 112734 125759 112747
+rect 125793 112734 125827 112747
+rect 125861 112734 125895 112747
+rect 125929 112734 125963 112747
+rect 125997 112734 126031 112747
+rect 126065 112734 126099 112747
+rect 126133 112734 126167 112747
+rect 126201 112734 126235 112747
+rect 126269 112734 126303 112747
+rect 126337 112734 126371 112747
+rect 126405 112734 126439 112747
+rect 126473 112734 126507 112747
+rect 126541 112734 126575 112747
+rect 126609 112734 126643 112747
+rect 126677 112734 126711 112747
+rect 126745 112734 126779 112747
+rect 126813 112734 126847 112747
+rect 126881 112734 126915 112747
+rect 126949 112734 126983 112747
+rect 127017 112734 127051 112747
+rect 127085 112734 127119 112747
+rect 127153 112734 127264 112747
+rect 121044 112423 122044 112473
+rect 122174 112423 123574 112473
+rect 123936 112423 125336 112473
+rect 125466 112423 126866 112473
+rect 121044 112267 122044 112395
+rect 122174 112267 123574 112395
+rect 123936 112267 125336 112395
+rect 125466 112267 126866 112395
+rect 121044 112111 122044 112239
+rect 122174 112111 123574 112239
+rect 123936 112111 125336 112239
+rect 125466 112111 126866 112239
+rect 121044 111955 122044 112083
+rect 122174 111955 123574 112083
+rect 123936 111955 125336 112083
+rect 125466 111955 126866 112083
+rect 128877 112031 129047 112337
+rect 132165 112001 132181 112067
+rect 134189 112001 134205 112067
+rect 121044 111805 122044 111855
+rect 122174 111805 123574 111855
+rect 123936 111805 125336 111855
+rect 125466 111805 126866 111855
+rect 121202 111368 121236 111392
+rect 121270 111368 121304 111392
+rect 121338 111368 121372 111392
+rect 121406 111368 121440 111392
+rect 121474 111368 121508 111392
+rect 121542 111368 121576 111392
+rect 121610 111368 121644 111392
+rect 121678 111368 121712 111392
+rect 121746 111368 121780 111392
+rect 121814 111368 121848 111392
+rect 121882 111368 121916 111392
+rect 121950 111368 121984 111392
+rect 122018 111368 122052 111392
+rect 122086 111368 122120 111392
+rect 122154 111368 122188 111392
+rect 122222 111368 122256 111392
+rect 122290 111368 122324 111392
+rect 122358 111368 122392 111392
+rect 122426 111368 122460 111392
+rect 122494 111368 122528 111392
+rect 122562 111368 122596 111392
+rect 122630 111368 122664 111392
+rect 122698 111368 122732 111392
+rect 122766 111368 122800 111392
+rect 122834 111368 122868 111392
+rect 122902 111368 122936 111392
+rect 122970 111368 123004 111392
+rect 123038 111368 123072 111392
+rect 123106 111368 123140 111392
+rect 123174 111368 123208 111392
+rect 123242 111368 123276 111392
+rect 123310 111368 123344 111392
+rect 123378 111368 123412 111392
+rect 123446 111368 123480 111392
+rect 123514 111368 123548 111392
+rect 123582 111368 123616 111392
+rect 123650 111368 123684 111392
+rect 123718 111368 123752 111392
+rect 123786 111368 123820 111392
+rect 123854 111368 123888 111392
+rect 123922 111368 123956 111392
+rect 123990 111368 124024 111392
+rect 124058 111368 124092 111392
+rect 124126 111368 124160 111392
+rect 124194 111368 124228 111392
+rect 124262 111368 124296 111392
+rect 124330 111368 124364 111392
+rect 124398 111368 124432 111392
+rect 124466 111368 124500 111392
+rect 124534 111368 124568 111392
+rect 124602 111368 124636 111392
+rect 124670 111368 124704 111392
+rect 124738 111368 124772 111392
+rect 124806 111368 124840 111392
+rect 124874 111368 124908 111392
+rect 124942 111368 124976 111392
+rect 125010 111368 125044 111392
+rect 125067 111343 125068 111368
+rect 125026 111334 125068 111343
+rect 121577 111004 124577 111054
+rect 121577 110848 124577 110976
+rect 125026 110932 125128 110956
+rect 125026 110908 125050 110932
+rect 125104 110908 125128 110932
+rect 126509 110908 126543 110966
+rect 126698 110932 126732 110966
+rect 126770 110932 126804 110966
+rect 126842 110932 126876 110966
+rect 126914 110932 126948 110966
+rect 126698 110908 126722 110932
+rect 126924 110908 126948 110932
+rect 127102 110932 127204 110956
+rect 128332 110945 128356 110969
+rect 128230 110932 128254 110935
+rect 127102 110908 127126 110932
+rect 127180 110908 127204 110932
+rect 128308 110921 128332 110935
+rect 128485 110932 128587 110956
+rect 121577 110692 124577 110820
+rect 121577 110536 124577 110664
+rect 121577 110380 124577 110508
+rect 121577 110224 124577 110352
+rect 121577 110068 124577 110196
+rect 1823 105308 1824 105332
+rect 1904 105308 1905 105332
+rect 2377 105308 2378 105332
+rect 2458 105308 2459 105332
+rect 2931 105308 2932 105332
+rect 3012 105308 3013 105332
+rect 3485 105308 3486 105332
+rect 3566 105308 3567 105332
+rect 4039 105308 4040 105332
+rect 4120 105308 4121 105332
+rect 4593 105308 4594 105332
+rect 4674 105308 4675 105332
+rect 5147 105308 5148 105332
+rect 5228 105308 5229 105332
+rect 5701 105308 5702 105332
+rect 5782 105308 5783 105332
+rect 6255 105308 6256 105332
+rect 6336 105308 6337 105332
+rect 6809 105308 6810 105332
+rect 6890 105308 6891 105332
+rect 7363 105308 7364 105332
+rect 7444 105308 7445 105332
+rect 7917 105308 7918 105332
+rect 7998 105308 7999 105332
+rect 8471 105308 8472 105332
+rect 8552 105308 8553 105332
+rect 9025 105308 9026 105332
+rect 9106 105308 9107 105332
+rect 9579 105308 9580 105332
+rect 9660 105308 9661 105332
+rect 10133 105308 10134 105332
+rect 10214 105308 10215 105332
+rect 10687 105308 10688 105332
+rect 10768 105308 10769 105332
+rect 11241 105308 11242 105332
+rect 11322 105308 11323 105332
+rect 11795 105308 11796 105332
+rect 11876 105308 11877 105332
+rect 12349 105308 12350 105332
+rect 12430 105308 12431 105332
+rect 1847 105284 1881 105296
+rect 2401 105284 2435 105296
+rect 2955 105284 2989 105296
+rect 3509 105284 3543 105296
+rect 4063 105284 4097 105296
+rect 4617 105284 4651 105296
+rect 5171 105284 5205 105296
+rect 5725 105284 5759 105296
+rect 6279 105284 6313 105296
+rect 6833 105284 6867 105296
+rect 7387 105284 7421 105296
+rect 7941 105284 7975 105296
+rect 8495 105284 8529 105296
+rect 9049 105284 9083 105296
+rect 9603 105284 9637 105296
+rect 10157 105284 10191 105296
+rect 10711 105284 10745 105296
+rect 11265 105284 11299 105296
+rect 11819 105284 11853 105296
+rect 12373 105284 12407 105296
+rect 1823 103308 1824 103332
+rect 1904 103308 1905 103332
+rect 2377 103308 2378 103332
+rect 2458 103308 2459 103332
+rect 2931 103308 2932 103332
+rect 3012 103308 3013 103332
+rect 3485 103308 3486 103332
+rect 3566 103308 3567 103332
+rect 4039 103308 4040 103332
+rect 4120 103308 4121 103332
+rect 4593 103308 4594 103332
+rect 4674 103308 4675 103332
+rect 5147 103308 5148 103332
+rect 5228 103308 5229 103332
+rect 5701 103308 5702 103332
+rect 5782 103308 5783 103332
+rect 6255 103308 6256 103332
+rect 6336 103308 6337 103332
+rect 6809 103308 6810 103332
+rect 6890 103308 6891 103332
+rect 7363 103308 7364 103332
+rect 7444 103308 7445 103332
+rect 7917 103308 7918 103332
+rect 7998 103308 7999 103332
+rect 8471 103308 8472 103332
+rect 8552 103308 8553 103332
+rect 9025 103308 9026 103332
+rect 9106 103308 9107 103332
+rect 9579 103308 9580 103332
+rect 9660 103308 9661 103332
+rect 10133 103308 10134 103332
+rect 10214 103308 10215 103332
+rect 10687 103308 10688 103332
+rect 10768 103308 10769 103332
+rect 11241 103308 11242 103332
+rect 11322 103308 11323 103332
+rect 11795 103308 11796 103332
+rect 11876 103308 11877 103332
+rect 12349 103308 12350 103332
+rect 12430 103308 12431 103332
+rect 1847 103284 1881 103296
+rect 2401 103284 2435 103296
+rect 2955 103284 2989 103296
+rect 3509 103284 3543 103296
+rect 4063 103284 4097 103296
+rect 4617 103284 4651 103296
+rect 5171 103284 5205 103296
+rect 5725 103284 5759 103296
+rect 6279 103284 6313 103296
+rect 6833 103284 6867 103296
+rect 7387 103284 7421 103296
+rect 7941 103284 7975 103296
+rect 8495 103284 8529 103296
+rect 9049 103284 9083 103296
+rect 9603 103284 9637 103296
+rect 10157 103284 10191 103296
+rect 10711 103284 10745 103296
+rect 11265 103284 11299 103296
+rect 11819 103284 11853 103296
+rect 12373 103284 12407 103296
+rect 22784 101500 22856 105500
+rect 23055 101533 23173 105467
+rect 23444 101500 23504 105500
+rect 23704 101500 23776 105500
+rect 23975 101533 24093 105467
+rect 24364 101500 24424 105500
+rect 24624 101500 24696 105500
+rect 24895 101533 25013 105467
+rect 25284 101500 25344 105500
+rect 25544 101500 25616 105500
+rect 25815 101533 25933 105467
+rect 26204 101500 26264 105500
+rect 26464 101500 26536 105500
+rect 26735 101533 26853 105467
+rect 27124 101500 27184 105500
+rect 27384 101500 27456 105500
+rect 27655 101533 27773 105467
+rect 28044 101500 28104 105500
+rect 28304 101500 28376 105500
+rect 28575 101533 28693 105467
+rect 28964 101500 29024 105500
+rect 29224 101500 29296 105500
+rect 29495 101533 29613 105467
+rect 29884 101500 29944 105500
+rect 30144 101500 30216 105500
+rect 30415 101533 30533 105467
+rect 30804 101500 30864 105500
+rect 31064 101500 31136 105500
+rect 31335 101533 31453 105467
+rect 31724 101500 31784 105500
+rect 31984 101500 32056 105500
+rect 32255 101533 32373 105467
+rect 32644 101500 32704 105500
+rect 61464 104964 61536 108964
+rect 61735 104997 61853 108931
+rect 62124 104964 62184 108964
+rect 62384 104964 62456 108964
+rect 62655 104997 62773 108931
+rect 63044 104964 63104 108964
+rect 63304 104964 63376 108964
+rect 63575 104997 63693 108931
+rect 63964 104964 64024 108964
+rect 64224 104964 64296 108964
+rect 64495 104997 64613 108931
+rect 64884 104964 64944 108964
+rect 65144 104964 65216 108964
+rect 65415 104997 65533 108931
+rect 65804 104964 65864 108964
+rect 66064 104964 66136 108964
+rect 66335 104997 66453 108931
+rect 66724 104964 66784 108964
+rect 66984 104964 67056 108964
+rect 67255 104997 67373 108931
+rect 67644 104964 67704 108964
+rect 67904 104964 67976 108964
+rect 68175 104997 68293 108931
+rect 68564 104964 68624 108964
+rect 68824 104964 68896 108964
+rect 69095 104997 69213 108931
+rect 69484 104964 69544 108964
+rect 82016 105934 82088 109934
+rect 82287 105967 82405 109901
+rect 82676 105934 82736 109934
+rect 82936 105934 83008 109934
+rect 83207 105967 83325 109901
+rect 83596 105934 83656 109934
+rect 83856 105934 83928 109934
+rect 84127 105967 84245 109901
+rect 84516 105934 84576 109934
+rect 84776 105934 84848 109934
+rect 85047 105967 85165 109901
+rect 85436 105934 85496 109934
+rect 85696 105934 85768 109934
+rect 85967 105967 86085 109901
+rect 86356 105934 86416 109934
+rect 86616 105934 86688 109934
+rect 86887 105967 87005 109901
+rect 87276 105934 87336 109934
+rect 87536 105934 87608 109934
+rect 87807 105967 87925 109901
+rect 88196 105934 88256 109934
+rect 88456 105934 88528 109934
+rect 88727 105967 88845 109901
+rect 89116 105934 89176 109934
+rect 89376 105934 89448 109934
+rect 89647 105967 89765 109901
+rect 90036 105934 90096 109934
+rect 121577 109918 124577 109968
+rect 125414 109504 125457 110904
+rect 125564 109504 125692 110904
+rect 125727 109504 125855 110904
+rect 125890 109504 126018 110904
+rect 126053 109504 126181 110904
+rect 126216 109504 126344 110904
+rect 126379 109504 126422 110904
+rect 127291 109504 127341 110904
+rect 127448 109504 127576 110904
+rect 127611 109504 127739 110904
+rect 127774 109504 127902 110904
+rect 127937 109504 128065 110904
+rect 128100 109504 128143 110904
+rect 128206 110887 128230 110911
+rect 128332 110887 128356 110911
+rect 128485 110908 128509 110932
+rect 128563 110908 128587 110932
+rect 122070 109105 122240 109411
+rect 122870 109105 123040 109411
+rect 123670 109105 123840 109411
+rect 122070 108605 122240 108911
+rect 122870 108605 123040 108911
+rect 123670 108605 123840 108911
+rect 119527 107145 119577 107745
+rect 119677 107145 119805 107745
+rect 119833 107145 119961 107745
+rect 119989 107145 120045 107745
+rect 120145 107145 120273 107745
+rect 120301 107145 120429 107745
+rect 120457 107145 120507 107745
+rect 120587 107145 120637 107745
+rect 120737 107145 120787 107745
+rect 121225 107144 121275 107744
+rect 121375 107144 121503 107744
+rect 121531 107144 121659 107744
+rect 121687 107144 121743 107744
+rect 121843 107144 121971 107744
+rect 121999 107144 122127 107744
+rect 122155 107144 122205 107744
+rect 122285 107144 122335 107744
+rect 122435 107144 122485 107744
+rect 122607 107144 122657 107744
+rect 122757 107144 122807 107744
+rect 122887 107144 122937 107744
+rect 123037 107144 123165 107744
+rect 123193 107144 123321 107744
+rect 123349 107144 123405 107744
+rect 123505 107144 123633 107744
+rect 123661 107144 123789 107744
+rect 123817 107144 123867 107744
+rect 125414 107232 125457 108632
+rect 125564 107232 125692 108632
+rect 125727 107232 125855 108632
+rect 125890 107232 126018 108632
+rect 126053 107232 126181 108632
+rect 126216 107232 126344 108632
+rect 126379 107232 126422 108632
+rect 125026 107204 125128 107228
+rect 125104 107180 125128 107204
+rect 126509 107180 126543 107238
+rect 126698 107204 126732 107238
+rect 126770 107204 126804 107238
+rect 126842 107204 126876 107238
+rect 126914 107204 126948 107238
+rect 127291 107232 127341 108632
+rect 127448 107232 127576 108632
+rect 127611 107232 127739 108632
+rect 127774 107232 127902 108632
+rect 127937 107232 128065 108632
+rect 128100 107232 128143 108632
+rect 126698 107180 126722 107204
+rect 126924 107180 126948 107204
+rect 127102 107204 127204 107228
+rect 128206 107225 128230 107249
+rect 128332 107225 128356 107249
+rect 127102 107180 127126 107204
+rect 127180 107180 127204 107204
+rect 128230 107201 128254 107204
+rect 128308 107201 128332 107215
+rect 128485 107204 128587 107228
+rect 128332 107167 128356 107191
+rect 128485 107180 128509 107204
+rect 128563 107180 128587 107204
+rect 128763 106764 129299 111372
+rect 131734 111064 131825 111166
+rect 132058 111131 132072 111155
+rect 132024 111107 132048 111131
+rect 132082 111107 132106 111131
+rect 135278 111057 135312 111077
+rect 131681 110944 131705 110968
+rect 131739 110944 131763 110968
+rect 132215 110962 132249 110966
+rect 132283 110962 132317 110966
+rect 132351 110962 132385 110966
+rect 132419 110962 132453 110966
+rect 132487 110962 132521 110966
+rect 132555 110962 132589 110966
+rect 132623 110962 132657 110966
+rect 132691 110962 132725 110966
+rect 132759 110962 132793 110966
+rect 132827 110962 132861 110966
+rect 132895 110962 132929 110966
+rect 132963 110962 132997 110966
+rect 133031 110962 133065 110966
+rect 133099 110962 133133 110966
+rect 133167 110962 133201 110966
+rect 133235 110962 133269 110966
+rect 133303 110962 133337 110966
+rect 133371 110962 133405 110966
+rect 133439 110962 133473 110966
+rect 133507 110962 133541 110966
+rect 133575 110962 133609 110966
+rect 133643 110962 133677 110966
+rect 133711 110962 133745 110966
+rect 133779 110962 133813 110966
+rect 133847 110962 133881 110966
+rect 133915 110962 133949 110966
+rect 133983 110962 134017 110966
+rect 134051 110962 134085 110966
+rect 134119 110962 134153 110966
+rect 134187 110962 134221 110966
+rect 134255 110962 134289 110966
+rect 134323 110962 134357 110966
+rect 134391 110962 134425 110966
+rect 134459 110962 134493 110966
+rect 134527 110962 134561 110966
+rect 134595 110962 134629 110966
+rect 134663 110962 134697 110966
+rect 134731 110962 134765 110966
+rect 134799 110962 134833 110966
+rect 134867 110962 134901 110966
+rect 134935 110962 134969 110966
+rect 132147 110944 135047 110962
+rect 132215 110940 132249 110944
+rect 132283 110940 132317 110944
+rect 132351 110940 132385 110944
+rect 132419 110940 132453 110944
+rect 132487 110940 132521 110944
+rect 132555 110940 132589 110944
+rect 132623 110940 132657 110944
+rect 132691 110940 132725 110944
+rect 132759 110940 132793 110944
+rect 132827 110940 132861 110944
+rect 132895 110940 132929 110944
+rect 132963 110940 132997 110944
+rect 133031 110940 133065 110944
+rect 133099 110940 133133 110944
+rect 133167 110940 133201 110944
+rect 133235 110940 133269 110944
+rect 133303 110940 133337 110944
+rect 133371 110940 133405 110944
+rect 133439 110940 133473 110944
+rect 133507 110940 133541 110944
+rect 133575 110940 133609 110944
+rect 133643 110940 133677 110944
+rect 133711 110940 133745 110944
+rect 133779 110940 133813 110944
+rect 133847 110940 133881 110944
+rect 133915 110940 133949 110944
+rect 133983 110940 134017 110944
+rect 134051 110940 134085 110944
+rect 134119 110940 134153 110944
+rect 134187 110940 134221 110944
+rect 134255 110940 134289 110944
+rect 134323 110940 134357 110944
+rect 134391 110940 134425 110944
+rect 134459 110940 134493 110944
+rect 134527 110940 134561 110944
+rect 134595 110940 134629 110944
+rect 134663 110940 134697 110944
+rect 134731 110940 134765 110944
+rect 134799 110940 134833 110944
+rect 134867 110940 134901 110944
+rect 134935 110940 134969 110944
+rect 135186 110941 135210 110965
+rect 131705 110920 131739 110934
+rect 132151 110932 135043 110940
+rect 132191 110920 134993 110932
+rect 135210 110917 135234 110932
+rect 135278 110921 135312 110956
+rect 129333 109504 129461 110904
+rect 129496 109504 129624 110904
+rect 129659 109504 129787 110904
+rect 129822 109504 129950 110904
+rect 129985 109504 130113 110904
+rect 130148 109504 130276 110904
+rect 130311 109504 130354 110904
+rect 130447 109504 130490 110904
+rect 130597 109504 130725 110904
+rect 130760 109504 130888 110904
+rect 130923 109504 131051 110904
+rect 131086 109504 131214 110904
+rect 131249 109504 131377 110904
+rect 131412 109504 131540 110904
+rect 131575 109504 131625 110904
+rect 131681 110886 131705 110910
+rect 131739 110886 131763 110910
+rect 135288 110908 135312 110921
+rect 131892 109119 131994 110683
+rect 132261 109436 132311 110836
+rect 132418 109436 132546 110836
+rect 132581 109436 132709 110836
+rect 132744 109436 132872 110836
+rect 132907 109436 133035 110836
+rect 133070 109436 133198 110836
+rect 133233 109436 133361 110836
+rect 133396 109436 133439 110836
+rect 133532 109436 133575 110836
+rect 133682 109436 133810 110836
+rect 133845 109436 133973 110836
+rect 134008 109436 134136 110836
+rect 134171 109436 134299 110836
+rect 134334 109436 134462 110836
+rect 134497 109436 134625 110836
+rect 134660 109436 134788 110836
+rect 134823 109436 134866 110836
+rect 140951 109684 140967 109750
+rect 131926 109095 131960 109119
+rect 131926 109017 131960 109041
+rect 129333 107232 129461 108632
+rect 129496 107232 129624 108632
+rect 129659 107232 129787 108632
+rect 129822 107232 129950 108632
+rect 129985 107232 130113 108632
+rect 130148 107232 130276 108632
+rect 130311 107232 130354 108632
+rect 130447 107232 130490 108632
+rect 130597 107232 130725 108632
+rect 130760 107232 130888 108632
+rect 130923 107232 131051 108632
+rect 131086 107232 131214 108632
+rect 131249 107232 131377 108632
+rect 131412 107232 131540 108632
+rect 131575 107232 131625 108632
+rect 131892 107453 131994 109017
+rect 132261 107300 132311 108700
+rect 132418 107300 132546 108700
+rect 132581 107300 132709 108700
+rect 132744 107300 132872 108700
+rect 132907 107300 133035 108700
+rect 133070 107300 133198 108700
+rect 133233 107300 133361 108700
+rect 133396 107300 133439 108700
+rect 133532 107300 133575 108700
+rect 133682 107300 133810 108700
+rect 133845 107300 133973 108700
+rect 134008 107300 134136 108700
+rect 134171 107300 134299 108700
+rect 134334 107300 134462 108700
+rect 134497 107300 134625 108700
+rect 134660 107300 134788 108700
+rect 134823 107300 134866 108700
+rect 131681 107226 131705 107250
+rect 131739 107226 131763 107250
+rect 132215 107234 132249 107238
+rect 132283 107234 132317 107238
+rect 132351 107234 132385 107238
+rect 132419 107234 132453 107238
+rect 132487 107234 132521 107238
+rect 132555 107234 132589 107238
+rect 132623 107234 132657 107238
+rect 132691 107234 132725 107238
+rect 132759 107234 132793 107238
+rect 132827 107234 132861 107238
+rect 132895 107234 132929 107238
+rect 132963 107234 132997 107238
+rect 133031 107234 133065 107238
+rect 133099 107234 133133 107238
+rect 133167 107234 133201 107238
+rect 133235 107234 133269 107238
+rect 133303 107234 133337 107238
+rect 133371 107234 133405 107238
+rect 133439 107234 133473 107238
+rect 133507 107234 133541 107238
+rect 133575 107234 133609 107238
+rect 133643 107234 133677 107238
+rect 133711 107234 133745 107238
+rect 133779 107234 133813 107238
+rect 133847 107234 133881 107238
+rect 133915 107234 133949 107238
+rect 133983 107234 134017 107238
+rect 134051 107234 134085 107238
+rect 134119 107234 134153 107238
+rect 134187 107234 134221 107238
+rect 134255 107234 134289 107238
+rect 134323 107234 134357 107238
+rect 134391 107234 134425 107238
+rect 134459 107234 134493 107238
+rect 134527 107234 134561 107238
+rect 134595 107234 134629 107238
+rect 134663 107234 134697 107238
+rect 134731 107234 134765 107238
+rect 134799 107234 134833 107238
+rect 134867 107234 134901 107238
+rect 134935 107234 134969 107238
+rect 132181 107226 135013 107234
+rect 135244 107229 135312 107249
+rect 132215 107222 132249 107226
+rect 132283 107222 132317 107226
+rect 132351 107222 132385 107226
+rect 132419 107222 132453 107226
+rect 132487 107222 132521 107226
+rect 132555 107222 132589 107226
+rect 132623 107222 132657 107226
+rect 132691 107222 132725 107226
+rect 132759 107222 132793 107226
+rect 132827 107222 132861 107226
+rect 132895 107222 132929 107226
+rect 132963 107222 132997 107226
+rect 133031 107222 133065 107226
+rect 133099 107222 133133 107226
+rect 133167 107222 133201 107226
+rect 133235 107222 133269 107226
+rect 133303 107222 133337 107226
+rect 133371 107222 133405 107226
+rect 133439 107222 133473 107226
+rect 133507 107222 133541 107226
+rect 133575 107222 133609 107226
+rect 133643 107222 133677 107226
+rect 133711 107222 133745 107226
+rect 133779 107222 133813 107226
+rect 133847 107222 133881 107226
+rect 133915 107222 133949 107226
+rect 133983 107222 134017 107226
+rect 134051 107222 134085 107226
+rect 134119 107222 134153 107226
+rect 134187 107222 134221 107226
+rect 134255 107222 134289 107226
+rect 134323 107222 134357 107226
+rect 134391 107222 134425 107226
+rect 134459 107222 134493 107226
+rect 134527 107222 134561 107226
+rect 134595 107222 134629 107226
+rect 134663 107222 134697 107226
+rect 134731 107222 134765 107226
+rect 134799 107222 134833 107226
+rect 134867 107222 134901 107226
+rect 134935 107222 134969 107226
+rect 131705 107202 131739 107216
+rect 132147 107204 135047 107222
+rect 135210 107204 135234 107219
+rect 135278 107204 135312 107229
+rect 132191 107202 134993 107204
+rect 131681 107168 131705 107192
+rect 131739 107168 131763 107192
+rect 135186 107171 135210 107195
+rect 135288 107180 135312 107204
+rect 135244 107093 135312 107113
+rect 131734 106970 131825 107072
+rect 132024 107005 132048 107029
+rect 132082 107005 132106 107029
+rect 132058 106981 132072 107005
+rect 99739 105696 99740 105720
+rect 99820 105696 99821 105720
+rect 100293 105696 100294 105720
+rect 100374 105696 100375 105720
+rect 100847 105696 100848 105720
+rect 100928 105696 100929 105720
+rect 101401 105696 101402 105720
+rect 101482 105696 101483 105720
+rect 101955 105696 101956 105720
+rect 102036 105696 102037 105720
+rect 102509 105696 102510 105720
+rect 102590 105696 102591 105720
+rect 103063 105696 103064 105720
+rect 103144 105696 103145 105720
+rect 103617 105696 103618 105720
+rect 103698 105696 103699 105720
+rect 104171 105696 104172 105720
+rect 104252 105696 104253 105720
+rect 104725 105696 104726 105720
+rect 104806 105696 104807 105720
+rect 105279 105696 105280 105720
+rect 105360 105696 105361 105720
+rect 105833 105696 105834 105720
+rect 105914 105696 105915 105720
+rect 106387 105696 106388 105720
+rect 106468 105696 106469 105720
+rect 106941 105696 106942 105720
+rect 107022 105696 107023 105720
+rect 107495 105696 107496 105720
+rect 107576 105696 107577 105720
+rect 108049 105696 108050 105720
+rect 108130 105696 108131 105720
+rect 108603 105696 108604 105720
+rect 108684 105696 108685 105720
+rect 109157 105696 109158 105720
+rect 109238 105696 109239 105720
+rect 109711 105696 109712 105720
+rect 109792 105696 109793 105720
+rect 110265 105696 110266 105720
+rect 110346 105696 110347 105720
+rect 99763 105672 99797 105684
+rect 100317 105672 100351 105684
+rect 100871 105672 100905 105684
+rect 101425 105672 101459 105684
+rect 101979 105672 102013 105684
+rect 102533 105672 102567 105684
+rect 103087 105672 103121 105684
+rect 103641 105672 103675 105684
+rect 104195 105672 104229 105684
+rect 104749 105672 104783 105684
+rect 105303 105672 105337 105684
+rect 105857 105672 105891 105684
+rect 106411 105672 106445 105684
+rect 106965 105672 106999 105684
+rect 107519 105672 107553 105684
+rect 108073 105672 108107 105684
+rect 108627 105672 108661 105684
+rect 109181 105672 109215 105684
+rect 109735 105672 109769 105684
+rect 110289 105672 110323 105684
+rect 121923 105627 121973 105827
+rect 122073 105627 122129 105827
+rect 122229 105627 122279 105827
+rect 122629 105627 122679 105827
+rect 122779 105627 122835 105827
+rect 122935 105627 122985 105827
+rect 123049 105627 123060 105827
+rect 129913 105381 129963 106381
+rect 130063 105381 130119 106381
+rect 130219 105381 130275 106381
+rect 130375 105381 130431 106381
+rect 130531 105924 130581 106381
+rect 130995 105924 131045 106381
+rect 130531 105840 130584 105924
+rect 130992 105840 131045 105924
+rect 130531 105591 130581 105840
+rect 130995 105591 131045 105840
+rect 130531 105507 130584 105591
+rect 130992 105507 131045 105591
+rect 130531 105381 130581 105507
+rect 130995 105381 131045 105507
+rect 131145 105381 131201 106381
+rect 131301 105381 131357 106381
+rect 131457 105381 131513 106381
+rect 131613 105381 131663 106381
+rect 133848 105992 133898 106592
+rect 133998 105992 134048 106592
+rect 134120 105992 134170 106592
+rect 134270 105992 134320 106592
+rect 134396 105992 134446 106592
+rect 134546 105992 134596 106592
+rect 134668 105992 134718 106592
+rect 134818 105992 134868 106592
+rect 132804 105669 133110 105839
+rect 40797 104532 40798 104556
+rect 40878 104532 40879 104556
+rect 41351 104532 41352 104556
+rect 41432 104532 41433 104556
+rect 41905 104532 41906 104556
+rect 41986 104532 41987 104556
+rect 42459 104532 42460 104556
+rect 42540 104532 42541 104556
+rect 43013 104532 43014 104556
+rect 43094 104532 43095 104556
+rect 43567 104532 43568 104556
+rect 43648 104532 43649 104556
+rect 44121 104532 44122 104556
+rect 44202 104532 44203 104556
+rect 44675 104532 44676 104556
+rect 44756 104532 44757 104556
+rect 45229 104532 45230 104556
+rect 45310 104532 45311 104556
+rect 45783 104532 45784 104556
+rect 45864 104532 45865 104556
+rect 46337 104532 46338 104556
+rect 46418 104532 46419 104556
+rect 46891 104532 46892 104556
+rect 46972 104532 46973 104556
+rect 47445 104532 47446 104556
+rect 47526 104532 47527 104556
+rect 47999 104532 48000 104556
+rect 48080 104532 48081 104556
+rect 48553 104532 48554 104556
+rect 48634 104532 48635 104556
+rect 49107 104532 49108 104556
+rect 49188 104532 49189 104556
+rect 49661 104532 49662 104556
+rect 49742 104532 49743 104556
+rect 50215 104532 50216 104556
+rect 50296 104532 50297 104556
+rect 50769 104532 50770 104556
+rect 50850 104532 50851 104556
+rect 51323 104532 51324 104556
+rect 51404 104532 51405 104556
+rect 40821 104508 40855 104520
+rect 41375 104508 41409 104520
+rect 41929 104508 41963 104520
+rect 42483 104508 42517 104520
+rect 43037 104508 43071 104520
+rect 43591 104508 43625 104520
+rect 44145 104508 44179 104520
+rect 44699 104508 44733 104520
+rect 45253 104508 45287 104520
+rect 45807 104508 45841 104520
+rect 46361 104508 46395 104520
+rect 46915 104508 46949 104520
+rect 47469 104508 47503 104520
+rect 48023 104508 48057 104520
+rect 48577 104508 48611 104520
+rect 49131 104508 49165 104520
+rect 49685 104508 49719 104520
+rect 50239 104508 50273 104520
+rect 50793 104508 50827 104520
+rect 51347 104508 51381 104520
+rect 40797 102532 40798 102556
+rect 40878 102532 40879 102556
+rect 41351 102532 41352 102556
+rect 41432 102532 41433 102556
+rect 41905 102532 41906 102556
+rect 41986 102532 41987 102556
+rect 42459 102532 42460 102556
+rect 42540 102532 42541 102556
+rect 43013 102532 43014 102556
+rect 43094 102532 43095 102556
+rect 43567 102532 43568 102556
+rect 43648 102532 43649 102556
+rect 44121 102532 44122 102556
+rect 44202 102532 44203 102556
+rect 44675 102532 44676 102556
+rect 44756 102532 44757 102556
+rect 45229 102532 45230 102556
+rect 45310 102532 45311 102556
+rect 45783 102532 45784 102556
+rect 45864 102532 45865 102556
+rect 46337 102532 46338 102556
+rect 46418 102532 46419 102556
+rect 46891 102532 46892 102556
+rect 46972 102532 46973 102556
+rect 47445 102532 47446 102556
+rect 47526 102532 47527 102556
+rect 47999 102532 48000 102556
+rect 48080 102532 48081 102556
+rect 48553 102532 48554 102556
+rect 48634 102532 48635 102556
+rect 49107 102532 49108 102556
+rect 49188 102532 49189 102556
+rect 49661 102532 49662 102556
+rect 49742 102532 49743 102556
+rect 50215 102532 50216 102556
+rect 50296 102532 50297 102556
+rect 50769 102532 50770 102556
+rect 50850 102532 50851 102556
+rect 51323 102532 51324 102556
+rect 51404 102532 51405 102556
+rect 40821 102508 40855 102520
+rect 41375 102508 41409 102520
+rect 41929 102508 41963 102520
+rect 42483 102508 42517 102520
+rect 43037 102508 43071 102520
+rect 43591 102508 43625 102520
+rect 44145 102508 44179 102520
+rect 44699 102508 44733 102520
+rect 45253 102508 45287 102520
+rect 45807 102508 45841 102520
+rect 46361 102508 46395 102520
+rect 46915 102508 46949 102520
+rect 47469 102508 47503 102520
+rect 48023 102508 48057 102520
+rect 48577 102508 48611 102520
+rect 49131 102508 49165 102520
+rect 49685 102508 49719 102520
+rect 50239 102508 50273 102520
+rect 50793 102508 50827 102520
+rect 51347 102508 51381 102520
+rect 1823 101308 1824 101332
+rect 1904 101308 1905 101332
+rect 2377 101308 2378 101332
+rect 2458 101308 2459 101332
+rect 2931 101308 2932 101332
+rect 3012 101308 3013 101332
+rect 3485 101308 3486 101332
+rect 3566 101308 3567 101332
+rect 4039 101308 4040 101332
+rect 4120 101308 4121 101332
+rect 4593 101308 4594 101332
+rect 4674 101308 4675 101332
+rect 5147 101308 5148 101332
+rect 5228 101308 5229 101332
+rect 5701 101308 5702 101332
+rect 5782 101308 5783 101332
+rect 6255 101308 6256 101332
+rect 6336 101308 6337 101332
+rect 6809 101308 6810 101332
+rect 6890 101308 6891 101332
+rect 7363 101308 7364 101332
+rect 7444 101308 7445 101332
+rect 7917 101308 7918 101332
+rect 7998 101308 7999 101332
+rect 8471 101308 8472 101332
+rect 8552 101308 8553 101332
+rect 9025 101308 9026 101332
+rect 9106 101308 9107 101332
+rect 9579 101308 9580 101332
+rect 9660 101308 9661 101332
+rect 10133 101308 10134 101332
+rect 10214 101308 10215 101332
+rect 10687 101308 10688 101332
+rect 10768 101308 10769 101332
+rect 11241 101308 11242 101332
+rect 11322 101308 11323 101332
+rect 11795 101308 11796 101332
+rect 11876 101308 11877 101332
+rect 12349 101308 12350 101332
+rect 12430 101308 12431 101332
+rect 1847 101284 1881 101296
+rect 2401 101284 2435 101296
+rect 2955 101284 2989 101296
+rect 3509 101284 3543 101296
+rect 4063 101284 4097 101296
+rect 4617 101284 4651 101296
+rect 5171 101284 5205 101296
+rect 5725 101284 5759 101296
+rect 6279 101284 6313 101296
+rect 6833 101284 6867 101296
+rect 7387 101284 7421 101296
+rect 7941 101284 7975 101296
+rect 8495 101284 8529 101296
+rect 9049 101284 9083 101296
+rect 9603 101284 9637 101296
+rect 10157 101284 10191 101296
+rect 10711 101284 10745 101296
+rect 11265 101284 11299 101296
+rect 11819 101284 11853 101296
+rect 12373 101284 12407 101296
+rect 40797 100532 40798 100556
+rect 40878 100532 40879 100556
+rect 41351 100532 41352 100556
+rect 41432 100532 41433 100556
+rect 41905 100532 41906 100556
+rect 41986 100532 41987 100556
+rect 42459 100532 42460 100556
+rect 42540 100532 42541 100556
+rect 43013 100532 43014 100556
+rect 43094 100532 43095 100556
+rect 43567 100532 43568 100556
+rect 43648 100532 43649 100556
+rect 44121 100532 44122 100556
+rect 44202 100532 44203 100556
+rect 44675 100532 44676 100556
+rect 44756 100532 44757 100556
+rect 45229 100532 45230 100556
+rect 45310 100532 45311 100556
+rect 45783 100532 45784 100556
+rect 45864 100532 45865 100556
+rect 46337 100532 46338 100556
+rect 46418 100532 46419 100556
+rect 46891 100532 46892 100556
+rect 46972 100532 46973 100556
+rect 47445 100532 47446 100556
+rect 47526 100532 47527 100556
+rect 47999 100532 48000 100556
+rect 48080 100532 48081 100556
+rect 48553 100532 48554 100556
+rect 48634 100532 48635 100556
+rect 49107 100532 49108 100556
+rect 49188 100532 49189 100556
+rect 49661 100532 49662 100556
+rect 49742 100532 49743 100556
+rect 50215 100532 50216 100556
+rect 50296 100532 50297 100556
+rect 50769 100532 50770 100556
+rect 50850 100532 50851 100556
+rect 51323 100532 51324 100556
+rect 51404 100532 51405 100556
+rect 40821 100508 40855 100520
+rect 41375 100508 41409 100520
+rect 41929 100508 41963 100520
+rect 42483 100508 42517 100520
+rect 43037 100508 43071 100520
+rect 43591 100508 43625 100520
+rect 44145 100508 44179 100520
+rect 44699 100508 44733 100520
+rect 45253 100508 45287 100520
+rect 45807 100508 45841 100520
+rect 46361 100508 46395 100520
+rect 46915 100508 46949 100520
+rect 47469 100508 47503 100520
+rect 48023 100508 48057 100520
+rect 48577 100508 48611 100520
+rect 49131 100508 49165 100520
+rect 49685 100508 49719 100520
+rect 50239 100508 50273 100520
+rect 50793 100508 50827 100520
+rect 51347 100508 51381 100520
+rect 59624 100364 59696 104364
+rect 59895 100397 60013 104331
+rect 60284 100364 60344 104364
+rect 60544 100364 60616 104364
+rect 60815 100397 60933 104331
+rect 61204 100364 61264 104364
+rect 61464 100364 61536 104364
+rect 61735 100397 61853 104331
+rect 62124 100364 62184 104364
+rect 62384 100364 62456 104364
+rect 62655 100397 62773 104331
+rect 63044 100364 63104 104364
+rect 63304 100364 63376 104364
+rect 63575 100397 63693 104331
+rect 63964 100364 64024 104364
+rect 64224 100364 64296 104364
+rect 64495 100397 64613 104331
+rect 64884 100364 64944 104364
+rect 65144 100364 65216 104364
+rect 65415 100397 65533 104331
+rect 65804 100364 65864 104364
+rect 66064 100364 66136 104364
+rect 66335 100397 66453 104331
+rect 66724 100364 66784 104364
+rect 66984 100364 67056 104364
+rect 67255 100397 67373 104331
+rect 67644 100364 67704 104364
+rect 67904 100364 67976 104364
+rect 68175 100397 68293 104331
+rect 68564 100364 68624 104364
+rect 68824 100364 68896 104364
+rect 69095 100397 69213 104331
+rect 69484 100364 69544 104364
+rect 80176 101334 80248 105334
+rect 80447 101367 80565 105301
+rect 80836 101334 80896 105334
+rect 81096 101334 81168 105334
+rect 81367 101367 81485 105301
+rect 81756 101334 81816 105334
+rect 82016 101334 82088 105334
+rect 82287 101367 82405 105301
+rect 82676 101334 82736 105334
+rect 82936 101334 83008 105334
+rect 83207 101367 83325 105301
+rect 83596 101334 83656 105334
+rect 83856 101334 83928 105334
+rect 84127 101367 84245 105301
+rect 84516 101334 84576 105334
+rect 84776 101334 84848 105334
+rect 85047 101367 85165 105301
+rect 85436 101334 85496 105334
+rect 85696 101334 85768 105334
+rect 85967 101367 86085 105301
+rect 86356 101334 86416 105334
+rect 86616 101334 86688 105334
+rect 86887 101367 87005 105301
+rect 87276 101334 87336 105334
+rect 87536 101334 87608 105334
+rect 87807 101367 87925 105301
+rect 88196 101334 88256 105334
+rect 88456 101334 88528 105334
+rect 88727 101367 88845 105301
+rect 89116 101334 89176 105334
+rect 89376 101334 89448 105334
+rect 89647 101367 89765 105301
+rect 90036 101334 90096 105334
+rect 130062 105043 130112 105159
+rect 130059 104959 130112 105043
+rect 130232 104959 130360 105159
+rect 130408 104959 130464 105159
+rect 130584 104959 130712 105159
+rect 130760 104959 130816 105159
+rect 130936 104959 131064 105159
+rect 131112 104959 131168 105159
+rect 131288 104959 131416 105159
+rect 131464 105043 131514 105159
+rect 133925 105105 134925 105155
+rect 131464 104959 131517 105043
+rect 130067 104955 130101 104959
+rect 131475 104955 131509 104959
+rect 133925 104949 134925 105077
+rect 133925 104793 134925 104921
+rect 130000 104645 131000 104695
+rect 132192 104645 133192 104695
+rect 133925 104637 134925 104765
+rect 122363 104026 122413 104626
+rect 122513 104026 122563 104626
+rect 122643 104026 122693 104626
+rect 122793 104026 122921 104626
+rect 122949 104026 123077 104626
+rect 123105 104026 123161 104626
+rect 123261 104026 123389 104626
+rect 123417 104026 123545 104626
+rect 123573 104026 123623 104626
+rect 130000 104489 131000 104545
+rect 132192 104489 133192 104545
+rect 133925 104481 134925 104609
+rect 131338 104405 131422 104408
+rect 130000 104333 131000 104389
+rect 131222 104355 131422 104405
+rect 131770 104405 131854 104408
+rect 131770 104400 131970 104405
+rect 131766 104366 131970 104400
+rect 131770 104355 131970 104366
+rect 132192 104333 133192 104389
+rect 133925 104325 134925 104453
+rect 130000 104177 131000 104233
+rect 131222 104179 131422 104307
+rect 131770 104179 131970 104307
+rect 132192 104177 133192 104233
+rect 133925 104169 134925 104297
+rect 130000 104021 131000 104077
+rect 131222 104003 131422 104059
+rect 131770 104003 131970 104059
+rect 132192 104021 133192 104077
+rect 133925 104013 134925 104141
+rect 130000 103871 131000 103921
+rect 130458 103868 130542 103871
+rect 130790 103868 130874 103871
+rect 131222 103827 131422 103955
+rect 131770 103827 131970 103955
+rect 132192 103871 133192 103921
+rect 132318 103868 132402 103871
+rect 132650 103868 132734 103871
+rect 133925 103857 134925 103985
+rect 99739 103696 99740 103720
+rect 99820 103696 99821 103720
+rect 100293 103696 100294 103720
+rect 100374 103696 100375 103720
+rect 100847 103696 100848 103720
+rect 100928 103696 100929 103720
+rect 101401 103696 101402 103720
+rect 101482 103696 101483 103720
+rect 101955 103696 101956 103720
+rect 102036 103696 102037 103720
+rect 102509 103696 102510 103720
+rect 102590 103696 102591 103720
+rect 103063 103696 103064 103720
+rect 103144 103696 103145 103720
+rect 103617 103696 103618 103720
+rect 103698 103696 103699 103720
+rect 104171 103696 104172 103720
+rect 104252 103696 104253 103720
+rect 104725 103696 104726 103720
+rect 104806 103696 104807 103720
+rect 105279 103696 105280 103720
+rect 105360 103696 105361 103720
+rect 105833 103696 105834 103720
+rect 105914 103696 105915 103720
+rect 106387 103696 106388 103720
+rect 106468 103696 106469 103720
+rect 106941 103696 106942 103720
+rect 107022 103696 107023 103720
+rect 107495 103696 107496 103720
+rect 107576 103696 107577 103720
+rect 108049 103696 108050 103720
+rect 108130 103696 108131 103720
+rect 108603 103696 108604 103720
+rect 108684 103696 108685 103720
+rect 109157 103696 109158 103720
+rect 109238 103696 109239 103720
+rect 109711 103696 109712 103720
+rect 109792 103696 109793 103720
+rect 110265 103696 110266 103720
+rect 110346 103696 110347 103720
+rect 99763 103672 99797 103684
+rect 100317 103672 100351 103684
+rect 100871 103672 100905 103684
+rect 101425 103672 101459 103684
+rect 101979 103672 102013 103684
+rect 102533 103672 102567 103684
+rect 103087 103672 103121 103684
+rect 103641 103672 103675 103684
+rect 104195 103672 104229 103684
+rect 104749 103672 104783 103684
+rect 105303 103672 105337 103684
+rect 105857 103672 105891 103684
+rect 106411 103672 106445 103684
+rect 106965 103672 106999 103684
+rect 107519 103672 107553 103684
+rect 108073 103672 108107 103684
+rect 108627 103672 108661 103684
+rect 109181 103672 109215 103684
+rect 109735 103672 109769 103684
+rect 110289 103672 110323 103684
+rect 125664 103634 125698 103668
+rect 125733 103634 125767 103668
+rect 125802 103634 125836 103668
+rect 125871 103634 125905 103668
+rect 125940 103634 125974 103668
+rect 126009 103634 126043 103668
+rect 126078 103634 126112 103668
+rect 126147 103634 126181 103668
+rect 126216 103634 126250 103668
+rect 126285 103634 126319 103668
+rect 126354 103634 126388 103668
+rect 126423 103634 126457 103668
+rect 126492 103634 126526 103668
+rect 126561 103634 126595 103668
+rect 126630 103634 126664 103668
+rect 126699 103634 126733 103668
+rect 126768 103634 126802 103668
+rect 126837 103634 126871 103668
+rect 126906 103634 126940 103668
+rect 126975 103634 127009 103668
+rect 127044 103634 127078 103668
+rect 127113 103634 127147 103668
+rect 127182 103634 127216 103668
+rect 127251 103634 127285 103668
+rect 127320 103634 127354 103668
+rect 127389 103634 127423 103668
+rect 127458 103634 127492 103668
+rect 127527 103634 127561 103668
+rect 127596 103634 127630 103668
+rect 127665 103634 127699 103668
+rect 127734 103635 127763 103668
+rect 131222 103657 131422 103707
+rect 131770 103657 131970 103707
+rect 133925 103701 134925 103829
+rect 127734 103634 127797 103635
+rect 125664 103610 125688 103634
+rect 133925 103545 134925 103673
+rect 133925 103389 134925 103517
+rect 133925 103233 134925 103361
+rect 133925 103077 134925 103205
+rect 133925 102927 134925 102977
+rect 128376 102515 128400 102539
+rect 128436 102515 128460 102539
+rect 130751 102515 130775 102539
+rect 130810 102515 130834 102539
+rect 127858 102481 128306 102515
+rect 128412 102491 128424 102515
+rect 130786 102491 130799 102515
+rect 130904 102481 131352 102515
+rect 128414 102427 128448 102437
+rect 128390 102416 128448 102427
+rect 126030 102403 128448 102416
+rect 130796 102416 130830 102437
+rect 131423 102427 131457 102437
+rect 131399 102416 131457 102427
+rect 130796 102403 131457 102416
+rect 126030 102395 128414 102403
+rect 130796 102395 131423 102403
+rect 133133 102402 133157 102426
+rect 126030 102386 131613 102395
+rect 133062 102386 133133 102392
+rect 126030 102365 131583 102386
+rect 133109 102378 133133 102386
+rect 99739 101696 99740 101720
+rect 99820 101696 99821 101720
+rect 100293 101696 100294 101720
+rect 100374 101696 100375 101720
+rect 100847 101696 100848 101720
+rect 100928 101696 100929 101720
+rect 101401 101696 101402 101720
+rect 101482 101696 101483 101720
+rect 101955 101696 101956 101720
+rect 102036 101696 102037 101720
+rect 102509 101696 102510 101720
+rect 102590 101696 102591 101720
+rect 103063 101696 103064 101720
+rect 103144 101696 103145 101720
+rect 103617 101696 103618 101720
+rect 103698 101696 103699 101720
+rect 104171 101696 104172 101720
+rect 104252 101696 104253 101720
+rect 104725 101696 104726 101720
+rect 104806 101696 104807 101720
+rect 105279 101696 105280 101720
+rect 105360 101696 105361 101720
+rect 105833 101696 105834 101720
+rect 105914 101696 105915 101720
+rect 106387 101696 106388 101720
+rect 106468 101696 106469 101720
+rect 106941 101696 106942 101720
+rect 107022 101696 107023 101720
+rect 107495 101696 107496 101720
+rect 107576 101696 107577 101720
+rect 108049 101696 108050 101720
+rect 108130 101696 108131 101720
+rect 108603 101696 108604 101720
+rect 108684 101696 108685 101720
+rect 109157 101696 109158 101720
+rect 109238 101696 109239 101720
+rect 109711 101696 109712 101720
+rect 109792 101696 109793 101720
+rect 110265 101696 110266 101720
+rect 110346 101696 110347 101720
+rect 99763 101672 99797 101684
+rect 100317 101672 100351 101684
+rect 100871 101672 100905 101684
+rect 101425 101672 101459 101684
+rect 101979 101672 102013 101684
+rect 102533 101672 102567 101684
+rect 103087 101672 103121 101684
+rect 103641 101672 103675 101684
+rect 104195 101672 104229 101684
+rect 104749 101672 104783 101684
+rect 105303 101672 105337 101684
+rect 105857 101672 105891 101684
+rect 106411 101672 106445 101684
+rect 106965 101672 106999 101684
+rect 107519 101672 107553 101684
+rect 108073 101672 108107 101684
+rect 108627 101672 108661 101684
+rect 109181 101672 109215 101684
+rect 109735 101672 109769 101684
+rect 110289 101672 110323 101684
+rect 121250 101546 121300 102146
+rect 121420 101546 121476 102146
+rect 121596 101546 121646 102146
+rect 119951 101460 119975 101484
+rect 120012 101474 120036 101484
+rect 120012 101470 120046 101474
+rect 120083 101470 120117 101474
+rect 120154 101470 120188 101474
+rect 119990 101460 120212 101470
+rect 119988 101456 119999 101460
+rect 120012 101456 120046 101460
+rect 120083 101456 120117 101460
+rect 120154 101456 120188 101460
+rect 119988 101436 120212 101456
+rect 120012 101416 120036 101436
+rect 121735 101324 121785 102324
+rect 121885 101324 121935 102324
+rect 122044 101324 122094 102324
+rect 122194 101324 122244 102324
+rect 122374 101864 122554 102064
+rect 122719 102049 122779 102064
+rect 122805 102049 122865 102064
+rect 124379 102049 124439 102064
+rect 124465 102049 124525 102064
+rect 122734 101879 122764 102049
+rect 122820 101879 122850 102049
+rect 124394 101879 124424 102049
+rect 124480 101879 124510 102049
+rect 122723 101876 122775 101879
+rect 122809 101876 122861 101879
+rect 124383 101876 124435 101879
+rect 124469 101876 124521 101879
+rect 122719 101864 122779 101876
+rect 122805 101864 122865 101876
+rect 124379 101864 124439 101876
+rect 124465 101864 124525 101876
+rect 124690 101864 124870 102064
+rect 122374 101604 122554 101804
+rect 122719 101789 122779 101804
+rect 122805 101789 122865 101804
+rect 124379 101789 124439 101804
+rect 124465 101789 124525 101804
+rect 122734 101619 122764 101789
+rect 122820 101619 122850 101789
+rect 124394 101619 124424 101789
+rect 124480 101619 124510 101789
+rect 122723 101616 122775 101619
+rect 122809 101616 122861 101619
+rect 124383 101616 124435 101619
+rect 124469 101616 124521 101619
+rect 122719 101604 122779 101616
+rect 122805 101604 122865 101616
+rect 124379 101604 124439 101616
+rect 124465 101604 124525 101616
+rect 124690 101604 124870 101804
+rect 122374 101344 122554 101544
+rect 122719 101529 122779 101544
+rect 122805 101529 122865 101544
+rect 124379 101529 124439 101544
+rect 124465 101529 124525 101544
+rect 122734 101524 122764 101529
+rect 122820 101524 122850 101529
+rect 124394 101524 124424 101529
+rect 124480 101524 124510 101529
+rect 124690 101344 124870 101544
+rect 125000 101324 125050 102324
+rect 125150 101324 125200 102324
+rect 125309 101324 125359 102324
+rect 125459 101324 125509 102324
+rect 126787 102302 132608 102338
+rect 126787 102290 126823 102302
+rect 126873 102290 126907 102302
+rect 126942 102290 126976 102302
+rect 127011 102290 127045 102302
+rect 127080 102290 127114 102302
+rect 127149 102290 127183 102302
+rect 127218 102290 127252 102302
+rect 127287 102290 127321 102302
+rect 127356 102290 127390 102302
+rect 127425 102290 127459 102302
+rect 127494 102290 127528 102302
+rect 127563 102290 127597 102302
+rect 127632 102290 127666 102302
+rect 127701 102290 127735 102302
+rect 127770 102290 127804 102302
+rect 127839 102290 127873 102302
+rect 127908 102290 127942 102302
+rect 127977 102290 128011 102302
+rect 128046 102290 128080 102302
+rect 128115 102290 128149 102302
+rect 128184 102290 128218 102302
+rect 128253 102290 128287 102302
+rect 128322 102290 128356 102302
+rect 128391 102290 128425 102302
+rect 128460 102290 128494 102302
+rect 128529 102290 128563 102302
+rect 128598 102290 128632 102302
+rect 128667 102290 128701 102302
+rect 128736 102290 128770 102302
+rect 128805 102290 128839 102302
+rect 128874 102290 128908 102302
+rect 128943 102290 128977 102302
+rect 129012 102290 129046 102302
+rect 129081 102290 129115 102302
+rect 129150 102290 129184 102302
+rect 129219 102290 129253 102302
+rect 129288 102290 129322 102302
+rect 129357 102290 129391 102302
+rect 129426 102290 129460 102302
+rect 129495 102290 129529 102302
+rect 129564 102290 129598 102302
+rect 129633 102290 129667 102302
+rect 129702 102290 129736 102302
+rect 129771 102290 129805 102302
+rect 129840 102290 129874 102302
+rect 129909 102290 129943 102302
+rect 129978 102290 130012 102302
+rect 130047 102290 130081 102302
+rect 130116 102290 130150 102302
+rect 130185 102290 130219 102302
+rect 130254 102290 130288 102302
+rect 130323 102290 130357 102302
+rect 130392 102290 130426 102302
+rect 130461 102290 130495 102302
+rect 130530 102290 130564 102302
+rect 130599 102290 130633 102302
+rect 130668 102290 130702 102302
+rect 130737 102290 130771 102302
+rect 130806 102290 130840 102302
+rect 130875 102290 130909 102302
+rect 130944 102290 130978 102302
+rect 131013 102290 131047 102302
+rect 131082 102290 131116 102302
+rect 131151 102290 131185 102302
+rect 131220 102290 131254 102302
+rect 131289 102290 131323 102302
+rect 131358 102290 131392 102302
+rect 131426 102290 131460 102302
+rect 131494 102290 131528 102302
+rect 131562 102290 131596 102302
+rect 131630 102290 131664 102302
+rect 131698 102290 131732 102302
+rect 131766 102290 131800 102302
+rect 131834 102290 131868 102302
+rect 131902 102290 131936 102302
+rect 131970 102290 132004 102302
+rect 132038 102290 132072 102302
+rect 132106 102290 132140 102302
+rect 132174 102290 132208 102302
+rect 132242 102290 132276 102302
+rect 132310 102290 132344 102302
+rect 132378 102290 132412 102302
+rect 132446 102290 132480 102302
+rect 132514 102290 132548 102302
+rect 132572 102290 132608 102302
+rect 126787 102254 126839 102290
+rect 125598 101546 125648 102146
+rect 125768 101546 125824 102146
+rect 125944 101546 125994 102146
+rect 126823 101599 126839 102254
+rect 126803 101596 126839 101599
+rect 126849 101596 126885 102290
+rect 126907 102254 126942 102290
+rect 126976 102254 127011 102290
+rect 127045 102254 127080 102290
+rect 127114 102254 127149 102290
+rect 127183 102254 127218 102290
+rect 127252 102254 127287 102290
+rect 127321 102254 127356 102290
+rect 127390 102254 127425 102290
+rect 127459 102254 127494 102290
+rect 127528 102254 127563 102290
+rect 127597 102254 127632 102290
+rect 127666 102254 127701 102290
+rect 127735 102254 127770 102290
+rect 127804 102254 127839 102290
+rect 127873 102254 127908 102290
+rect 127942 102254 127977 102290
+rect 128011 102254 128046 102290
+rect 128080 102254 128115 102290
+rect 128149 102254 128184 102290
+rect 128218 102254 128253 102290
+rect 128287 102254 128322 102290
+rect 128356 102254 128391 102290
+rect 128425 102254 128460 102290
+rect 128494 102254 128529 102290
+rect 128563 102254 128598 102290
+rect 128632 102254 128667 102290
+rect 128701 102254 128736 102290
+rect 128770 102254 128805 102290
+rect 128839 102254 128874 102290
+rect 128908 102254 128943 102290
+rect 128977 102254 129012 102290
+rect 129046 102254 129081 102290
+rect 129115 102254 129150 102290
+rect 129184 102254 129219 102290
+rect 129253 102254 129288 102290
+rect 129322 102254 129357 102290
+rect 129391 102254 129426 102290
+rect 129460 102254 129495 102290
+rect 129529 102254 129564 102290
+rect 129598 102254 129633 102290
+rect 129667 102254 129702 102290
+rect 129736 102254 129771 102290
+rect 129805 102254 129840 102290
+rect 129874 102254 129909 102290
+rect 129943 102254 129978 102290
+rect 130012 102254 130047 102290
+rect 130081 102254 130116 102290
+rect 130150 102254 130185 102290
+rect 130219 102254 130254 102290
+rect 130288 102254 130323 102290
+rect 130357 102254 130392 102290
+rect 130426 102254 130461 102290
+rect 130495 102254 130530 102290
+rect 130564 102254 130599 102290
+rect 130633 102254 130668 102290
+rect 130702 102254 130737 102290
+rect 130771 102254 130806 102290
+rect 130840 102254 130875 102290
+rect 130909 102254 130944 102290
+rect 130978 102254 131013 102290
+rect 131047 102254 131082 102290
+rect 131116 102254 131151 102290
+rect 131185 102254 131220 102290
+rect 131254 102254 131289 102290
+rect 131323 102254 131358 102290
+rect 131392 102254 131426 102290
+rect 131460 102254 131494 102290
+rect 131528 102254 131562 102290
+rect 131596 102254 131630 102290
+rect 131664 102254 131698 102290
+rect 131732 102254 131766 102290
+rect 131800 102254 131834 102290
+rect 131868 102254 131902 102290
+rect 131936 102254 131970 102290
+rect 132004 102254 132038 102290
+rect 132072 102254 132106 102290
+rect 132140 102254 132174 102290
+rect 132208 102254 132242 102290
+rect 132276 102254 132310 102290
+rect 132344 102254 132378 102290
+rect 132412 102254 132446 102290
+rect 132480 102254 132514 102290
+rect 132548 102254 132608 102290
+rect 126803 101560 126885 101596
+rect 126983 101582 127033 102182
+rect 127153 101582 127209 102182
+rect 127329 101582 127379 102182
+rect 127445 101582 127495 102182
+rect 127615 101582 127671 102182
+rect 127791 101582 127919 102182
+rect 127967 101582 128095 102182
+rect 128143 101582 128271 102182
+rect 128319 101582 128369 102182
+rect 128435 101582 128485 102182
+rect 128605 101582 128733 102182
+rect 128781 101582 128837 102182
+rect 128957 101582 129085 102182
+rect 129133 101582 129183 102182
+rect 129249 101582 129299 102182
+rect 129419 101582 129547 102182
+rect 129595 101582 129723 102182
+rect 129771 101582 129899 102182
+rect 129947 101582 130075 102182
+rect 130123 101582 130251 102182
+rect 130299 101582 130355 102182
+rect 130475 101582 130603 102182
+rect 130651 101582 130779 102182
+rect 130827 101582 130955 102182
+rect 131003 101582 131131 102182
+rect 131179 101582 131307 102182
+rect 131355 101582 131411 102182
+rect 131531 101582 131659 102182
+rect 131707 101582 131763 102182
+rect 131883 101582 132011 102182
+rect 132059 101582 132115 102182
+rect 132235 101582 132363 102182
+rect 132411 101582 132461 102182
+rect 133886 101872 134066 102072
+rect 134122 101872 134302 102072
+rect 133886 101737 134066 101774
+rect 134573 101472 134623 102072
+rect 134743 101472 134799 102072
+rect 134919 101472 134975 102072
+rect 135095 101472 135145 102072
+rect 122374 101030 122554 101230
+rect 124690 101030 124870 101230
+rect 120738 100254 120788 100854
+rect 120888 100254 120944 100854
+rect 121044 100254 121094 100854
+rect 121778 100770 121958 100970
+rect 122014 100770 122194 100970
+rect 122374 100770 122554 100970
+rect 122719 100955 122779 100970
+rect 122805 100955 122865 100970
+rect 124379 100955 124439 100970
+rect 124465 100955 124525 100970
+rect 122734 100785 122764 100955
+rect 122820 100785 122850 100955
+rect 122975 100836 123063 100872
+rect 122975 100832 123011 100836
+rect 123027 100832 123063 100836
+rect 123011 100798 123063 100832
+rect 122723 100782 122775 100785
+rect 122809 100782 122861 100785
+rect 122719 100770 122779 100782
+rect 122805 100770 122865 100782
+rect 122975 100764 123011 100798
+rect 123027 100764 123063 100798
+rect 123011 100730 123063 100764
+rect 121778 100510 121958 100710
+rect 122014 100510 122194 100710
+rect 122374 100510 122554 100710
+rect 122719 100695 122779 100710
+rect 122805 100695 122865 100710
+rect 122975 100696 123011 100730
+rect 123027 100696 123063 100730
+rect 122734 100525 122764 100695
+rect 122820 100525 122850 100695
+rect 123011 100662 123063 100696
+rect 122975 100628 123011 100662
+rect 123027 100628 123063 100662
+rect 123011 100594 123063 100628
+rect 122975 100560 123011 100594
+rect 123027 100560 123063 100594
+rect 123011 100526 123063 100560
+rect 122723 100522 122775 100525
+rect 122809 100522 122861 100525
+rect 122719 100510 122779 100522
+rect 122805 100510 122865 100522
+rect 122975 100494 123011 100526
+rect 123027 100520 123063 100526
+rect 122374 100250 122554 100450
+rect 122719 100435 122779 100450
+rect 122805 100435 122865 100450
+rect 122734 100396 122764 100435
+rect 122820 100396 122850 100435
+rect 122977 100256 123011 100494
+rect 123015 100484 123063 100520
+rect 124179 100836 124269 100872
+rect 124179 100520 124215 100836
+rect 124233 100520 124269 100836
+rect 124394 100785 124424 100955
+rect 124480 100785 124510 100955
+rect 124383 100782 124435 100785
+rect 124469 100782 124521 100785
+rect 124379 100770 124439 100782
+rect 124465 100770 124525 100782
+rect 124690 100770 124870 100970
+rect 125050 100770 125230 100970
+rect 125286 100770 125466 100970
+rect 124379 100695 124439 100710
+rect 124465 100695 124525 100710
+rect 124394 100525 124424 100695
+rect 124480 100525 124510 100695
+rect 124383 100522 124435 100525
+rect 124469 100522 124521 100525
+rect 124179 100484 124269 100520
+rect 124379 100510 124439 100522
+rect 124465 100510 124525 100522
+rect 124690 100510 124870 100710
+rect 125050 100510 125230 100710
+rect 125286 100510 125466 100710
+rect 123015 100256 123051 100484
+rect 124235 100256 124267 100484
+rect 124379 100435 124439 100450
+rect 124465 100435 124525 100450
+rect 124394 100396 124424 100435
+rect 124480 100396 124510 100435
+rect 122975 100220 123051 100256
+rect 124690 100250 124870 100450
+rect 126150 100254 126200 100854
+rect 126300 100254 126356 100854
+rect 126456 100254 126506 100854
+rect 127003 100268 127053 101268
+rect 127153 100268 127209 101268
+rect 127309 100268 127359 101268
+rect 127445 100268 127495 101268
+rect 127595 100268 127651 101268
+rect 127751 100268 127807 101268
+rect 127907 100268 127963 101268
+rect 128063 100268 128113 101268
+rect 128179 100268 128229 101268
+rect 128329 100268 128457 101268
+rect 128485 100268 128613 101268
+rect 128641 100268 128769 101268
+rect 128797 100268 128925 101268
+rect 128953 100268 129081 101268
+rect 129109 100268 129165 101268
+rect 129265 100268 129393 101268
+rect 129421 100268 129549 101268
+rect 129577 100268 129705 101268
+rect 129733 100268 129861 101268
+rect 129889 100268 130017 101268
+rect 130045 100268 130101 101268
+rect 130221 100268 130349 101268
+rect 130397 100268 130525 101268
+rect 130573 100268 130701 101268
+rect 130749 100268 130877 101268
+rect 130925 100268 131053 101268
+rect 131101 100268 131229 101268
+rect 131277 100268 131405 101268
+rect 131453 100268 131503 101268
+rect 131569 100268 131619 101268
+rect 131719 100268 131847 101268
+rect 131875 100268 132003 101268
+rect 132031 100268 132159 101268
+rect 132187 100268 132243 101268
+rect 132343 100268 132471 101268
+rect 132499 100268 132627 101268
+rect 132655 100268 132783 101268
+rect 132811 100268 132861 101268
+rect 133452 100709 133505 100859
+rect 133455 100612 133505 100709
+rect 133452 100390 133505 100612
+rect 133455 100259 133505 100390
+rect 133625 100259 133681 100859
+rect 133801 100259 133851 100859
+rect 134227 100264 134277 100864
+rect 134397 100264 134447 100864
+rect 1823 99308 1824 99332
+rect 1904 99308 1905 99332
+rect 2377 99308 2378 99332
+rect 2458 99308 2459 99332
+rect 2931 99308 2932 99332
+rect 3012 99308 3013 99332
+rect 3485 99308 3486 99332
+rect 3566 99308 3567 99332
+rect 4039 99308 4040 99332
+rect 4120 99308 4121 99332
+rect 4593 99308 4594 99332
+rect 4674 99308 4675 99332
+rect 5147 99308 5148 99332
+rect 5228 99308 5229 99332
+rect 5701 99308 5702 99332
+rect 5782 99308 5783 99332
+rect 6255 99308 6256 99332
+rect 6336 99308 6337 99332
+rect 6809 99308 6810 99332
+rect 6890 99308 6891 99332
+rect 7363 99308 7364 99332
+rect 7444 99308 7445 99332
+rect 7917 99308 7918 99332
+rect 7998 99308 7999 99332
+rect 8471 99308 8472 99332
+rect 8552 99308 8553 99332
+rect 9025 99308 9026 99332
+rect 9106 99308 9107 99332
+rect 9579 99308 9580 99332
+rect 9660 99308 9661 99332
+rect 10133 99308 10134 99332
+rect 10214 99308 10215 99332
+rect 10687 99308 10688 99332
+rect 10768 99308 10769 99332
+rect 11241 99308 11242 99332
+rect 11322 99308 11323 99332
+rect 11795 99308 11796 99332
+rect 11876 99308 11877 99332
+rect 12349 99308 12350 99332
+rect 12430 99308 12431 99332
+rect 1847 99284 1881 99296
+rect 2401 99284 2435 99296
+rect 2955 99284 2989 99296
+rect 3509 99284 3543 99296
+rect 4063 99284 4097 99296
+rect 4617 99284 4651 99296
+rect 5171 99284 5205 99296
+rect 5725 99284 5759 99296
+rect 6279 99284 6313 99296
+rect 6833 99284 6867 99296
+rect 7387 99284 7421 99296
+rect 7941 99284 7975 99296
+rect 8495 99284 8529 99296
+rect 9049 99284 9083 99296
+rect 9603 99284 9637 99296
+rect 10157 99284 10191 99296
+rect 10711 99284 10745 99296
+rect 11265 99284 11299 99296
+rect 11819 99284 11853 99296
+rect 12373 99284 12407 99296
+rect 20904 98024 20954 99424
+rect 21054 98024 21182 99424
+rect 21210 98024 21338 99424
+rect 21366 98024 21494 99424
+rect 21522 98024 21650 99424
+rect 21678 98024 21806 99424
+rect 21834 98024 21962 99424
+rect 21990 98024 22118 99424
+rect 22146 98024 22274 99424
+rect 22302 98024 22430 99424
+rect 22458 98024 22586 99424
+rect 22614 98024 22742 99424
+rect 22770 98024 22898 99424
+rect 22926 98024 23054 99424
+rect 23082 98024 23210 99424
+rect 23238 98024 23366 99424
+rect 23394 98024 23522 99424
+rect 23550 98024 23678 99424
+rect 23706 98024 23834 99424
+rect 23862 98024 23990 99424
+rect 24018 98024 24146 99424
+rect 24174 98024 24302 99424
+rect 24330 98024 24458 99424
+rect 24486 98024 24614 99424
+rect 24642 98024 24770 99424
+rect 24798 98024 24926 99424
+rect 24954 98024 25082 99424
+rect 25110 98024 25238 99424
+rect 25266 98024 25394 99424
+rect 25422 98024 25550 99424
+rect 25578 98024 25706 99424
+rect 25734 98024 25862 99424
+rect 25890 98024 26018 99424
+rect 26046 98024 26174 99424
+rect 26202 98024 26330 99424
+rect 26358 98024 26486 99424
+rect 26514 98024 26642 99424
+rect 26670 98024 26798 99424
+rect 26826 98024 26954 99424
+rect 26982 98024 27110 99424
+rect 27138 98024 27266 99424
+rect 27294 98024 27422 99424
+rect 27450 98024 27578 99424
+rect 27606 98024 27734 99424
+rect 27762 98024 27890 99424
+rect 27918 98024 28046 99424
+rect 28074 98024 28202 99424
+rect 28230 98024 28358 99424
+rect 28386 98024 28514 99424
+rect 28542 98024 28670 99424
+rect 28698 98024 28748 99424
+rect 30619 98580 30669 99980
+rect 30769 98580 30897 99980
+rect 30925 98580 31053 99980
+rect 31081 98580 31209 99980
+rect 31237 98580 31365 99980
+rect 31393 98580 31521 99980
+rect 31549 98580 31677 99980
+rect 31705 98580 31833 99980
+rect 31861 98580 31989 99980
+rect 32017 98580 32145 99980
+rect 32173 98580 32301 99980
+rect 32329 98580 32457 99980
+rect 32485 98580 32613 99980
+rect 32641 98580 32769 99980
+rect 32797 98580 32925 99980
+rect 32953 98580 33003 99980
+rect 40797 98532 40798 98556
+rect 40878 98532 40879 98556
+rect 41351 98532 41352 98556
+rect 41432 98532 41433 98556
+rect 41905 98532 41906 98556
+rect 41986 98532 41987 98556
+rect 42459 98532 42460 98556
+rect 42540 98532 42541 98556
+rect 43013 98532 43014 98556
+rect 43094 98532 43095 98556
+rect 43567 98532 43568 98556
+rect 43648 98532 43649 98556
+rect 44121 98532 44122 98556
+rect 44202 98532 44203 98556
+rect 44675 98532 44676 98556
+rect 44756 98532 44757 98556
+rect 45229 98532 45230 98556
+rect 45310 98532 45311 98556
+rect 45783 98532 45784 98556
+rect 45864 98532 45865 98556
+rect 46337 98532 46338 98556
+rect 46418 98532 46419 98556
+rect 46891 98532 46892 98556
+rect 46972 98532 46973 98556
+rect 47445 98532 47446 98556
+rect 47526 98532 47527 98556
+rect 47999 98532 48000 98556
+rect 48080 98532 48081 98556
+rect 48553 98532 48554 98556
+rect 48634 98532 48635 98556
+rect 49107 98532 49108 98556
+rect 49188 98532 49189 98556
+rect 49661 98532 49662 98556
+rect 49742 98532 49743 98556
+rect 50215 98532 50216 98556
+rect 50296 98532 50297 98556
+rect 50769 98532 50770 98556
+rect 50850 98532 50851 98556
+rect 51323 98532 51324 98556
+rect 51404 98532 51405 98556
+rect 40821 98508 40855 98520
+rect 41375 98508 41409 98520
+rect 41929 98508 41963 98520
+rect 42483 98508 42517 98520
+rect 43037 98508 43071 98520
+rect 43591 98508 43625 98520
+rect 44145 98508 44179 98520
+rect 44699 98508 44733 98520
+rect 45253 98508 45287 98520
+rect 45807 98508 45841 98520
+rect 46361 98508 46395 98520
+rect 46915 98508 46949 98520
+rect 47469 98508 47503 98520
+rect 48023 98508 48057 98520
+rect 48577 98508 48611 98520
+rect 49131 98508 49165 98520
+rect 49685 98508 49719 98520
+rect 50239 98508 50273 98520
+rect 50793 98508 50827 98520
+rect 51347 98508 51381 98520
+rect 1823 97308 1824 97332
+rect 1904 97308 1905 97332
+rect 2377 97308 2378 97332
+rect 2458 97308 2459 97332
+rect 2931 97308 2932 97332
+rect 3012 97308 3013 97332
+rect 3485 97308 3486 97332
+rect 3566 97308 3567 97332
+rect 4039 97308 4040 97332
+rect 4120 97308 4121 97332
+rect 4593 97308 4594 97332
+rect 4674 97308 4675 97332
+rect 5147 97308 5148 97332
+rect 5228 97308 5229 97332
+rect 5701 97308 5702 97332
+rect 5782 97308 5783 97332
+rect 6255 97308 6256 97332
+rect 6336 97308 6337 97332
+rect 6809 97308 6810 97332
+rect 6890 97308 6891 97332
+rect 7363 97308 7364 97332
+rect 7444 97308 7445 97332
+rect 7917 97308 7918 97332
+rect 7998 97308 7999 97332
+rect 8471 97308 8472 97332
+rect 8552 97308 8553 97332
+rect 9025 97308 9026 97332
+rect 9106 97308 9107 97332
+rect 9579 97308 9580 97332
+rect 9660 97308 9661 97332
+rect 10133 97308 10134 97332
+rect 10214 97308 10215 97332
+rect 10687 97308 10688 97332
+rect 10768 97308 10769 97332
+rect 11241 97308 11242 97332
+rect 11322 97308 11323 97332
+rect 11795 97308 11796 97332
+rect 11876 97308 11877 97332
+rect 12349 97308 12350 97332
+rect 12430 97308 12431 97332
+rect 1847 97284 1881 97296
+rect 2401 97284 2435 97296
+rect 2955 97284 2989 97296
+rect 3509 97284 3543 97296
+rect 4063 97284 4097 97296
+rect 4617 97284 4651 97296
+rect 5171 97284 5205 97296
+rect 5725 97284 5759 97296
+rect 6279 97284 6313 97296
+rect 6833 97284 6867 97296
+rect 7387 97284 7421 97296
+rect 7941 97284 7975 97296
+rect 8495 97284 8529 97296
+rect 9049 97284 9083 97296
+rect 9603 97284 9637 97296
+rect 10157 97284 10191 97296
+rect 10711 97284 10745 97296
+rect 11265 97284 11299 97296
+rect 11819 97284 11853 97296
+rect 12373 97284 12407 97296
+rect 31199 96493 31249 97493
+rect 32049 96493 32099 97493
+rect 32351 96493 32401 97493
+rect 33201 96493 33251 97493
+rect 57744 96888 57794 98288
+rect 57894 96888 58022 98288
+rect 58050 96888 58178 98288
+rect 58206 96888 58334 98288
+rect 58362 96888 58490 98288
+rect 58518 96888 58646 98288
+rect 58674 96888 58802 98288
+rect 58830 96888 58958 98288
+rect 58986 96888 59114 98288
+rect 59142 96888 59270 98288
+rect 59298 96888 59426 98288
+rect 59454 96888 59582 98288
+rect 59610 96888 59738 98288
+rect 59766 96888 59894 98288
+rect 59922 96888 60050 98288
+rect 60078 96888 60206 98288
+rect 60234 96888 60362 98288
+rect 60390 96888 60518 98288
+rect 60546 96888 60674 98288
+rect 60702 96888 60830 98288
+rect 60858 96888 60986 98288
+rect 61014 96888 61142 98288
+rect 61170 96888 61298 98288
+rect 61326 96888 61454 98288
+rect 61482 96888 61610 98288
+rect 61638 96888 61766 98288
+rect 61794 96888 61922 98288
+rect 61950 96888 62078 98288
+rect 62106 96888 62234 98288
+rect 62262 96888 62390 98288
+rect 62418 96888 62546 98288
+rect 62574 96888 62702 98288
+rect 62730 96888 62858 98288
+rect 62886 96888 63014 98288
+rect 63042 96888 63170 98288
+rect 63198 96888 63326 98288
+rect 63354 96888 63482 98288
+rect 63510 96888 63638 98288
+rect 63666 96888 63794 98288
+rect 63822 96888 63950 98288
+rect 63978 96888 64106 98288
+rect 64134 96888 64262 98288
+rect 64290 96888 64418 98288
+rect 64446 96888 64574 98288
+rect 64602 96888 64730 98288
+rect 64758 96888 64886 98288
+rect 64914 96888 65042 98288
+rect 65070 96888 65198 98288
+rect 65226 96888 65354 98288
+rect 65382 96888 65510 98288
+rect 65538 96888 65588 98288
+rect 67459 97444 67509 98844
+rect 67609 97444 67737 98844
+rect 67765 97444 67893 98844
+rect 67921 97444 68049 98844
+rect 68077 97444 68205 98844
+rect 68233 97444 68361 98844
+rect 68389 97444 68517 98844
+rect 68545 97444 68673 98844
+rect 68701 97444 68829 98844
+rect 68857 97444 68985 98844
+rect 69013 97444 69141 98844
+rect 69169 97444 69297 98844
+rect 69325 97444 69453 98844
+rect 69481 97444 69609 98844
+rect 69637 97444 69765 98844
+rect 69793 97444 69843 98844
+rect 78296 97858 78346 99258
+rect 78446 97858 78574 99258
+rect 78602 97858 78730 99258
+rect 78758 97858 78886 99258
+rect 78914 97858 79042 99258
+rect 79070 97858 79198 99258
+rect 79226 97858 79354 99258
+rect 79382 97858 79510 99258
+rect 79538 97858 79666 99258
+rect 79694 97858 79822 99258
+rect 79850 97858 79978 99258
+rect 80006 97858 80134 99258
+rect 80162 97858 80290 99258
+rect 80318 97858 80446 99258
+rect 80474 97858 80602 99258
+rect 80630 97858 80758 99258
+rect 80786 97858 80914 99258
+rect 80942 97858 81070 99258
+rect 81098 97858 81226 99258
+rect 81254 97858 81382 99258
+rect 81410 97858 81538 99258
+rect 81566 97858 81694 99258
+rect 81722 97858 81850 99258
+rect 81878 97858 82006 99258
+rect 82034 97858 82162 99258
+rect 82190 97858 82318 99258
+rect 82346 97858 82474 99258
+rect 82502 97858 82630 99258
+rect 82658 97858 82786 99258
+rect 82814 97858 82942 99258
+rect 82970 97858 83098 99258
+rect 83126 97858 83254 99258
+rect 83282 97858 83410 99258
+rect 83438 97858 83566 99258
+rect 83594 97858 83722 99258
+rect 83750 97858 83878 99258
+rect 83906 97858 84034 99258
+rect 84062 97858 84190 99258
+rect 84218 97858 84346 99258
+rect 84374 97858 84502 99258
+rect 84530 97858 84658 99258
+rect 84686 97858 84814 99258
+rect 84842 97858 84970 99258
+rect 84998 97858 85126 99258
+rect 85154 97858 85282 99258
+rect 85310 97858 85438 99258
+rect 85466 97858 85594 99258
+rect 85622 97858 85750 99258
+rect 85778 97858 85906 99258
+rect 85934 97858 86062 99258
+rect 86090 97858 86140 99258
+rect 88011 98414 88061 99814
+rect 88161 98414 88289 99814
+rect 88317 98414 88445 99814
+rect 88473 98414 88601 99814
+rect 88629 98414 88757 99814
+rect 88785 98414 88913 99814
+rect 88941 98414 89069 99814
+rect 89097 98414 89225 99814
+rect 89253 98414 89381 99814
+rect 89409 98414 89537 99814
+rect 89565 98414 89693 99814
+rect 89721 98414 89849 99814
+rect 89877 98414 90005 99814
+rect 90033 98414 90161 99814
+rect 90189 98414 90317 99814
+rect 90345 98414 90395 99814
+rect 99739 99696 99740 99720
+rect 99820 99696 99821 99720
+rect 100293 99696 100294 99720
+rect 100374 99696 100375 99720
+rect 100847 99696 100848 99720
+rect 100928 99696 100929 99720
+rect 101401 99696 101402 99720
+rect 101482 99696 101483 99720
+rect 101955 99696 101956 99720
+rect 102036 99696 102037 99720
+rect 102509 99696 102510 99720
+rect 102590 99696 102591 99720
+rect 103063 99696 103064 99720
+rect 103144 99696 103145 99720
+rect 103617 99696 103618 99720
+rect 103698 99696 103699 99720
+rect 104171 99696 104172 99720
+rect 104252 99696 104253 99720
+rect 104725 99696 104726 99720
+rect 104806 99696 104807 99720
+rect 105279 99696 105280 99720
+rect 105360 99696 105361 99720
+rect 105833 99696 105834 99720
+rect 105914 99696 105915 99720
+rect 106387 99696 106388 99720
+rect 106468 99696 106469 99720
+rect 106941 99696 106942 99720
+rect 107022 99696 107023 99720
+rect 107495 99696 107496 99720
+rect 107576 99696 107577 99720
+rect 108049 99696 108050 99720
+rect 108130 99696 108131 99720
+rect 108603 99696 108604 99720
+rect 108684 99696 108685 99720
+rect 109157 99696 109158 99720
+rect 109238 99696 109239 99720
+rect 109711 99696 109712 99720
+rect 109792 99696 109793 99720
+rect 110265 99696 110266 99720
+rect 110346 99696 110347 99720
+rect 99763 99672 99797 99684
+rect 100317 99672 100351 99684
+rect 100871 99672 100905 99684
+rect 101425 99672 101459 99684
+rect 101979 99672 102013 99684
+rect 102533 99672 102567 99684
+rect 103087 99672 103121 99684
+rect 103641 99672 103675 99684
+rect 104195 99672 104229 99684
+rect 104749 99672 104783 99684
+rect 105303 99672 105337 99684
+rect 105857 99672 105891 99684
+rect 106411 99672 106445 99684
+rect 106965 99672 106999 99684
+rect 107519 99672 107553 99684
+rect 108073 99672 108107 99684
+rect 108627 99672 108661 99684
+rect 109181 99672 109215 99684
+rect 109735 99672 109769 99684
+rect 110289 99672 110323 99684
+rect 119455 99282 119463 99507
+rect 119532 98425 119582 99025
+rect 119682 98425 119732 99025
+rect 120588 98787 120638 99387
+rect 120738 98787 120794 99387
+rect 120894 98787 120944 99387
+rect 121116 98721 121166 99721
+rect 121266 98721 121322 99721
+rect 121422 98721 121472 99721
+rect 121538 98721 121588 99721
+rect 121688 98721 121816 99721
+rect 121844 98721 121972 99721
+rect 122000 98721 122128 99721
+rect 122156 98721 122212 99721
+rect 122312 98721 122440 99721
+rect 122468 98721 122596 99721
+rect 122624 98721 122752 99721
+rect 122780 98721 122830 99721
+rect 122982 98721 123032 99721
+rect 123132 98721 123260 99721
+rect 123288 98721 123416 99721
+rect 123444 98721 123572 99721
+rect 123600 98721 123728 99721
+rect 123756 98721 123884 99721
+rect 123912 98721 124040 99721
+rect 124068 98721 124196 99721
+rect 124224 98721 124274 99721
+rect 124426 98771 124476 99771
+rect 124576 98771 124704 99771
+rect 124732 98771 124860 99771
+rect 124888 98771 125016 99771
+rect 125044 98771 125172 99771
+rect 125200 98771 125328 99771
+rect 125356 98771 125484 99771
+rect 125512 98771 125640 99771
+rect 125668 98771 125718 99771
+rect 125870 98721 125920 99721
+rect 126020 98721 126148 99721
+rect 126176 98721 126304 99721
+rect 126332 98721 126460 99721
+rect 126488 98721 126616 99721
+rect 126644 98721 126772 99721
+rect 126800 98721 126928 99721
+rect 126956 98721 127084 99721
+rect 127112 98721 127168 99721
+rect 127268 98721 127318 99721
+rect 127470 99121 127520 99721
+rect 127904 99121 127954 99721
+rect 129147 99236 129197 99836
+rect 129297 99236 129425 99836
+rect 129453 99236 129581 99836
+rect 129609 99236 129659 99836
+rect 129739 99236 129789 99836
+rect 129889 99236 130017 99836
+rect 130045 99236 130101 99836
+rect 130201 99236 130329 99836
+rect 130357 99236 130407 99836
+rect 130487 99236 130537 99836
+rect 130637 99236 130693 99836
+rect 130793 99236 130843 99836
+rect 129772 98456 129808 99056
+rect 130132 98456 130188 99056
+rect 130322 98456 130372 99056
+rect 126035 98342 126101 98358
+rect 126197 98342 126263 98358
+rect 128605 98288 128680 98298
+rect 128900 98288 128975 98298
+rect 99739 97696 99740 97720
+rect 99820 97696 99821 97720
+rect 100293 97696 100294 97720
+rect 100374 97696 100375 97720
+rect 100847 97696 100848 97720
+rect 100928 97696 100929 97720
+rect 101401 97696 101402 97720
+rect 101482 97696 101483 97720
+rect 101955 97696 101956 97720
+rect 102036 97696 102037 97720
+rect 102509 97696 102510 97720
+rect 102590 97696 102591 97720
+rect 103063 97696 103064 97720
+rect 103144 97696 103145 97720
+rect 103617 97696 103618 97720
+rect 103698 97696 103699 97720
+rect 104171 97696 104172 97720
+rect 104252 97696 104253 97720
+rect 104725 97696 104726 97720
+rect 104806 97696 104807 97720
+rect 105279 97696 105280 97720
+rect 105360 97696 105361 97720
+rect 105833 97696 105834 97720
+rect 105914 97696 105915 97720
+rect 106387 97696 106388 97720
+rect 106468 97696 106469 97720
+rect 106941 97696 106942 97720
+rect 107022 97696 107023 97720
+rect 107495 97696 107496 97720
+rect 107576 97696 107577 97720
+rect 108049 97696 108050 97720
+rect 108130 97696 108131 97720
+rect 108603 97696 108604 97720
+rect 108684 97696 108685 97720
+rect 109157 97696 109158 97720
+rect 109238 97696 109239 97720
+rect 109711 97696 109712 97720
+rect 109792 97696 109793 97720
+rect 110265 97696 110266 97720
+rect 110346 97696 110347 97720
+rect 99763 97672 99797 97684
+rect 100317 97672 100351 97684
+rect 100871 97672 100905 97684
+rect 101425 97672 101459 97684
+rect 101979 97672 102013 97684
+rect 102533 97672 102567 97684
+rect 103087 97672 103121 97684
+rect 103641 97672 103675 97684
+rect 104195 97672 104229 97684
+rect 104749 97672 104783 97684
+rect 105303 97672 105337 97684
+rect 105857 97672 105891 97684
+rect 106411 97672 106445 97684
+rect 106965 97672 106999 97684
+rect 107519 97672 107553 97684
+rect 108073 97672 108107 97684
+rect 108627 97672 108661 97684
+rect 109181 97672 109215 97684
+rect 109735 97672 109769 97684
+rect 110289 97672 110323 97684
+rect 120888 97638 120938 98238
+rect 121038 97638 121094 98238
+rect 121194 97638 121244 98238
+rect 121456 97607 121506 98207
+rect 121606 97607 121734 98207
+rect 121762 97607 121890 98207
+rect 121918 97607 122046 98207
+rect 122074 97607 122124 98207
+rect 122190 97607 122240 98207
+rect 122340 97607 122468 98207
+rect 122496 97607 122624 98207
+rect 122652 97607 122780 98207
+rect 122808 97607 122864 98207
+rect 122964 97607 123092 98207
+rect 123120 97607 123248 98207
+rect 123276 97607 123404 98207
+rect 123432 97607 123488 98207
+rect 123588 97607 123644 98207
+rect 123744 97607 123800 98207
+rect 123900 97607 123950 98207
+rect 124016 97607 124066 98207
+rect 124166 97607 124294 98207
+rect 124322 97607 124378 98207
+rect 124478 97607 124606 98207
+rect 124634 97607 124684 98207
+rect 127617 98115 128617 98165
+rect 128680 98115 128730 98226
+rect 128677 97995 128730 98115
+rect 127617 97945 128617 97995
+rect 40797 96532 40798 96556
+rect 40878 96532 40879 96556
+rect 41351 96532 41352 96556
+rect 41432 96532 41433 96556
+rect 41905 96532 41906 96556
+rect 41986 96532 41987 96556
+rect 42459 96532 42460 96556
+rect 42540 96532 42541 96556
+rect 43013 96532 43014 96556
+rect 43094 96532 43095 96556
+rect 43567 96532 43568 96556
+rect 43648 96532 43649 96556
+rect 44121 96532 44122 96556
+rect 44202 96532 44203 96556
+rect 44675 96532 44676 96556
+rect 44756 96532 44757 96556
+rect 45229 96532 45230 96556
+rect 45310 96532 45311 96556
+rect 45783 96532 45784 96556
+rect 45864 96532 45865 96556
+rect 46337 96532 46338 96556
+rect 46418 96532 46419 96556
+rect 46891 96532 46892 96556
+rect 46972 96532 46973 96556
+rect 47445 96532 47446 96556
+rect 47526 96532 47527 96556
+rect 47999 96532 48000 96556
+rect 48080 96532 48081 96556
+rect 48553 96532 48554 96556
+rect 48634 96532 48635 96556
+rect 49107 96532 49108 96556
+rect 49188 96532 49189 96556
+rect 49661 96532 49662 96556
+rect 49742 96532 49743 96556
+rect 50215 96532 50216 96556
+rect 50296 96532 50297 96556
+rect 50769 96532 50770 96556
+rect 50850 96532 50851 96556
+rect 51323 96532 51324 96556
+rect 51404 96532 51405 96556
+rect 40821 96508 40855 96520
+rect 41375 96508 41409 96520
+rect 41929 96508 41963 96520
+rect 42483 96508 42517 96520
+rect 43037 96508 43071 96520
+rect 43591 96508 43625 96520
+rect 44145 96508 44179 96520
+rect 44699 96508 44733 96520
+rect 45253 96508 45287 96520
+rect 45807 96508 45841 96520
+rect 46361 96508 46395 96520
+rect 46915 96508 46949 96520
+rect 47469 96508 47503 96520
+rect 48023 96508 48057 96520
+rect 48577 96508 48611 96520
+rect 49131 96508 49165 96520
+rect 49685 96508 49719 96520
+rect 50239 96508 50273 96520
+rect 50793 96508 50827 96520
+rect 51347 96508 51381 96520
+rect -820 95764 -754 95780
+rect 6411 95594 6497 95630
+rect 3043 95400 3395 95426
+rect 3867 95400 4219 95426
+rect 4691 95400 5043 95426
+rect 5515 95400 5867 95426
+rect 3069 92401 3070 95400
+rect 3369 92401 3395 95400
+rect 3069 92400 3395 92401
+rect 3893 92401 3894 95400
+rect 4193 92401 4219 95400
+rect 3893 92400 4219 92401
+rect 4717 92401 4718 95400
+rect 5017 92401 5043 95400
+rect 4717 92400 5043 92401
+rect 5541 92401 5542 95400
+rect 5841 92401 5867 95400
+rect 5541 92400 5867 92401
+rect 6411 92206 6447 95594
+rect 6461 92206 6497 95594
+rect 7041 95400 7393 95426
+rect 7865 95400 8217 95426
+rect 8689 95400 9041 95426
+rect 9513 95400 9865 95426
+rect 7067 92401 7068 95400
+rect 7367 92401 7393 95400
+rect 7067 92400 7393 92401
+rect 7891 92401 7892 95400
+rect 8191 92401 8217 95400
+rect 7891 92400 8217 92401
+rect 8715 92401 8716 95400
+rect 9015 92401 9041 95400
+rect 8715 92400 9041 92401
+rect 9539 92401 9540 95400
+rect 9839 92401 9865 95400
+rect 22591 95249 22641 96249
+rect 23441 95249 23491 96249
+rect 23743 95249 23793 96249
+rect 25393 95249 25443 96249
+rect 25695 95249 25745 96249
+rect 27345 95249 27395 96249
+rect 27647 95249 27697 96249
+rect 29297 95249 29347 96249
+rect 29599 95249 29649 96249
+rect 31249 95249 31299 96249
+rect 31551 95249 31601 96249
+rect 33201 95249 33251 96249
+rect 68039 95357 68089 96357
+rect 68889 95357 68939 96357
+rect 69191 95357 69241 96357
+rect 70041 95357 70091 96357
+rect 88591 96327 88641 97327
+rect 89441 96327 89491 97327
+rect 89743 96327 89793 97327
+rect 90593 96327 90643 97327
+rect 127580 97225 127630 97825
+rect 127750 97225 127806 97825
+rect 127926 97225 127976 97825
+rect 128196 97226 128246 97826
+rect 128366 97226 128422 97826
+rect 128542 97226 128592 97826
+rect 128680 97226 128730 97995
+rect 128850 97226 128900 98226
+rect 128963 98115 129563 98165
+rect 128963 98015 128975 98115
+rect 130862 98045 130912 98645
+rect 131032 98045 131088 98645
+rect 131208 98045 131336 98645
+rect 131384 98045 131440 98645
+rect 131560 98045 131616 98645
+rect 131736 98045 131792 98645
+rect 131912 98045 132040 98645
+rect 132088 98045 132138 98645
+rect 128963 97965 129563 98015
+rect 128979 97226 129029 97826
+rect 129149 97226 129205 97826
+rect 129325 97226 129375 97826
+rect 129666 97226 129716 97826
+rect 129836 97226 129964 97826
+rect 130012 97226 130068 97826
+rect 130188 97226 130316 97826
+rect 130364 97226 130414 97826
+rect 130786 97290 130836 97890
+rect 130956 97290 131084 97890
+rect 131132 97290 131260 97890
+rect 131308 97290 131436 97890
+rect 131484 97290 131612 97890
+rect 131660 97290 131716 97890
+rect 131836 97290 131964 97890
+rect 132012 97290 132062 97890
+rect 123463 97102 123513 97183
+rect 119796 96771 119811 96786
+rect 119760 96741 119811 96771
+rect 119796 96726 119811 96741
+rect 120654 96430 120704 97030
+rect 120824 96430 120952 97030
+rect 121000 96430 121056 97030
+rect 121176 96601 121226 97030
+rect 121289 96830 121301 97030
+rect 123460 96830 123513 97102
+rect 121176 96529 121229 96601
+rect 123463 96583 123513 96830
+rect 123613 96583 123663 97183
+rect 123729 96583 123779 97183
+rect 123879 96583 124007 97183
+rect 124035 96583 124163 97183
+rect 124191 96583 124319 97183
+rect 124397 96583 124450 97183
+rect 121176 96430 121226 96529
+rect 121289 96430 121301 96529
+rect 123800 96245 124290 96246
+rect 124400 96183 124450 96583
+rect 124550 96183 124678 97183
+rect 124706 96183 124756 97183
+rect 124957 96998 124967 97032
+rect 124957 96930 124967 96964
+rect 124957 96862 124967 96896
+rect 124957 96794 124967 96828
+rect 124957 96719 124967 96753
+rect 124957 96651 124967 96685
+rect 124957 96583 124967 96617
+rect 124957 96515 124967 96549
+rect 124957 96447 124967 96481
+rect 124957 96379 124967 96413
+rect 124957 96311 124967 96345
+rect 124957 96243 124967 96277
+rect 124957 96175 124967 96209
+rect 97096 96152 97162 96168
+rect 124957 96107 124967 96141
+rect 22591 94005 22641 95005
+rect 23441 94005 23491 95005
+rect 23743 94005 23793 95005
+rect 25393 94005 25443 95005
+rect 25695 94005 25745 95005
+rect 27345 94005 27395 95005
+rect 27647 94005 27697 95005
+rect 29297 94005 29347 95005
+rect 29599 94005 29649 95005
+rect 31249 94005 31299 95005
+rect 31551 94005 31601 95005
+rect 33201 94005 33251 95005
+rect 38154 94988 38220 95004
+rect 45385 94818 45471 94854
+rect 42017 94624 42369 94650
+rect 42841 94624 43193 94650
+rect 43665 94624 44017 94650
+rect 44489 94624 44841 94650
+rect 22591 92761 22641 93761
+rect 23441 92761 23491 93761
+rect 23743 92761 23793 93761
+rect 25393 92761 25443 93761
+rect 25695 92761 25745 93761
+rect 27345 92761 27395 93761
+rect 27647 92761 27697 93761
+rect 29297 92761 29347 93761
+rect 29599 92761 29649 93761
+rect 31249 92761 31299 93761
+rect 31551 92761 31601 93761
+rect 33201 92761 33251 93761
+rect 9539 92400 9865 92401
+rect 6411 92170 6497 92206
+rect 42043 91625 42044 94624
+rect 42343 91625 42369 94624
+rect 42043 91624 42369 91625
+rect 42867 91625 42868 94624
+rect 43167 91625 43193 94624
+rect 42867 91624 43193 91625
+rect 43691 91625 43692 94624
+rect 43991 91625 44017 94624
+rect 43691 91624 44017 91625
+rect 44515 91625 44516 94624
+rect 44815 91625 44841 94624
+rect 44515 91624 44841 91625
+rect 45385 91430 45421 94818
+rect 45435 91430 45471 94818
+rect 46015 94624 46367 94650
+rect 46839 94624 47191 94650
+rect 47663 94624 48015 94650
+rect 48487 94624 48839 94650
+rect 46041 91625 46042 94624
+rect 46341 91625 46367 94624
+rect 46041 91624 46367 91625
+rect 46865 91625 46866 94624
+rect 47165 91625 47191 94624
+rect 46865 91624 47191 91625
+rect 47689 91625 47690 94624
+rect 47989 91625 48015 94624
+rect 47689 91624 48015 91625
+rect 48513 91625 48514 94624
+rect 48813 91625 48839 94624
+rect 59431 94113 59481 95113
+rect 60281 94113 60331 95113
+rect 60583 94113 60633 95113
+rect 62233 94113 62283 95113
+rect 62535 94113 62585 95113
+rect 64185 94113 64235 95113
+rect 64487 94113 64537 95113
+rect 66137 94113 66187 95113
+rect 66439 94113 66489 95113
+rect 68089 94113 68139 95113
+rect 68391 94113 68441 95113
+rect 70041 94113 70091 95113
+rect 79983 95083 80033 96083
+rect 80833 95083 80883 96083
+rect 81135 95083 81185 96083
+rect 82785 95083 82835 96083
+rect 83087 95083 83137 96083
+rect 84737 95083 84787 96083
+rect 85039 95083 85089 96083
+rect 86689 95083 86739 96083
+rect 86991 95083 87041 96083
+rect 88641 95083 88691 96083
+rect 88943 95083 88993 96083
+rect 90593 95083 90643 96083
+rect 125026 96062 125076 97062
+rect 125196 96062 125324 97062
+rect 125372 96062 125500 97062
+rect 125548 96062 125604 97062
+rect 125724 96062 125774 97062
+rect 125873 96942 125939 96958
+rect 126359 96942 126425 96958
+rect 125873 96158 125939 96174
+rect 126035 96158 126101 96174
+rect 126197 96158 126263 96174
+rect 126359 96158 126425 96174
+rect 126524 96062 126574 97062
+rect 126694 96062 126750 97062
+rect 126870 96062 126998 97062
+rect 127046 96062 127174 97062
+rect 127222 96062 127272 97062
+rect 127365 96998 127375 97032
+rect 127365 96930 127375 96964
+rect 127365 96862 127375 96896
+rect 127365 96794 127375 96828
+rect 127365 96719 127375 96753
+rect 127365 96651 127375 96685
+rect 127365 96583 127375 96617
+rect 127365 96515 127375 96549
+rect 127365 96447 127375 96481
+rect 127365 96379 127375 96413
+rect 127365 96311 127375 96345
+rect 127365 96243 127375 96277
+rect 127365 96175 127375 96209
+rect 127365 96107 127375 96141
+rect 127424 96062 127474 97062
+rect 127594 96062 127722 97062
+rect 127770 96062 127826 97062
+rect 127946 96062 127996 97062
+rect 128162 96462 128212 97062
+rect 128332 96462 128388 97062
+rect 128508 96462 128636 97062
+rect 128684 96462 128734 97062
+rect 128886 96462 128936 97062
+rect 129036 96462 129164 97062
+rect 129192 96462 129248 97062
+rect 129348 96462 129476 97062
+rect 129504 96462 129554 97062
+rect 129758 96462 129808 97062
+rect 129908 96462 130036 97062
+rect 130064 96462 130192 97062
+rect 130220 96462 130276 97062
+rect 130376 96462 130426 97062
+rect 132211 96933 132261 96988
+rect 104327 95982 104413 96018
+rect 100959 95788 101311 95814
+rect 101783 95788 102135 95814
+rect 102607 95788 102959 95814
+rect 103431 95788 103783 95814
+rect 59431 92869 59481 93869
+rect 60281 92869 60331 93869
+rect 60583 92869 60633 93869
+rect 62233 92869 62283 93869
+rect 62535 92869 62585 93869
+rect 64185 92869 64235 93869
+rect 64487 92869 64537 93869
+rect 66137 92869 66187 93869
+rect 66439 92869 66489 93869
+rect 68089 92869 68139 93869
+rect 68391 92869 68441 93869
+rect 70041 92869 70091 93869
+rect 79983 93839 80033 94839
+rect 80833 93839 80883 94839
+rect 81135 93839 81185 94839
+rect 82785 93839 82835 94839
+rect 83087 93839 83137 94839
+rect 84737 93839 84787 94839
+rect 85039 93839 85089 94839
+rect 86689 93839 86739 94839
+rect 86991 93839 87041 94839
+rect 88641 93839 88691 94839
+rect 88943 93839 88993 94839
+rect 90593 93839 90643 94839
+rect 59431 91625 59481 92625
+rect 60281 91625 60331 92625
+rect 60583 91625 60633 92625
+rect 62233 91625 62283 92625
+rect 62535 91625 62585 92625
+rect 64185 91625 64235 92625
+rect 64487 91625 64537 92625
+rect 66137 91625 66187 92625
+rect 66439 91625 66489 92625
+rect 68089 91625 68139 92625
+rect 68391 91625 68441 92625
+rect 70041 91625 70091 92625
+rect 79983 92595 80033 93595
+rect 80833 92595 80883 93595
+rect 81135 92595 81185 93595
+rect 82785 92595 82835 93595
+rect 83087 92595 83137 93595
+rect 84737 92595 84787 93595
+rect 85039 92595 85089 93595
+rect 86689 92595 86739 93595
+rect 86991 92595 87041 93595
+rect 88641 92595 88691 93595
+rect 88943 92595 88993 93595
+rect 90593 92595 90643 93595
+rect 100985 92789 100986 95788
+rect 101285 92789 101311 95788
+rect 100985 92788 101311 92789
+rect 101809 92789 101810 95788
+rect 102109 92789 102135 95788
+rect 101809 92788 102135 92789
+rect 102633 92789 102634 95788
+rect 102933 92789 102959 95788
+rect 102633 92788 102959 92789
+rect 103457 92789 103458 95788
+rect 103757 92789 103783 95788
+rect 103457 92788 103783 92789
+rect 104327 92594 104363 95982
+rect 104377 92594 104413 95982
+rect 104957 95788 105309 95814
+rect 105781 95788 106133 95814
+rect 106605 95788 106957 95814
+rect 107429 95788 107781 95814
+rect 104983 92789 104984 95788
+rect 105283 92789 105309 95788
+rect 104983 92788 105309 92789
+rect 105807 92789 105808 95788
+rect 106107 92789 106133 95788
+rect 105807 92788 106133 92789
+rect 106631 92789 106632 95788
+rect 106931 92789 106957 95788
+rect 106631 92788 106957 92789
+rect 107455 92789 107456 95788
+rect 107755 92789 107781 95788
+rect 119826 95382 119879 95532
+rect 119829 94932 119879 95382
+rect 119999 94932 120055 95532
+rect 120175 94932 120231 95532
+rect 120351 94932 120407 95532
+rect 120527 94932 120577 95532
+rect 120643 94932 120693 95532
+rect 120813 94932 120869 95532
+rect 120989 94932 121045 95532
+rect 121165 94932 121215 95532
+rect 121486 95332 121666 95532
+rect 121722 95332 121902 95532
+rect 123456 95332 123636 95532
+rect 123692 95332 123872 95532
+rect 121722 95197 121902 95234
+rect 123456 95197 123636 95234
+rect 124143 94932 124193 95532
+rect 124313 94932 124369 95532
+rect 124489 94932 124545 95532
+rect 124665 94932 124715 95532
+rect 124797 94932 124847 95532
+rect 124967 94932 125023 95532
+rect 125143 94932 125199 95532
+rect 125319 94932 125369 95532
+rect 125640 95332 125820 95532
+rect 125876 95332 126056 95532
+rect 127610 95332 127790 95532
+rect 127846 95332 128026 95532
+rect 125876 95197 126056 95234
+rect 127610 95197 127790 95234
+rect 128297 94932 128347 95532
+rect 128467 94932 128523 95532
+rect 128643 94932 128699 95532
+rect 128819 94932 128869 95532
+rect 128951 94932 129001 95532
+rect 129121 94932 129177 95532
+rect 129297 94932 129353 95532
+rect 129473 94932 129523 95532
+rect 129794 95332 129974 95532
+rect 130030 95332 130210 95532
+rect 131764 95332 131944 95532
+rect 132000 95332 132180 95532
+rect 130030 95197 130210 95234
+rect 131764 95197 131944 95234
+rect 132451 94932 132501 95532
+rect 132621 94932 132677 95532
+rect 132797 94932 132853 95532
+rect 132973 94932 133023 95532
+rect 133204 94534 133228 94558
+rect 133625 94534 133649 94558
+rect 133228 94510 133252 94525
+rect 133601 94510 133625 94525
+rect 133032 94354 133056 94378
+rect 133057 94330 133080 94354
+rect 119452 93516 119502 94116
+rect 119622 93516 119678 94116
+rect 119798 93516 119848 94116
+rect 121341 93724 121391 94324
+rect 121511 93724 121561 94324
+rect 121937 93719 121987 94319
+rect 122107 93719 122163 94319
+rect 122283 94072 122333 94319
+rect 122396 94169 122408 94319
+rect 123022 94169 123075 94319
+rect 123025 94072 123075 94169
+rect 122283 94000 122336 94072
+rect 122283 93719 122333 94000
+rect 122396 93850 122408 94000
+rect 123022 93850 123075 94072
+rect 123025 93719 123075 93850
+rect 123195 93719 123251 94319
+rect 123371 93719 123421 94319
+rect 123797 93724 123847 94324
+rect 123967 93724 124017 94324
+rect 125495 93724 125545 94324
+rect 125665 93724 125715 94324
+rect 126091 93719 126141 94319
+rect 126261 93719 126317 94319
+rect 126437 94072 126487 94319
+rect 126550 94169 126562 94319
+rect 127176 94169 127229 94319
+rect 127179 94072 127229 94169
+rect 126437 94000 126490 94072
+rect 126437 93719 126487 94000
+rect 126550 93850 126562 94000
+rect 127176 93850 127229 94072
+rect 127179 93719 127229 93850
+rect 127349 93719 127405 94319
+rect 127525 93719 127575 94319
+rect 127951 93724 128001 94324
+rect 128121 93724 128171 94324
+rect 129649 93724 129699 94324
+rect 129819 93724 129869 94324
+rect 130245 93719 130295 94319
+rect 130415 93719 130471 94319
+rect 130591 94072 130641 94319
+rect 130704 94169 130716 94319
+rect 131330 94169 131383 94319
+rect 131333 94072 131383 94169
+rect 130591 94000 130644 94072
+rect 130591 93719 130641 94000
+rect 130704 93850 130716 94000
+rect 131330 93850 131383 94072
+rect 131333 93719 131383 93850
+rect 131503 93719 131559 94319
+rect 131679 93719 131729 94319
+rect 132105 93724 132155 94324
+rect 132275 93724 132325 94324
+rect 133252 94266 133286 94290
+rect 133322 94266 133356 94290
+rect 133392 94266 133426 94290
+rect 133462 94266 133496 94290
+rect 133532 94266 133566 94290
+rect 133602 94266 133625 94290
+rect 133057 94232 133080 94256
+rect 133032 94208 133056 94232
+rect 120880 93397 120914 93421
+rect 120948 93397 120982 93421
+rect 121016 93397 121050 93421
+rect 121084 93397 121118 93421
+rect 121152 93397 121186 93421
+rect 121220 93397 121254 93421
+rect 121288 93397 121322 93421
+rect 121356 93397 121390 93421
+rect 121424 93397 121458 93421
+rect 121492 93397 121526 93421
+rect 121560 93397 121594 93421
+rect 121628 93397 121662 93421
+rect 121696 93397 121730 93421
+rect 121764 93397 121798 93421
+rect 121832 93397 121866 93421
+rect 121900 93397 121934 93421
+rect 121968 93397 122002 93421
+rect 122036 93397 122070 93421
+rect 122104 93397 122138 93421
+rect 122172 93397 122206 93421
+rect 122240 93397 122274 93421
+rect 122308 93397 122342 93421
+rect 122376 93397 122410 93421
+rect 122444 93397 122478 93421
+rect 122512 93397 122546 93421
+rect 122580 93397 122614 93421
+rect 122648 93397 122682 93421
+rect 122716 93397 122750 93421
+rect 122784 93397 122818 93421
+rect 122852 93397 122886 93421
+rect 122920 93397 122954 93421
+rect 122988 93397 123022 93421
+rect 123056 93397 123090 93421
+rect 123124 93397 123158 93421
+rect 123192 93397 123226 93421
+rect 123260 93397 123294 93421
+rect 123328 93397 123362 93421
+rect 123396 93397 123430 93421
+rect 123464 93397 123498 93421
+rect 123532 93397 123566 93421
+rect 123600 93397 123634 93421
+rect 123668 93397 123702 93421
+rect 123736 93397 123770 93421
+rect 123804 93397 123838 93421
+rect 123872 93397 123906 93421
+rect 123940 93397 123974 93421
+rect 124008 93397 124042 93421
+rect 124076 93397 124110 93421
+rect 124144 93397 124178 93421
+rect 124212 93397 124246 93421
+rect 124280 93397 124314 93421
+rect 124348 93397 124382 93421
+rect 124416 93397 124450 93421
+rect 124484 93397 124518 93421
+rect 124552 93397 124586 93421
+rect 124620 93397 124654 93421
+rect 124688 93397 124722 93421
+rect 124756 93397 124790 93421
+rect 124824 93397 124858 93421
+rect 124892 93397 124926 93421
+rect 124960 93397 124994 93421
+rect 125028 93397 125062 93421
+rect 125096 93397 125130 93421
+rect 125164 93397 125198 93421
+rect 125232 93397 125266 93421
+rect 125300 93397 125334 93421
+rect 125368 93397 125402 93421
+rect 125436 93397 125470 93421
+rect 125504 93397 125538 93421
+rect 125572 93397 125606 93421
+rect 125640 93397 125674 93421
+rect 125708 93397 125742 93421
+rect 125776 93397 125810 93421
+rect 125844 93397 125878 93421
+rect 125912 93397 125946 93421
+rect 125980 93397 126014 93421
+rect 126048 93397 126082 93421
+rect 126116 93397 126150 93421
+rect 126184 93397 126218 93421
+rect 126252 93397 126286 93421
+rect 126320 93397 126354 93421
+rect 126388 93397 126422 93421
+rect 126456 93397 126490 93421
+rect 126524 93397 126558 93421
+rect 126592 93397 126626 93421
+rect 126660 93397 126694 93421
+rect 126728 93397 126762 93421
+rect 126796 93397 126830 93421
+rect 126864 93397 126898 93421
+rect 126932 93397 126966 93421
+rect 127000 93397 127034 93421
+rect 127068 93397 127102 93421
+rect 127136 93397 127170 93421
+rect 127204 93397 127238 93421
+rect 127272 93397 127306 93421
+rect 127340 93397 127374 93421
+rect 127408 93397 127442 93421
+rect 127476 93397 127510 93421
+rect 127544 93397 127578 93421
+rect 127612 93397 127646 93421
+rect 127680 93397 127714 93421
+rect 127748 93397 127782 93421
+rect 127816 93397 127850 93421
+rect 127884 93397 127918 93421
+rect 127952 93397 127986 93421
+rect 128020 93397 128054 93421
+rect 128088 93397 128122 93421
+rect 128156 93397 128190 93421
+rect 128224 93397 128258 93421
+rect 128358 93397 128392 93421
+rect 128426 93397 128460 93421
+rect 128494 93397 128528 93421
+rect 128562 93397 128596 93421
+rect 128630 93397 128664 93421
+rect 128698 93397 128732 93421
+rect 128766 93397 128800 93421
+rect 128834 93397 128868 93421
+rect 128902 93397 128936 93421
+rect 128970 93397 129004 93421
+rect 129038 93397 129072 93421
+rect 129106 93397 129140 93421
+rect 129174 93397 129208 93421
+rect 129242 93397 129276 93421
+rect 129310 93397 129344 93421
+rect 129378 93397 129412 93421
+rect 129446 93397 129480 93421
+rect 129514 93397 129548 93421
+rect 129582 93397 129616 93421
+rect 129650 93397 129684 93421
+rect 129718 93397 129752 93421
+rect 129786 93397 129820 93421
+rect 129854 93397 129888 93421
+rect 129922 93397 129956 93421
+rect 129990 93397 130024 93421
+rect 130058 93397 130092 93421
+rect 130126 93397 130160 93421
+rect 130194 93397 130228 93421
+rect 130262 93397 130296 93421
+rect 130330 93397 130364 93421
+rect 130398 93397 130432 93421
+rect 130466 93397 130500 93421
+rect 130534 93397 130568 93421
+rect 130602 93397 130636 93421
+rect 130670 93397 130704 93421
+rect 130738 93397 130772 93421
+rect 130806 93397 130840 93421
+rect 130874 93397 130908 93421
+rect 130942 93397 130976 93421
+rect 131010 93397 131044 93421
+rect 131078 93397 131112 93421
+rect 131146 93397 131180 93421
+rect 131214 93397 131248 93421
+rect 131282 93397 131316 93421
+rect 131350 93397 131384 93421
+rect 131418 93397 131452 93421
+rect 128334 93363 128362 93397
+rect 107455 92788 107781 92789
+rect 104327 92558 104413 92594
+rect 48513 91624 48839 91625
+rect 45385 91394 45471 91430
+rect 1188 85320 1254 85336
+rect 2211 83550 2212 83574
+rect 2292 83550 2293 83574
+rect 2765 83550 2766 83574
+rect 2846 83550 2847 83574
+rect 3319 83550 3320 83574
+rect 3400 83550 3401 83574
+rect 3873 83550 3874 83574
+rect 3954 83550 3955 83574
+rect 4427 83550 4428 83574
+rect 4508 83550 4509 83574
+rect 4981 83550 4982 83574
+rect 5062 83550 5063 83574
+rect 5535 83550 5536 83574
+rect 5616 83550 5617 83574
+rect 6089 83550 6090 83574
+rect 6170 83550 6171 83574
+rect 6643 83550 6644 83574
+rect 6724 83550 6725 83574
+rect 7197 83550 7198 83574
+rect 7278 83550 7279 83574
+rect 7751 83550 7752 83574
+rect 7832 83550 7833 83574
+rect 8305 83550 8306 83574
+rect 8386 83550 8387 83574
+rect 8859 83550 8860 83574
+rect 8940 83550 8941 83574
+rect 9413 83550 9414 83574
+rect 9494 83550 9495 83574
+rect 9967 83550 9968 83574
+rect 10048 83550 10049 83574
+rect 10521 83550 10522 83574
+rect 10602 83550 10603 83574
+rect 11075 83550 11076 83574
+rect 11156 83550 11157 83574
+rect 11629 83550 11630 83574
+rect 11710 83550 11711 83574
+rect 12183 83550 12184 83574
+rect 12264 83550 12265 83574
+rect 12737 83550 12738 83574
+rect 12818 83550 12819 83574
+rect 2235 83526 2269 83538
+rect 2789 83526 2823 83538
+rect 3343 83526 3377 83538
+rect 3897 83526 3931 83538
+rect 4451 83526 4485 83538
+rect 5005 83526 5039 83538
+rect 5559 83526 5593 83538
+rect 6113 83526 6147 83538
+rect 6667 83526 6701 83538
+rect 7221 83526 7255 83538
+rect 7775 83526 7809 83538
+rect 8329 83526 8363 83538
+rect 8883 83526 8917 83538
+rect 9437 83526 9471 83538
+rect 9991 83526 10025 83538
+rect 10545 83526 10579 83538
+rect 11099 83526 11133 83538
+rect 11653 83526 11687 83538
+rect 12207 83526 12241 83538
+rect 12761 83526 12795 83538
+rect 21232 83370 21304 85370
+rect 21503 83403 21621 85297
+rect 21892 83370 21952 85370
+rect 22152 83370 22224 85370
+rect 22423 83403 22541 85297
+rect 22812 83370 22872 85370
+rect 23072 83370 23144 85370
+rect 23343 83403 23461 85297
+rect 23732 83370 23792 85370
+rect 23992 83370 24064 85370
+rect 24263 83403 24381 85297
+rect 24652 83370 24712 85370
+rect 24912 83370 24984 85370
+rect 25183 83403 25301 85297
+rect 25572 83370 25632 85370
+rect 25832 83370 25904 85370
+rect 26103 83403 26221 85297
+rect 26492 83370 26552 85370
+rect 26752 83370 26824 85370
+rect 27023 83403 27141 85297
+rect 27412 83370 27472 85370
+rect 27672 83370 27744 85370
+rect 27943 83403 28061 85297
+rect 28332 83370 28392 85370
+rect 28592 83370 28664 85370
+rect 28863 83403 28981 85297
+rect 29252 83370 29312 85370
+rect 29512 83370 29584 85370
+rect 29783 83403 29901 85297
+rect 30172 83370 30232 85370
+rect 30432 83370 30504 85370
+rect 30703 83403 30821 85297
+rect 31092 83370 31152 85370
+rect 41010 83564 41082 85564
+rect 41281 83597 41399 85491
+rect 41670 83564 41730 85564
+rect 41930 83564 42002 85564
+rect 42201 83597 42319 85491
+rect 42590 83564 42650 85564
+rect 42850 83564 42922 85564
+rect 43121 83597 43239 85491
+rect 43510 83564 43570 85564
+rect 43770 83564 43842 85564
+rect 44041 83597 44159 85491
+rect 44430 83564 44490 85564
+rect 44690 83564 44762 85564
+rect 44961 83597 45079 85491
+rect 45350 83564 45410 85564
+rect 45610 83564 45682 85564
+rect 45881 83597 45999 85491
+rect 46270 83564 46330 85564
+rect 46530 83564 46602 85564
+rect 46801 83597 46919 85491
+rect 47190 83564 47250 85564
+rect 47450 83564 47522 85564
+rect 47721 83597 47839 85491
+rect 48110 83564 48170 85564
+rect 48370 83564 48442 85564
+rect 48641 83597 48759 85491
+rect 49030 83564 49090 85564
+rect 49290 83564 49362 85564
+rect 49561 83597 49679 85491
+rect 49950 83564 50010 85564
+rect 50210 83564 50282 85564
+rect 50481 83597 50599 85491
+rect 50870 83564 50930 85564
+rect 61684 83574 61750 83590
+rect 80686 83380 80752 83396
+rect 2765 81550 2766 81574
+rect 2846 81550 2847 81574
+rect 3319 81550 3320 81574
+rect 3400 81550 3401 81574
+rect 3873 81550 3874 81574
+rect 3954 81550 3955 81574
+rect 4427 81550 4428 81574
+rect 4508 81550 4509 81574
+rect 4981 81550 4982 81574
+rect 5062 81550 5063 81574
+rect 5535 81550 5536 81574
+rect 5616 81550 5617 81574
+rect 6089 81550 6090 81574
+rect 6170 81550 6171 81574
+rect 6643 81550 6644 81574
+rect 6724 81550 6725 81574
+rect 7197 81550 7198 81574
+rect 7278 81550 7279 81574
+rect 7751 81550 7752 81574
+rect 7832 81550 7833 81574
+rect 8305 81550 8306 81574
+rect 8386 81550 8387 81574
+rect 8859 81550 8860 81574
+rect 8940 81550 8941 81574
+rect 9413 81550 9414 81574
+rect 9494 81550 9495 81574
+rect 9967 81550 9968 81574
+rect 10048 81550 10049 81574
+rect 10521 81550 10522 81574
+rect 10602 81550 10603 81574
+rect 11075 81550 11076 81574
+rect 11156 81550 11157 81574
+rect 11629 81550 11630 81574
+rect 11710 81550 11711 81574
+rect 12183 81550 12184 81574
+rect 12264 81550 12265 81574
+rect 12737 81550 12738 81574
+rect 12818 81550 12819 81574
+rect 2789 81526 2823 81538
+rect 3343 81526 3377 81538
+rect 3897 81526 3931 81538
+rect 4451 81526 4485 81538
+rect 5005 81526 5039 81538
+rect 5559 81526 5593 81538
+rect 6113 81526 6147 81538
+rect 6667 81526 6701 81538
+rect 7221 81526 7255 81538
+rect 7775 81526 7809 81538
+rect 8329 81526 8363 81538
+rect 8883 81526 8917 81538
+rect 9437 81526 9471 81538
+rect 9991 81526 10025 81538
+rect 10545 81526 10579 81538
+rect 11099 81526 11133 81538
+rect 11653 81526 11687 81538
+rect 12207 81526 12241 81538
+rect 12761 81526 12795 81538
+rect 2705 79550 2706 79574
+rect 2786 79550 2787 79574
+rect 3541 79550 3542 79574
+rect 3622 79550 3623 79574
+rect 4377 79550 4378 79574
+rect 4458 79550 4459 79574
+rect 5213 79550 5214 79574
+rect 5294 79550 5295 79574
+rect 6049 79550 6050 79574
+rect 6130 79550 6131 79574
+rect 6885 79550 6886 79574
+rect 6966 79550 6967 79574
+rect 7721 79550 7722 79574
+rect 7802 79550 7803 79574
+rect 8557 79550 8558 79574
+rect 8638 79550 8639 79574
+rect 9393 79550 9394 79574
+rect 9474 79550 9475 79574
+rect 10229 79550 10230 79574
+rect 10310 79550 10311 79574
+rect 11065 79550 11066 79574
+rect 11146 79550 11147 79574
+rect 11901 79550 11902 79574
+rect 11982 79550 11983 79574
+rect 12737 79550 12738 79574
+rect 12818 79550 12819 79574
+rect 2729 79526 2763 79538
+rect 3565 79526 3599 79538
+rect 4401 79526 4435 79538
+rect 5237 79526 5271 79538
+rect 6073 79526 6107 79538
+rect 6909 79526 6943 79538
+rect 7745 79526 7779 79538
+rect 8581 79526 8615 79538
+rect 9417 79526 9451 79538
+rect 10253 79526 10287 79538
+rect 11089 79526 11123 79538
+rect 11925 79526 11959 79538
+rect 12761 79526 12795 79538
+rect 21232 78770 21304 82770
+rect 21503 78803 21621 82737
+rect 21892 78770 21952 82770
+rect 22152 78770 22224 82770
+rect 22423 78803 22541 82737
+rect 22812 78770 22872 82770
+rect 23072 78770 23144 82770
+rect 23343 78803 23461 82737
+rect 23732 78770 23792 82770
+rect 23992 78770 24064 82770
+rect 24263 78803 24381 82737
+rect 24652 78770 24712 82770
+rect 24912 78770 24984 82770
+rect 25183 78803 25301 82737
+rect 25572 78770 25632 82770
+rect 25832 78770 25904 82770
+rect 26103 78803 26221 82737
+rect 26492 78770 26552 82770
+rect 26752 78770 26824 82770
+rect 27023 78803 27141 82737
+rect 27412 78770 27472 82770
+rect 27672 78770 27744 82770
+rect 27943 78803 28061 82737
+rect 28332 78770 28392 82770
+rect 28592 78770 28664 82770
+rect 28863 78803 28981 82737
+rect 29252 78770 29312 82770
+rect 29512 78770 29584 82770
+rect 29783 78803 29901 82737
+rect 30172 78770 30232 82770
+rect 30432 78770 30504 82770
+rect 30703 78803 30821 82737
+rect 31092 78770 31152 82770
+rect 41010 78964 41082 82964
+rect 41281 78997 41399 82931
+rect 41670 78964 41730 82964
+rect 41930 78964 42002 82964
+rect 42201 78997 42319 82931
+rect 42590 78964 42650 82964
+rect 42850 78964 42922 82964
+rect 43121 78997 43239 82931
+rect 43510 78964 43570 82964
+rect 43770 78964 43842 82964
+rect 44041 78997 44159 82931
+rect 44430 78964 44490 82964
+rect 44690 78964 44762 82964
+rect 44961 78997 45079 82931
+rect 45350 78964 45410 82964
+rect 45610 78964 45682 82964
+rect 45881 78997 45999 82931
+rect 46270 78964 46330 82964
+rect 46530 78964 46602 82964
+rect 46801 78997 46919 82931
+rect 47190 78964 47250 82964
+rect 47450 78964 47522 82964
+rect 47721 78997 47839 82931
+rect 48110 78964 48170 82964
+rect 48370 78964 48442 82964
+rect 48641 78997 48759 82931
+rect 49030 78964 49090 82964
+rect 49290 78964 49362 82964
+rect 49561 78997 49679 82931
+rect 49950 78964 50010 82964
+rect 50210 78964 50282 82964
+rect 50481 78997 50599 82931
+rect 50870 78964 50930 82964
+rect 62707 81804 62708 81828
+rect 62788 81804 62789 81828
+rect 63261 81804 63262 81828
+rect 63342 81804 63343 81828
+rect 63815 81804 63816 81828
+rect 63896 81804 63897 81828
+rect 64369 81804 64370 81828
+rect 64450 81804 64451 81828
+rect 64923 81804 64924 81828
+rect 65004 81804 65005 81828
+rect 65477 81804 65478 81828
+rect 65558 81804 65559 81828
+rect 66031 81804 66032 81828
+rect 66112 81804 66113 81828
+rect 66585 81804 66586 81828
+rect 66666 81804 66667 81828
+rect 67139 81804 67140 81828
+rect 67220 81804 67221 81828
+rect 67693 81804 67694 81828
+rect 67774 81804 67775 81828
+rect 68247 81804 68248 81828
+rect 68328 81804 68329 81828
+rect 68801 81804 68802 81828
+rect 68882 81804 68883 81828
+rect 69355 81804 69356 81828
+rect 69436 81804 69437 81828
+rect 69909 81804 69910 81828
+rect 69990 81804 69991 81828
+rect 70463 81804 70464 81828
+rect 70544 81804 70545 81828
+rect 71017 81804 71018 81828
+rect 71098 81804 71099 81828
+rect 71571 81804 71572 81828
+rect 71652 81804 71653 81828
+rect 72125 81804 72126 81828
+rect 72206 81804 72207 81828
+rect 72679 81804 72680 81828
+rect 72760 81804 72761 81828
+rect 73233 81804 73234 81828
+rect 73314 81804 73315 81828
+rect 62731 81780 62765 81792
+rect 63285 81780 63319 81792
+rect 63839 81780 63873 81792
+rect 64393 81780 64427 81792
+rect 64947 81780 64981 81792
+rect 65501 81780 65535 81792
+rect 66055 81780 66089 81792
+rect 66609 81780 66643 81792
+rect 67163 81780 67197 81792
+rect 67717 81780 67751 81792
+rect 68271 81780 68305 81792
+rect 68825 81780 68859 81792
+rect 69379 81780 69413 81792
+rect 69933 81780 69967 81792
+rect 70487 81780 70521 81792
+rect 71041 81780 71075 81792
+rect 71595 81780 71629 81792
+rect 72149 81780 72183 81792
+rect 72703 81780 72737 81792
+rect 73257 81780 73291 81792
+rect 81709 81610 81710 81634
+rect 81790 81610 81791 81634
+rect 82263 81610 82264 81634
+rect 82344 81610 82345 81634
+rect 82817 81610 82818 81634
+rect 82898 81610 82899 81634
+rect 83371 81610 83372 81634
+rect 83452 81610 83453 81634
+rect 83925 81610 83926 81634
+rect 84006 81610 84007 81634
+rect 84479 81610 84480 81634
+rect 84560 81610 84561 81634
+rect 85033 81610 85034 81634
+rect 85114 81610 85115 81634
+rect 85587 81610 85588 81634
+rect 85668 81610 85669 81634
+rect 86141 81610 86142 81634
+rect 86222 81610 86223 81634
+rect 86695 81610 86696 81634
+rect 86776 81610 86777 81634
+rect 87249 81610 87250 81634
+rect 87330 81610 87331 81634
+rect 87803 81610 87804 81634
+rect 87884 81610 87885 81634
+rect 88357 81610 88358 81634
+rect 88438 81610 88439 81634
+rect 88911 81610 88912 81634
+rect 88992 81610 88993 81634
+rect 89465 81610 89466 81634
+rect 89546 81610 89547 81634
+rect 90019 81610 90020 81634
+rect 90100 81610 90101 81634
+rect 90573 81610 90574 81634
+rect 90654 81610 90655 81634
+rect 91127 81610 91128 81634
+rect 91208 81610 91209 81634
+rect 91681 81610 91682 81634
+rect 91762 81610 91763 81634
+rect 92235 81610 92236 81634
+rect 92316 81610 92317 81634
+rect 81733 81586 81767 81598
+rect 82287 81586 82321 81598
+rect 82841 81586 82875 81598
+rect 83395 81586 83429 81598
+rect 83949 81586 83983 81598
+rect 84503 81586 84537 81598
+rect 85057 81586 85091 81598
+rect 85611 81586 85645 81598
+rect 86165 81586 86199 81598
+rect 86719 81586 86753 81598
+rect 87273 81586 87307 81598
+rect 87827 81586 87861 81598
+rect 88381 81586 88415 81598
+rect 88935 81586 88969 81598
+rect 89489 81586 89523 81598
+rect 90043 81586 90077 81598
+rect 90597 81586 90631 81598
+rect 91151 81586 91185 81598
+rect 91705 81586 91739 81598
+rect 92259 81586 92293 81598
+rect 103638 81596 103710 83596
+rect 103909 81629 104027 83523
+rect 104298 81596 104358 83596
+rect 104558 81596 104630 83596
+rect 104829 81629 104947 83523
+rect 105218 81596 105278 83596
+rect 105478 81596 105550 83596
+rect 105749 81629 105867 83523
+rect 106138 81596 106198 83596
+rect 106398 81596 106470 83596
+rect 106669 81629 106787 83523
+rect 107058 81596 107118 83596
+rect 107318 81596 107390 83596
+rect 107589 81629 107707 83523
+rect 107978 81596 108038 83596
+rect 108238 81596 108310 83596
+rect 108509 81629 108627 83523
+rect 108898 81596 108958 83596
+rect 109158 81596 109230 83596
+rect 109429 81629 109547 83523
+rect 109818 81596 109878 83596
+rect 110078 81596 110150 83596
+rect 110349 81629 110467 83523
+rect 110738 81596 110798 83596
+rect 110998 81596 111070 83596
+rect 111269 81629 111387 83523
+rect 111658 81596 111718 83596
+rect 111918 81596 111990 83596
+rect 112189 81629 112307 83523
+rect 112578 81596 112638 83596
+rect 112838 81596 112910 83596
+rect 113109 81629 113227 83523
+rect 113498 81596 113558 83596
+rect 63261 79804 63262 79828
+rect 63342 79804 63343 79828
+rect 63815 79804 63816 79828
+rect 63896 79804 63897 79828
+rect 64369 79804 64370 79828
+rect 64450 79804 64451 79828
+rect 64923 79804 64924 79828
+rect 65004 79804 65005 79828
+rect 65477 79804 65478 79828
+rect 65558 79804 65559 79828
+rect 66031 79804 66032 79828
+rect 66112 79804 66113 79828
+rect 66585 79804 66586 79828
+rect 66666 79804 66667 79828
+rect 67139 79804 67140 79828
+rect 67220 79804 67221 79828
+rect 67693 79804 67694 79828
+rect 67774 79804 67775 79828
+rect 68247 79804 68248 79828
+rect 68328 79804 68329 79828
+rect 68801 79804 68802 79828
+rect 68882 79804 68883 79828
+rect 69355 79804 69356 79828
+rect 69436 79804 69437 79828
+rect 69909 79804 69910 79828
+rect 69990 79804 69991 79828
+rect 70463 79804 70464 79828
+rect 70544 79804 70545 79828
+rect 71017 79804 71018 79828
+rect 71098 79804 71099 79828
+rect 71571 79804 71572 79828
+rect 71652 79804 71653 79828
+rect 72125 79804 72126 79828
+rect 72206 79804 72207 79828
+rect 72679 79804 72680 79828
+rect 72760 79804 72761 79828
+rect 73233 79804 73234 79828
+rect 73314 79804 73315 79828
+rect 63285 79780 63319 79792
+rect 63839 79780 63873 79792
+rect 64393 79780 64427 79792
+rect 64947 79780 64981 79792
+rect 65501 79780 65535 79792
+rect 66055 79780 66089 79792
+rect 66609 79780 66643 79792
+rect 67163 79780 67197 79792
+rect 67717 79780 67751 79792
+rect 68271 79780 68305 79792
+rect 68825 79780 68859 79792
+rect 69379 79780 69413 79792
+rect 69933 79780 69967 79792
+rect 70487 79780 70521 79792
+rect 71041 79780 71075 79792
+rect 71595 79780 71629 79792
+rect 72149 79780 72183 79792
+rect 72703 79780 72737 79792
+rect 73257 79780 73291 79792
+rect 82263 79610 82264 79634
+rect 82344 79610 82345 79634
+rect 82817 79610 82818 79634
+rect 82898 79610 82899 79634
+rect 83371 79610 83372 79634
+rect 83452 79610 83453 79634
+rect 83925 79610 83926 79634
+rect 84006 79610 84007 79634
+rect 84479 79610 84480 79634
+rect 84560 79610 84561 79634
+rect 85033 79610 85034 79634
+rect 85114 79610 85115 79634
+rect 85587 79610 85588 79634
+rect 85668 79610 85669 79634
+rect 86141 79610 86142 79634
+rect 86222 79610 86223 79634
+rect 86695 79610 86696 79634
+rect 86776 79610 86777 79634
+rect 87249 79610 87250 79634
+rect 87330 79610 87331 79634
+rect 87803 79610 87804 79634
+rect 87884 79610 87885 79634
+rect 88357 79610 88358 79634
+rect 88438 79610 88439 79634
+rect 88911 79610 88912 79634
+rect 88992 79610 88993 79634
+rect 89465 79610 89466 79634
+rect 89546 79610 89547 79634
+rect 90019 79610 90020 79634
+rect 90100 79610 90101 79634
+rect 90573 79610 90574 79634
+rect 90654 79610 90655 79634
+rect 91127 79610 91128 79634
+rect 91208 79610 91209 79634
+rect 91681 79610 91682 79634
+rect 91762 79610 91763 79634
+rect 92235 79610 92236 79634
+rect 92316 79610 92317 79634
+rect 82287 79586 82321 79598
+rect 82841 79586 82875 79598
+rect 83395 79586 83429 79598
+rect 83949 79586 83983 79598
+rect 84503 79586 84537 79598
+rect 85057 79586 85091 79598
+rect 85611 79586 85645 79598
+rect 86165 79586 86199 79598
+rect 86719 79586 86753 79598
+rect 87273 79586 87307 79598
+rect 87827 79586 87861 79598
+rect 88381 79586 88415 79598
+rect 88935 79586 88969 79598
+rect 89489 79586 89523 79598
+rect 90043 79586 90077 79598
+rect 90597 79586 90631 79598
+rect 91151 79586 91185 79598
+rect 91705 79586 91739 79598
+rect 92259 79586 92293 79598
+rect 2705 77550 2706 77574
+rect 2786 77550 2787 77574
+rect 3541 77550 3542 77574
+rect 3622 77550 3623 77574
+rect 4377 77550 4378 77574
+rect 4458 77550 4459 77574
+rect 5213 77550 5214 77574
+rect 5294 77550 5295 77574
+rect 6049 77550 6050 77574
+rect 6130 77550 6131 77574
+rect 6885 77550 6886 77574
+rect 6966 77550 6967 77574
+rect 7721 77550 7722 77574
+rect 7802 77550 7803 77574
+rect 8557 77550 8558 77574
+rect 8638 77550 8639 77574
+rect 9393 77550 9394 77574
+rect 9474 77550 9475 77574
+rect 10229 77550 10230 77574
+rect 10310 77550 10311 77574
+rect 11065 77550 11066 77574
+rect 11146 77550 11147 77574
+rect 11901 77550 11902 77574
+rect 11982 77550 11983 77574
+rect 12737 77550 12738 77574
+rect 12818 77550 12819 77574
+rect 2729 77526 2763 77538
+rect 3565 77526 3599 77538
+rect 4401 77526 4435 77538
+rect 5237 77526 5271 77538
+rect 6073 77526 6107 77538
+rect 6909 77526 6943 77538
+rect 7745 77526 7779 77538
+rect 8581 77526 8615 77538
+rect 9417 77526 9451 77538
+rect 10253 77526 10287 77538
+rect 11089 77526 11123 77538
+rect 11925 77526 11959 77538
+rect 12761 77526 12795 77538
+rect 2705 75550 2706 75574
+rect 2786 75550 2787 75574
+rect 3541 75550 3542 75574
+rect 3622 75550 3623 75574
+rect 4377 75550 4378 75574
+rect 4458 75550 4459 75574
+rect 5213 75550 5214 75574
+rect 5294 75550 5295 75574
+rect 6049 75550 6050 75574
+rect 6130 75550 6131 75574
+rect 6885 75550 6886 75574
+rect 6966 75550 6967 75574
+rect 7721 75550 7722 75574
+rect 7802 75550 7803 75574
+rect 8557 75550 8558 75574
+rect 8638 75550 8639 75574
+rect 9393 75550 9394 75574
+rect 9474 75550 9475 75574
+rect 10229 75550 10230 75574
+rect 10310 75550 10311 75574
+rect 11065 75550 11066 75574
+rect 11146 75550 11147 75574
+rect 11901 75550 11902 75574
+rect 11982 75550 11983 75574
+rect 12737 75550 12738 75574
+rect 12818 75550 12819 75574
+rect 2729 75526 2763 75538
+rect 3565 75526 3599 75538
+rect 4401 75526 4435 75538
+rect 5237 75526 5271 75538
+rect 6073 75526 6107 75538
+rect 6909 75526 6943 75538
+rect 7745 75526 7779 75538
+rect 8581 75526 8615 75538
+rect 9417 75526 9451 75538
+rect 10253 75526 10287 75538
+rect 11089 75526 11123 75538
+rect 11925 75526 11959 75538
+rect 12761 75526 12795 75538
+rect 21232 74170 21304 78170
+rect 21503 74203 21621 78137
+rect 21892 74170 21952 78170
+rect 22152 74170 22224 78170
+rect 22423 74203 22541 78137
+rect 22812 74170 22872 78170
+rect 23072 74170 23144 78170
+rect 23343 74203 23461 78137
+rect 23732 74170 23792 78170
+rect 23992 74170 24064 78170
+rect 24263 74203 24381 78137
+rect 24652 74170 24712 78170
+rect 24912 74170 24984 78170
+rect 25183 74203 25301 78137
+rect 25572 74170 25632 78170
+rect 25832 74170 25904 78170
+rect 26103 74203 26221 78137
+rect 26492 74170 26552 78170
+rect 26752 74170 26824 78170
+rect 27023 74203 27141 78137
+rect 27412 74170 27472 78170
+rect 27672 74170 27744 78170
+rect 27943 74203 28061 78137
+rect 28332 74170 28392 78170
+rect 28592 74170 28664 78170
+rect 28863 74203 28981 78137
+rect 29252 74170 29312 78170
+rect 29512 74170 29584 78170
+rect 29783 74203 29901 78137
+rect 30172 74170 30232 78170
+rect 30432 74170 30504 78170
+rect 30703 74203 30821 78137
+rect 31092 74170 31152 78170
+rect 41010 74364 41082 78364
+rect 41281 74397 41399 78331
+rect 41670 74364 41730 78364
+rect 41930 74364 42002 78364
+rect 42201 74397 42319 78331
+rect 42590 74364 42650 78364
+rect 42850 74364 42922 78364
+rect 43121 74397 43239 78331
+rect 43510 74364 43570 78364
+rect 43770 74364 43842 78364
+rect 44041 74397 44159 78331
+rect 44430 74364 44490 78364
+rect 44690 74364 44762 78364
+rect 44961 74397 45079 78331
+rect 45350 74364 45410 78364
+rect 45610 74364 45682 78364
+rect 45881 74397 45999 78331
+rect 46270 74364 46330 78364
+rect 46530 74364 46602 78364
+rect 46801 74397 46919 78331
+rect 47190 74364 47250 78364
+rect 47450 74364 47522 78364
+rect 47721 74397 47839 78331
+rect 48110 74364 48170 78364
+rect 48370 74364 48442 78364
+rect 48641 74397 48759 78331
+rect 49030 74364 49090 78364
+rect 49290 74364 49362 78364
+rect 49561 74397 49679 78331
+rect 49950 74364 50010 78364
+rect 50210 74364 50282 78364
+rect 50481 74397 50599 78331
+rect 50870 74364 50930 78364
+rect 63201 77804 63202 77828
+rect 63282 77804 63283 77828
+rect 64037 77804 64038 77828
+rect 64118 77804 64119 77828
+rect 64873 77804 64874 77828
+rect 64954 77804 64955 77828
+rect 65709 77804 65710 77828
+rect 65790 77804 65791 77828
+rect 66545 77804 66546 77828
+rect 66626 77804 66627 77828
+rect 67381 77804 67382 77828
+rect 67462 77804 67463 77828
+rect 68217 77804 68218 77828
+rect 68298 77804 68299 77828
+rect 69053 77804 69054 77828
+rect 69134 77804 69135 77828
+rect 69889 77804 69890 77828
+rect 69970 77804 69971 77828
+rect 70725 77804 70726 77828
+rect 70806 77804 70807 77828
+rect 71561 77804 71562 77828
+rect 71642 77804 71643 77828
+rect 72397 77804 72398 77828
+rect 72478 77804 72479 77828
+rect 73233 77804 73234 77828
+rect 73314 77804 73315 77828
+rect 63225 77780 63259 77792
+rect 64061 77780 64095 77792
+rect 64897 77780 64931 77792
+rect 65733 77780 65767 77792
+rect 66569 77780 66603 77792
+rect 67405 77780 67439 77792
+rect 68241 77780 68275 77792
+rect 69077 77780 69111 77792
+rect 69913 77780 69947 77792
+rect 70749 77780 70783 77792
+rect 71585 77780 71619 77792
+rect 72421 77780 72455 77792
+rect 73257 77780 73291 77792
+rect 82203 77610 82204 77634
+rect 82284 77610 82285 77634
+rect 83039 77610 83040 77634
+rect 83120 77610 83121 77634
+rect 83875 77610 83876 77634
+rect 83956 77610 83957 77634
+rect 84711 77610 84712 77634
+rect 84792 77610 84793 77634
+rect 85547 77610 85548 77634
+rect 85628 77610 85629 77634
+rect 86383 77610 86384 77634
+rect 86464 77610 86465 77634
+rect 87219 77610 87220 77634
+rect 87300 77610 87301 77634
+rect 88055 77610 88056 77634
+rect 88136 77610 88137 77634
+rect 88891 77610 88892 77634
+rect 88972 77610 88973 77634
+rect 89727 77610 89728 77634
+rect 89808 77610 89809 77634
+rect 90563 77610 90564 77634
+rect 90644 77610 90645 77634
+rect 91399 77610 91400 77634
+rect 91480 77610 91481 77634
+rect 92235 77610 92236 77634
+rect 92316 77610 92317 77634
+rect 82227 77586 82261 77598
+rect 83063 77586 83097 77598
+rect 83899 77586 83933 77598
+rect 84735 77586 84769 77598
+rect 85571 77586 85605 77598
+rect 86407 77586 86441 77598
+rect 87243 77586 87277 77598
+rect 88079 77586 88113 77598
+rect 88915 77586 88949 77598
+rect 89751 77586 89785 77598
+rect 90587 77586 90621 77598
+rect 91423 77586 91457 77598
+rect 92259 77586 92293 77598
+rect 103638 76996 103710 80996
+rect 103909 77029 104027 80963
+rect 104298 76996 104358 80996
+rect 104558 76996 104630 80996
+rect 104829 77029 104947 80963
+rect 105218 76996 105278 80996
+rect 105478 76996 105550 80996
+rect 105749 77029 105867 80963
+rect 106138 76996 106198 80996
+rect 106398 76996 106470 80996
+rect 106669 77029 106787 80963
+rect 107058 76996 107118 80996
+rect 107318 76996 107390 80996
+rect 107589 77029 107707 80963
+rect 107978 76996 108038 80996
+rect 108238 76996 108310 80996
+rect 108509 77029 108627 80963
+rect 108898 76996 108958 80996
+rect 109158 76996 109230 80996
+rect 109429 77029 109547 80963
+rect 109818 76996 109878 80996
+rect 110078 76996 110150 80996
+rect 110349 77029 110467 80963
+rect 110738 76996 110798 80996
+rect 110998 76996 111070 80996
+rect 111269 77029 111387 80963
+rect 111658 76996 111718 80996
+rect 111918 76996 111990 80996
+rect 112189 77029 112307 80963
+rect 112578 76996 112638 80996
+rect 112838 76996 112910 80996
+rect 113109 77029 113227 80963
+rect 113498 76996 113558 80996
+rect 63201 75804 63202 75828
+rect 63282 75804 63283 75828
+rect 64037 75804 64038 75828
+rect 64118 75804 64119 75828
+rect 64873 75804 64874 75828
+rect 64954 75804 64955 75828
+rect 65709 75804 65710 75828
+rect 65790 75804 65791 75828
+rect 66545 75804 66546 75828
+rect 66626 75804 66627 75828
+rect 67381 75804 67382 75828
+rect 67462 75804 67463 75828
+rect 68217 75804 68218 75828
+rect 68298 75804 68299 75828
+rect 69053 75804 69054 75828
+rect 69134 75804 69135 75828
+rect 69889 75804 69890 75828
+rect 69970 75804 69971 75828
+rect 70725 75804 70726 75828
+rect 70806 75804 70807 75828
+rect 71561 75804 71562 75828
+rect 71642 75804 71643 75828
+rect 72397 75804 72398 75828
+rect 72478 75804 72479 75828
+rect 73233 75804 73234 75828
+rect 73314 75804 73315 75828
+rect 63225 75780 63259 75792
+rect 64061 75780 64095 75792
+rect 64897 75780 64931 75792
+rect 65733 75780 65767 75792
+rect 66569 75780 66603 75792
+rect 67405 75780 67439 75792
+rect 68241 75780 68275 75792
+rect 69077 75780 69111 75792
+rect 69913 75780 69947 75792
+rect 70749 75780 70783 75792
+rect 71585 75780 71619 75792
+rect 72421 75780 72455 75792
+rect 73257 75780 73291 75792
+rect 82203 75610 82204 75634
+rect 82284 75610 82285 75634
+rect 83039 75610 83040 75634
+rect 83120 75610 83121 75634
+rect 83875 75610 83876 75634
+rect 83956 75610 83957 75634
+rect 84711 75610 84712 75634
+rect 84792 75610 84793 75634
+rect 85547 75610 85548 75634
+rect 85628 75610 85629 75634
+rect 86383 75610 86384 75634
+rect 86464 75610 86465 75634
+rect 87219 75610 87220 75634
+rect 87300 75610 87301 75634
+rect 88055 75610 88056 75634
+rect 88136 75610 88137 75634
+rect 88891 75610 88892 75634
+rect 88972 75610 88973 75634
+rect 89727 75610 89728 75634
+rect 89808 75610 89809 75634
+rect 90563 75610 90564 75634
+rect 90644 75610 90645 75634
+rect 91399 75610 91400 75634
+rect 91480 75610 91481 75634
+rect 92235 75610 92236 75634
+rect 92316 75610 92317 75634
+rect 82227 75586 82261 75598
+rect 83063 75586 83097 75598
+rect 83899 75586 83933 75598
+rect 84735 75586 84769 75598
+rect 85571 75586 85605 75598
+rect 86407 75586 86441 75598
+rect 87243 75586 87277 75598
+rect 88079 75586 88113 75598
+rect 88915 75586 88949 75598
+rect 89751 75586 89785 75598
+rect 90587 75586 90621 75598
+rect 91423 75586 91457 75598
+rect 92259 75586 92293 75598
+rect 63201 73804 63202 73828
+rect 63282 73804 63283 73828
+rect 64037 73804 64038 73828
+rect 64118 73804 64119 73828
+rect 64873 73804 64874 73828
+rect 64954 73804 64955 73828
+rect 65709 73804 65710 73828
+rect 65790 73804 65791 73828
+rect 66545 73804 66546 73828
+rect 66626 73804 66627 73828
+rect 67381 73804 67382 73828
+rect 67462 73804 67463 73828
+rect 68217 73804 68218 73828
+rect 68298 73804 68299 73828
+rect 69053 73804 69054 73828
+rect 69134 73804 69135 73828
+rect 69889 73804 69890 73828
+rect 69970 73804 69971 73828
+rect 70725 73804 70726 73828
+rect 70806 73804 70807 73828
+rect 71561 73804 71562 73828
+rect 71642 73804 71643 73828
+rect 72397 73804 72398 73828
+rect 72478 73804 72479 73828
+rect 73233 73804 73234 73828
+rect 73314 73804 73315 73828
+rect 63225 73780 63259 73792
+rect 64061 73780 64095 73792
+rect 64897 73780 64931 73792
+rect 65733 73780 65767 73792
+rect 66569 73780 66603 73792
+rect 67405 73780 67439 73792
+rect 68241 73780 68275 73792
+rect 69077 73780 69111 73792
+rect 69913 73780 69947 73792
+rect 70749 73780 70783 73792
+rect 71585 73780 71619 73792
+rect 72421 73780 72455 73792
+rect 73257 73780 73291 73792
+rect 4377 73550 4378 73574
+rect 4458 73550 4459 73574
+rect 5213 73550 5214 73574
+rect 5294 73550 5295 73574
+rect 6049 73550 6050 73574
+rect 6130 73550 6131 73574
+rect 6885 73550 6886 73574
+rect 6966 73550 6967 73574
+rect 7721 73550 7722 73574
+rect 7802 73550 7803 73574
+rect 8557 73550 8558 73574
+rect 8638 73550 8639 73574
+rect 9393 73550 9394 73574
+rect 9474 73550 9475 73574
+rect 10229 73550 10230 73574
+rect 10310 73550 10311 73574
+rect 11065 73550 11066 73574
+rect 11146 73550 11147 73574
+rect 11901 73550 11902 73574
+rect 11982 73550 11983 73574
+rect 12737 73550 12738 73574
+rect 12818 73550 12819 73574
+rect 4401 73526 4435 73538
+rect 5237 73526 5271 73538
+rect 6073 73526 6107 73538
+rect 6909 73526 6943 73538
+rect 7745 73526 7779 73538
+rect 8581 73526 8615 73538
+rect 9417 73526 9451 73538
+rect 10253 73526 10287 73538
+rect 11089 73526 11123 73538
+rect 11925 73526 11959 73538
+rect 12761 73526 12795 73538
+rect 4377 71929 4378 71953
+rect 4458 71929 4459 71953
+rect 5213 71929 5214 71953
+rect 5294 71929 5295 71953
+rect 6049 71929 6050 71953
+rect 6130 71929 6131 71953
+rect 6885 71929 6886 71953
+rect 6966 71929 6967 71953
+rect 7721 71929 7722 71953
+rect 7802 71929 7803 71953
+rect 8557 71929 8558 71953
+rect 8638 71929 8639 71953
+rect 9393 71929 9394 71953
+rect 9474 71929 9475 71953
+rect 10229 71929 10230 71953
+rect 10310 71929 10311 71953
+rect 11065 71929 11066 71953
+rect 11146 71929 11147 71953
+rect 11901 71929 11902 71953
+rect 11982 71929 11983 71953
+rect 12737 71929 12738 71953
+rect 12818 71929 12819 71953
+rect 4401 71905 4435 71917
+rect 5237 71905 5271 71917
+rect 6073 71905 6107 71917
+rect 6909 71905 6943 71917
+rect 7745 71905 7779 71917
+rect 8581 71905 8615 71917
+rect 9417 71905 9451 71917
+rect 10253 71905 10287 71917
+rect 11089 71905 11123 71917
+rect 11925 71905 11959 71917
+rect 12761 71905 12795 71917
+rect 23072 69570 23144 73570
+rect 23343 69603 23461 73537
+rect 23732 69570 23792 73570
+rect 23992 69570 24064 73570
+rect 24263 69603 24381 73537
+rect 24652 69570 24712 73570
+rect 24912 69570 24984 73570
+rect 25183 69603 25301 73537
+rect 25572 69570 25632 73570
+rect 25832 69570 25904 73570
+rect 26103 69603 26221 73537
+rect 26492 69570 26552 73570
+rect 26752 69570 26824 73570
+rect 27023 69603 27141 73537
+rect 27412 69570 27472 73570
+rect 27672 69570 27744 73570
+rect 27943 69603 28061 73537
+rect 28332 69570 28392 73570
+rect 28592 69570 28664 73570
+rect 28863 69603 28981 73537
+rect 29252 69570 29312 73570
+rect 29512 69570 29584 73570
+rect 29783 69603 29901 73537
+rect 30172 69570 30232 73570
+rect 30432 69570 30504 73570
+rect 30703 69603 30821 73537
+rect 31092 69570 31152 73570
+rect 42850 69764 42922 73764
+rect 43121 69797 43239 73731
+rect 43510 69764 43570 73764
+rect 43770 69764 43842 73764
+rect 44041 69797 44159 73731
+rect 44430 69764 44490 73764
+rect 44690 69764 44762 73764
+rect 44961 69797 45079 73731
+rect 45350 69764 45410 73764
+rect 45610 69764 45682 73764
+rect 45881 69797 45999 73731
+rect 46270 69764 46330 73764
+rect 46530 69764 46602 73764
+rect 46801 69797 46919 73731
+rect 47190 69764 47250 73764
+rect 47450 69764 47522 73764
+rect 47721 69797 47839 73731
+rect 48110 69764 48170 73764
+rect 48370 69764 48442 73764
+rect 48641 69797 48759 73731
+rect 49030 69764 49090 73764
+rect 49290 69764 49362 73764
+rect 49561 69797 49679 73731
+rect 49950 69764 50010 73764
+rect 50210 69764 50282 73764
+rect 50481 69797 50599 73731
+rect 50870 69764 50930 73764
+rect 82203 73610 82204 73634
+rect 82284 73610 82285 73634
+rect 83039 73610 83040 73634
+rect 83120 73610 83121 73634
+rect 83875 73610 83876 73634
+rect 83956 73610 83957 73634
+rect 84711 73610 84712 73634
+rect 84792 73610 84793 73634
+rect 85547 73610 85548 73634
+rect 85628 73610 85629 73634
+rect 86383 73610 86384 73634
+rect 86464 73610 86465 73634
+rect 87219 73610 87220 73634
+rect 87300 73610 87301 73634
+rect 88055 73610 88056 73634
+rect 88136 73610 88137 73634
+rect 88891 73610 88892 73634
+rect 88972 73610 88973 73634
+rect 89727 73610 89728 73634
+rect 89808 73610 89809 73634
+rect 90563 73610 90564 73634
+rect 90644 73610 90645 73634
+rect 91399 73610 91400 73634
+rect 91480 73610 91481 73634
+rect 92235 73610 92236 73634
+rect 92316 73610 92317 73634
+rect 82227 73586 82261 73598
+rect 83063 73586 83097 73598
+rect 83899 73586 83933 73598
+rect 84735 73586 84769 73598
+rect 85571 73586 85605 73598
+rect 86407 73586 86441 73598
+rect 87243 73586 87277 73598
+rect 88079 73586 88113 73598
+rect 88915 73586 88949 73598
+rect 89751 73586 89785 73598
+rect 90587 73586 90621 73598
+rect 91423 73586 91457 73598
+rect 92259 73586 92293 73598
+rect 103638 72396 103710 76396
+rect 103909 72429 104027 76363
+rect 104298 72396 104358 76396
+rect 104558 72396 104630 76396
+rect 104829 72429 104947 76363
+rect 105218 72396 105278 76396
+rect 105478 72396 105550 76396
+rect 105749 72429 105867 76363
+rect 106138 72396 106198 76396
+rect 106398 72396 106470 76396
+rect 106669 72429 106787 76363
+rect 107058 72396 107118 76396
+rect 107318 72396 107390 76396
+rect 107589 72429 107707 76363
+rect 107978 72396 108038 76396
+rect 108238 72396 108310 76396
+rect 108509 72429 108627 76363
+rect 108898 72396 108958 76396
+rect 109158 72396 109230 76396
+rect 109429 72429 109547 76363
+rect 109818 72396 109878 76396
+rect 110078 72396 110150 76396
+rect 110349 72429 110467 76363
+rect 110738 72396 110798 76396
+rect 110998 72396 111070 76396
+rect 111269 72429 111387 76363
+rect 111658 72396 111718 76396
+rect 111918 72396 111990 76396
+rect 112189 72429 112307 76363
+rect 112578 72396 112638 76396
+rect 112838 72396 112910 76396
+rect 113109 72429 113227 76363
+rect 113498 72396 113558 76396
+rect 64873 71804 64874 71828
+rect 64954 71804 64955 71828
+rect 65709 71804 65710 71828
+rect 65790 71804 65791 71828
+rect 66545 71804 66546 71828
+rect 66626 71804 66627 71828
+rect 67381 71804 67382 71828
+rect 67462 71804 67463 71828
+rect 68217 71804 68218 71828
+rect 68298 71804 68299 71828
+rect 69053 71804 69054 71828
+rect 69134 71804 69135 71828
+rect 69889 71804 69890 71828
+rect 69970 71804 69971 71828
+rect 70725 71804 70726 71828
+rect 70806 71804 70807 71828
+rect 71561 71804 71562 71828
+rect 71642 71804 71643 71828
+rect 72397 71804 72398 71828
+rect 72478 71804 72479 71828
+rect 73233 71804 73234 71828
+rect 73314 71804 73315 71828
+rect 64897 71780 64931 71792
+rect 65733 71780 65767 71792
+rect 66569 71780 66603 71792
+rect 67405 71780 67439 71792
+rect 68241 71780 68275 71792
+rect 69077 71780 69111 71792
+rect 69913 71780 69947 71792
+rect 70749 71780 70783 71792
+rect 71585 71780 71619 71792
+rect 72421 71780 72455 71792
+rect 73257 71780 73291 71792
+rect 83875 71610 83876 71634
+rect 83956 71610 83957 71634
+rect 84711 71610 84712 71634
+rect 84792 71610 84793 71634
+rect 85547 71610 85548 71634
+rect 85628 71610 85629 71634
+rect 86383 71610 86384 71634
+rect 86464 71610 86465 71634
+rect 87219 71610 87220 71634
+rect 87300 71610 87301 71634
+rect 88055 71610 88056 71634
+rect 88136 71610 88137 71634
+rect 88891 71610 88892 71634
+rect 88972 71610 88973 71634
+rect 89727 71610 89728 71634
+rect 89808 71610 89809 71634
+rect 90563 71610 90564 71634
+rect 90644 71610 90645 71634
+rect 91399 71610 91400 71634
+rect 91480 71610 91481 71634
+rect 92235 71610 92236 71634
+rect 92316 71610 92317 71634
+rect 83899 71586 83933 71598
+rect 84735 71586 84769 71598
+rect 85571 71586 85605 71598
+rect 86407 71586 86441 71598
+rect 87243 71586 87277 71598
+rect 88079 71586 88113 71598
+rect 88915 71586 88949 71598
+rect 89751 71586 89785 71598
+rect 90587 71586 90621 71598
+rect 91423 71586 91457 71598
+rect 92259 71586 92293 71598
+rect 64873 70183 64874 70207
+rect 64954 70183 64955 70207
+rect 65709 70183 65710 70207
+rect 65790 70183 65791 70207
+rect 66545 70183 66546 70207
+rect 66626 70183 66627 70207
+rect 67381 70183 67382 70207
+rect 67462 70183 67463 70207
+rect 68217 70183 68218 70207
+rect 68298 70183 68299 70207
+rect 69053 70183 69054 70207
+rect 69134 70183 69135 70207
+rect 69889 70183 69890 70207
+rect 69970 70183 69971 70207
+rect 70725 70183 70726 70207
+rect 70806 70183 70807 70207
+rect 71561 70183 71562 70207
+rect 71642 70183 71643 70207
+rect 72397 70183 72398 70207
+rect 72478 70183 72479 70207
+rect 73233 70183 73234 70207
+rect 73314 70183 73315 70207
+rect 64897 70159 64931 70171
+rect 65733 70159 65767 70171
+rect 66569 70159 66603 70171
+rect 67405 70159 67439 70171
+rect 68241 70159 68275 70171
+rect 69077 70159 69111 70171
+rect 69913 70159 69947 70171
+rect 70749 70159 70783 70171
+rect 71585 70159 71619 70171
+rect 72421 70159 72455 70171
+rect 73257 70159 73291 70171
+rect 83875 69989 83876 70013
+rect 83956 69989 83957 70013
+rect 84711 69989 84712 70013
+rect 84792 69989 84793 70013
+rect 85547 69989 85548 70013
+rect 85628 69989 85629 70013
+rect 86383 69989 86384 70013
+rect 86464 69989 86465 70013
+rect 87219 69989 87220 70013
+rect 87300 69989 87301 70013
+rect 88055 69989 88056 70013
+rect 88136 69989 88137 70013
+rect 88891 69989 88892 70013
+rect 88972 69989 88973 70013
+rect 89727 69989 89728 70013
+rect 89808 69989 89809 70013
+rect 90563 69989 90564 70013
+rect 90644 69989 90645 70013
+rect 91399 69989 91400 70013
+rect 91480 69989 91481 70013
+rect 92235 69989 92236 70013
+rect 92316 69989 92317 70013
+rect 83899 69965 83933 69977
+rect 84735 69965 84769 69977
+rect 85571 69965 85605 69977
+rect 86407 69965 86441 69977
+rect 87243 69965 87277 69977
+rect 88079 69965 88113 69977
+rect 88915 69965 88949 69977
+rect 89751 69965 89785 69977
+rect 90587 69965 90621 69977
+rect 91423 69965 91457 69977
+rect 92259 69965 92293 69977
+rect 23072 64970 23144 68970
+rect 23343 65003 23461 68937
+rect 23732 64970 23792 68970
+rect 23992 64970 24064 68970
+rect 24263 65003 24381 68937
+rect 24652 64970 24712 68970
+rect 24912 64970 24984 68970
+rect 25183 65003 25301 68937
+rect 25572 64970 25632 68970
+rect 25832 64970 25904 68970
+rect 26103 65003 26221 68937
+rect 26492 64970 26552 68970
+rect 26752 64970 26824 68970
+rect 27023 65003 27141 68937
+rect 27412 64970 27472 68970
+rect 27672 64970 27744 68970
+rect 27943 65003 28061 68937
+rect 28332 64970 28392 68970
+rect 28592 64970 28664 68970
+rect 28863 65003 28981 68937
+rect 29252 64970 29312 68970
+rect 29512 64970 29584 68970
+rect 29783 65003 29901 68937
+rect 30172 64970 30232 68970
+rect 30432 64970 30504 68970
+rect 30703 65003 30821 68937
+rect 31092 64970 31152 68970
+rect 42850 65164 42922 69164
+rect 43121 65197 43239 69131
+rect 43510 65164 43570 69164
+rect 43770 65164 43842 69164
+rect 44041 65197 44159 69131
+rect 44430 65164 44490 69164
+rect 44690 65164 44762 69164
+rect 44961 65197 45079 69131
+rect 45350 65164 45410 69164
+rect 45610 65164 45682 69164
+rect 45881 65197 45999 69131
+rect 46270 65164 46330 69164
+rect 46530 65164 46602 69164
+rect 46801 65197 46919 69131
+rect 47190 65164 47250 69164
+rect 47450 65164 47522 69164
+rect 47721 65197 47839 69131
+rect 48110 65164 48170 69164
+rect 48370 65164 48442 69164
+rect 48641 65197 48759 69131
+rect 49030 65164 49090 69164
+rect 49290 65164 49362 69164
+rect 49561 65197 49679 69131
+rect 49950 65164 50010 69164
+rect 50210 65164 50282 69164
+rect 50481 65197 50599 69131
+rect 50870 65164 50930 69164
+rect 105478 67796 105550 71796
+rect 105749 67829 105867 71763
+rect 106138 67796 106198 71796
+rect 106398 67796 106470 71796
+rect 106669 67829 106787 71763
+rect 107058 67796 107118 71796
+rect 107318 67796 107390 71796
+rect 107589 67829 107707 71763
+rect 107978 67796 108038 71796
+rect 108238 67796 108310 71796
+rect 108509 67829 108627 71763
+rect 108898 67796 108958 71796
+rect 109158 67796 109230 71796
+rect 109429 67829 109547 71763
+rect 109818 67796 109878 71796
+rect 110078 67796 110150 71796
+rect 110349 67829 110467 71763
+rect 110738 67796 110798 71796
+rect 110998 67796 111070 71796
+rect 111269 67829 111387 71763
+rect 111658 67796 111718 71796
+rect 111918 67796 111990 71796
+rect 112189 67829 112307 71763
+rect 112578 67796 112638 71796
+rect 112838 67796 112910 71796
+rect 113109 67829 113227 71763
+rect 113498 67796 113558 71796
+rect 23072 60370 23144 64370
+rect 23343 60403 23461 64337
+rect 23732 60370 23792 64370
+rect 23992 60370 24064 64370
+rect 24263 60403 24381 64337
+rect 24652 60370 24712 64370
+rect 24912 60370 24984 64370
+rect 25183 60403 25301 64337
+rect 25572 60370 25632 64370
+rect 25832 60370 25904 64370
+rect 26103 60403 26221 64337
+rect 26492 60370 26552 64370
+rect 26752 60370 26824 64370
+rect 27023 60403 27141 64337
+rect 27412 60370 27472 64370
+rect 27672 60370 27744 64370
+rect 27943 60403 28061 64337
+rect 28332 60370 28392 64370
+rect 28592 60370 28664 64370
+rect 28863 60403 28981 64337
+rect 29252 60370 29312 64370
+rect 29512 60370 29584 64370
+rect 29783 60403 29901 64337
+rect 30172 60370 30232 64370
+rect 30432 60370 30504 64370
+rect 30703 60403 30821 64337
+rect 31092 60370 31152 64370
+rect 42850 60564 42922 64564
+rect 43121 60597 43239 64531
+rect 43510 60564 43570 64564
+rect 43770 60564 43842 64564
+rect 44041 60597 44159 64531
+rect 44430 60564 44490 64564
+rect 44690 60564 44762 64564
+rect 44961 60597 45079 64531
+rect 45350 60564 45410 64564
+rect 45610 60564 45682 64564
+rect 45881 60597 45999 64531
+rect 46270 60564 46330 64564
+rect 46530 60564 46602 64564
+rect 46801 60597 46919 64531
+rect 47190 60564 47250 64564
+rect 47450 60564 47522 64564
+rect 47721 60597 47839 64531
+rect 48110 60564 48170 64564
+rect 48370 60564 48442 64564
+rect 48641 60597 48759 64531
+rect 49030 60564 49090 64564
+rect 49290 60564 49362 64564
+rect 49561 60597 49679 64531
+rect 49950 60564 50010 64564
+rect 50210 60564 50282 64564
+rect 50481 60597 50599 64531
+rect 50870 60564 50930 64564
+rect 105478 63196 105550 67196
+rect 105749 63229 105867 67163
+rect 106138 63196 106198 67196
+rect 106398 63196 106470 67196
+rect 106669 63229 106787 67163
+rect 107058 63196 107118 67196
+rect 107318 63196 107390 67196
+rect 107589 63229 107707 67163
+rect 107978 63196 108038 67196
+rect 108238 63196 108310 67196
+rect 108509 63229 108627 67163
+rect 108898 63196 108958 67196
+rect 109158 63196 109230 67196
+rect 109429 63229 109547 67163
+rect 109818 63196 109878 67196
+rect 110078 63196 110150 67196
+rect 110349 63229 110467 67163
+rect 110738 63196 110798 67196
+rect 110998 63196 111070 67196
+rect 111269 63229 111387 67163
+rect 111658 63196 111718 67196
+rect 111918 63196 111990 67196
+rect 112189 63229 112307 67163
+rect 112578 63196 112638 67196
+rect 112838 63196 112910 67196
+rect 113109 63229 113227 67163
+rect 113498 63196 113558 67196
+rect 2211 59550 2212 59574
+rect 2292 59550 2293 59574
+rect 2765 59550 2766 59574
+rect 2846 59550 2847 59574
+rect 3319 59550 3320 59574
+rect 3400 59550 3401 59574
+rect 3873 59550 3874 59574
+rect 3954 59550 3955 59574
+rect 4427 59550 4428 59574
+rect 4508 59550 4509 59574
+rect 4981 59550 4982 59574
+rect 5062 59550 5063 59574
+rect 5535 59550 5536 59574
+rect 5616 59550 5617 59574
+rect 6089 59550 6090 59574
+rect 6170 59550 6171 59574
+rect 6643 59550 6644 59574
+rect 6724 59550 6725 59574
+rect 7197 59550 7198 59574
+rect 7278 59550 7279 59574
+rect 7751 59550 7752 59574
+rect 7832 59550 7833 59574
+rect 8305 59550 8306 59574
+rect 8386 59550 8387 59574
+rect 8859 59550 8860 59574
+rect 8940 59550 8941 59574
+rect 9413 59550 9414 59574
+rect 9494 59550 9495 59574
+rect 9967 59550 9968 59574
+rect 10048 59550 10049 59574
+rect 10521 59550 10522 59574
+rect 10602 59550 10603 59574
+rect 11075 59550 11076 59574
+rect 11156 59550 11157 59574
+rect 11629 59550 11630 59574
+rect 11710 59550 11711 59574
+rect 12183 59550 12184 59574
+rect 12264 59550 12265 59574
+rect 12737 59550 12738 59574
+rect 12818 59550 12819 59574
+rect 2235 59526 2269 59538
+rect 2789 59526 2823 59538
+rect 3343 59526 3377 59538
+rect 3897 59526 3931 59538
+rect 4451 59526 4485 59538
+rect 5005 59526 5039 59538
+rect 5559 59526 5593 59538
+rect 6113 59526 6147 59538
+rect 6667 59526 6701 59538
+rect 7221 59526 7255 59538
+rect 7775 59526 7809 59538
+rect 8329 59526 8363 59538
+rect 8883 59526 8917 59538
+rect 9437 59526 9471 59538
+rect 9991 59526 10025 59538
+rect 10545 59526 10579 59538
+rect 11099 59526 11133 59538
+rect 11653 59526 11687 59538
+rect 12207 59526 12241 59538
+rect 12761 59526 12795 59538
+rect 2211 57550 2212 57574
+rect 2292 57550 2293 57574
+rect 2765 57550 2766 57574
+rect 2846 57550 2847 57574
+rect 3319 57550 3320 57574
+rect 3400 57550 3401 57574
+rect 3873 57550 3874 57574
+rect 3954 57550 3955 57574
+rect 4427 57550 4428 57574
+rect 4508 57550 4509 57574
+rect 4981 57550 4982 57574
+rect 5062 57550 5063 57574
+rect 5535 57550 5536 57574
+rect 5616 57550 5617 57574
+rect 6089 57550 6090 57574
+rect 6170 57550 6171 57574
+rect 6643 57550 6644 57574
+rect 6724 57550 6725 57574
+rect 7197 57550 7198 57574
+rect 7278 57550 7279 57574
+rect 7751 57550 7752 57574
+rect 7832 57550 7833 57574
+rect 8305 57550 8306 57574
+rect 8386 57550 8387 57574
+rect 8859 57550 8860 57574
+rect 8940 57550 8941 57574
+rect 9413 57550 9414 57574
+rect 9494 57550 9495 57574
+rect 9967 57550 9968 57574
+rect 10048 57550 10049 57574
+rect 10521 57550 10522 57574
+rect 10602 57550 10603 57574
+rect 11075 57550 11076 57574
+rect 11156 57550 11157 57574
+rect 11629 57550 11630 57574
+rect 11710 57550 11711 57574
+rect 12183 57550 12184 57574
+rect 12264 57550 12265 57574
+rect 12737 57550 12738 57574
+rect 12818 57550 12819 57574
+rect 2235 57526 2269 57538
+rect 2789 57526 2823 57538
+rect 3343 57526 3377 57538
+rect 3897 57526 3931 57538
+rect 4451 57526 4485 57538
+rect 5005 57526 5039 57538
+rect 5559 57526 5593 57538
+rect 6113 57526 6147 57538
+rect 6667 57526 6701 57538
+rect 7221 57526 7255 57538
+rect 7775 57526 7809 57538
+rect 8329 57526 8363 57538
+rect 8883 57526 8917 57538
+rect 9437 57526 9471 57538
+rect 9991 57526 10025 57538
+rect 10545 57526 10579 57538
+rect 11099 57526 11133 57538
+rect 11653 57526 11687 57538
+rect 12207 57526 12241 57538
+rect 12761 57526 12795 57538
+rect 21232 55770 21304 59770
+rect 21503 55803 21621 59737
+rect 21892 55770 21952 59770
+rect 22152 55770 22224 59770
+rect 22423 55803 22541 59737
+rect 22812 55770 22872 59770
+rect 23072 55770 23144 59770
+rect 23343 55803 23461 59737
+rect 23732 55770 23792 59770
+rect 23992 55770 24064 59770
+rect 24263 55803 24381 59737
+rect 24652 55770 24712 59770
+rect 24912 55770 24984 59770
+rect 25183 55803 25301 59737
+rect 25572 55770 25632 59770
+rect 25832 55770 25904 59770
+rect 26103 55803 26221 59737
+rect 26492 55770 26552 59770
+rect 26752 55770 26824 59770
+rect 27023 55803 27141 59737
+rect 27412 55770 27472 59770
+rect 27672 55770 27744 59770
+rect 27943 55803 28061 59737
+rect 28332 55770 28392 59770
+rect 28592 55770 28664 59770
+rect 28863 55803 28981 59737
+rect 29252 55770 29312 59770
+rect 29512 55770 29584 59770
+rect 29783 55803 29901 59737
+rect 30172 55770 30232 59770
+rect 30432 55770 30504 59770
+rect 30703 55803 30821 59737
+rect 31092 55770 31152 59770
+rect 41010 55964 41082 59964
+rect 41281 55997 41399 59931
+rect 41670 55964 41730 59964
+rect 41930 55964 42002 59964
+rect 42201 55997 42319 59931
+rect 42590 55964 42650 59964
+rect 42850 55964 42922 59964
+rect 43121 55997 43239 59931
+rect 43510 55964 43570 59964
+rect 43770 55964 43842 59964
+rect 44041 55997 44159 59931
+rect 44430 55964 44490 59964
+rect 44690 55964 44762 59964
+rect 44961 55997 45079 59931
+rect 45350 55964 45410 59964
+rect 45610 55964 45682 59964
+rect 45881 55997 45999 59931
+rect 46270 55964 46330 59964
+rect 46530 55964 46602 59964
+rect 46801 55997 46919 59931
+rect 47190 55964 47250 59964
+rect 47450 55964 47522 59964
+rect 47721 55997 47839 59931
+rect 48110 55964 48170 59964
+rect 48370 55964 48442 59964
+rect 48641 55997 48759 59931
+rect 49030 55964 49090 59964
+rect 49290 55964 49362 59964
+rect 49561 55997 49679 59931
+rect 49950 55964 50010 59964
+rect 50210 55964 50282 59964
+rect 50481 55997 50599 59931
+rect 50870 55964 50930 59964
+rect 105478 58596 105550 62596
+rect 105749 58629 105867 62563
+rect 106138 58596 106198 62596
+rect 106398 58596 106470 62596
+rect 106669 58629 106787 62563
+rect 107058 58596 107118 62596
+rect 107318 58596 107390 62596
+rect 107589 58629 107707 62563
+rect 107978 58596 108038 62596
+rect 108238 58596 108310 62596
+rect 108509 58629 108627 62563
+rect 108898 58596 108958 62596
+rect 109158 58596 109230 62596
+rect 109429 58629 109547 62563
+rect 109818 58596 109878 62596
+rect 110078 58596 110150 62596
+rect 110349 58629 110467 62563
+rect 110738 58596 110798 62596
+rect 110998 58596 111070 62596
+rect 111269 58629 111387 62563
+rect 111658 58596 111718 62596
+rect 111918 58596 111990 62596
+rect 112189 58629 112307 62563
+rect 112578 58596 112638 62596
+rect 112838 58596 112910 62596
+rect 113109 58629 113227 62563
+rect 113498 58596 113558 62596
+rect 62707 57804 62708 57828
+rect 62788 57804 62789 57828
+rect 63261 57804 63262 57828
+rect 63342 57804 63343 57828
+rect 63815 57804 63816 57828
+rect 63896 57804 63897 57828
+rect 64369 57804 64370 57828
+rect 64450 57804 64451 57828
+rect 64923 57804 64924 57828
+rect 65004 57804 65005 57828
+rect 65477 57804 65478 57828
+rect 65558 57804 65559 57828
+rect 66031 57804 66032 57828
+rect 66112 57804 66113 57828
+rect 66585 57804 66586 57828
+rect 66666 57804 66667 57828
+rect 67139 57804 67140 57828
+rect 67220 57804 67221 57828
+rect 67693 57804 67694 57828
+rect 67774 57804 67775 57828
+rect 68247 57804 68248 57828
+rect 68328 57804 68329 57828
+rect 68801 57804 68802 57828
+rect 68882 57804 68883 57828
+rect 69355 57804 69356 57828
+rect 69436 57804 69437 57828
+rect 69909 57804 69910 57828
+rect 69990 57804 69991 57828
+rect 70463 57804 70464 57828
+rect 70544 57804 70545 57828
+rect 71017 57804 71018 57828
+rect 71098 57804 71099 57828
+rect 71571 57804 71572 57828
+rect 71652 57804 71653 57828
+rect 72125 57804 72126 57828
+rect 72206 57804 72207 57828
+rect 72679 57804 72680 57828
+rect 72760 57804 72761 57828
+rect 73233 57804 73234 57828
+rect 73314 57804 73315 57828
+rect 62731 57780 62765 57792
+rect 63285 57780 63319 57792
+rect 63839 57780 63873 57792
+rect 64393 57780 64427 57792
+rect 64947 57780 64981 57792
+rect 65501 57780 65535 57792
+rect 66055 57780 66089 57792
+rect 66609 57780 66643 57792
+rect 67163 57780 67197 57792
+rect 67717 57780 67751 57792
+rect 68271 57780 68305 57792
+rect 68825 57780 68859 57792
+rect 69379 57780 69413 57792
+rect 69933 57780 69967 57792
+rect 70487 57780 70521 57792
+rect 71041 57780 71075 57792
+rect 71595 57780 71629 57792
+rect 72149 57780 72183 57792
+rect 72703 57780 72737 57792
+rect 73257 57780 73291 57792
+rect 81709 57610 81710 57634
+rect 81790 57610 81791 57634
+rect 82263 57610 82264 57634
+rect 82344 57610 82345 57634
+rect 82817 57610 82818 57634
+rect 82898 57610 82899 57634
+rect 83371 57610 83372 57634
+rect 83452 57610 83453 57634
+rect 83925 57610 83926 57634
+rect 84006 57610 84007 57634
+rect 84479 57610 84480 57634
+rect 84560 57610 84561 57634
+rect 85033 57610 85034 57634
+rect 85114 57610 85115 57634
+rect 85587 57610 85588 57634
+rect 85668 57610 85669 57634
+rect 86141 57610 86142 57634
+rect 86222 57610 86223 57634
+rect 86695 57610 86696 57634
+rect 86776 57610 86777 57634
+rect 87249 57610 87250 57634
+rect 87330 57610 87331 57634
+rect 87803 57610 87804 57634
+rect 87884 57610 87885 57634
+rect 88357 57610 88358 57634
+rect 88438 57610 88439 57634
+rect 88911 57610 88912 57634
+rect 88992 57610 88993 57634
+rect 89465 57610 89466 57634
+rect 89546 57610 89547 57634
+rect 90019 57610 90020 57634
+rect 90100 57610 90101 57634
+rect 90573 57610 90574 57634
+rect 90654 57610 90655 57634
+rect 91127 57610 91128 57634
+rect 91208 57610 91209 57634
+rect 91681 57610 91682 57634
+rect 91762 57610 91763 57634
+rect 92235 57610 92236 57634
+rect 92316 57610 92317 57634
+rect 81733 57586 81767 57598
+rect 82287 57586 82321 57598
+rect 82841 57586 82875 57598
+rect 83395 57586 83429 57598
+rect 83949 57586 83983 57598
+rect 84503 57586 84537 57598
+rect 85057 57586 85091 57598
+rect 85611 57586 85645 57598
+rect 86165 57586 86199 57598
+rect 86719 57586 86753 57598
+rect 87273 57586 87307 57598
+rect 87827 57586 87861 57598
+rect 88381 57586 88415 57598
+rect 88935 57586 88969 57598
+rect 89489 57586 89523 57598
+rect 90043 57586 90077 57598
+rect 90597 57586 90631 57598
+rect 91151 57586 91185 57598
+rect 91705 57586 91739 57598
+rect 92259 57586 92293 57598
+rect 62707 55804 62708 55828
+rect 62788 55804 62789 55828
+rect 63261 55804 63262 55828
+rect 63342 55804 63343 55828
+rect 63815 55804 63816 55828
+rect 63896 55804 63897 55828
+rect 64369 55804 64370 55828
+rect 64450 55804 64451 55828
+rect 64923 55804 64924 55828
+rect 65004 55804 65005 55828
+rect 65477 55804 65478 55828
+rect 65558 55804 65559 55828
+rect 66031 55804 66032 55828
+rect 66112 55804 66113 55828
+rect 66585 55804 66586 55828
+rect 66666 55804 66667 55828
+rect 67139 55804 67140 55828
+rect 67220 55804 67221 55828
+rect 67693 55804 67694 55828
+rect 67774 55804 67775 55828
+rect 68247 55804 68248 55828
+rect 68328 55804 68329 55828
+rect 68801 55804 68802 55828
+rect 68882 55804 68883 55828
+rect 69355 55804 69356 55828
+rect 69436 55804 69437 55828
+rect 69909 55804 69910 55828
+rect 69990 55804 69991 55828
+rect 70463 55804 70464 55828
+rect 70544 55804 70545 55828
+rect 71017 55804 71018 55828
+rect 71098 55804 71099 55828
+rect 71571 55804 71572 55828
+rect 71652 55804 71653 55828
+rect 72125 55804 72126 55828
+rect 72206 55804 72207 55828
+rect 72679 55804 72680 55828
+rect 72760 55804 72761 55828
+rect 73233 55804 73234 55828
+rect 73314 55804 73315 55828
+rect 62731 55780 62765 55792
+rect 63285 55780 63319 55792
+rect 63839 55780 63873 55792
+rect 64393 55780 64427 55792
+rect 64947 55780 64981 55792
+rect 65501 55780 65535 55792
+rect 66055 55780 66089 55792
+rect 66609 55780 66643 55792
+rect 67163 55780 67197 55792
+rect 67717 55780 67751 55792
+rect 68271 55780 68305 55792
+rect 68825 55780 68859 55792
+rect 69379 55780 69413 55792
+rect 69933 55780 69967 55792
+rect 70487 55780 70521 55792
+rect 71041 55780 71075 55792
+rect 71595 55780 71629 55792
+rect 72149 55780 72183 55792
+rect 72703 55780 72737 55792
+rect 73257 55780 73291 55792
+rect 81709 55610 81710 55634
+rect 81790 55610 81791 55634
+rect 82263 55610 82264 55634
+rect 82344 55610 82345 55634
+rect 82817 55610 82818 55634
+rect 82898 55610 82899 55634
+rect 83371 55610 83372 55634
+rect 83452 55610 83453 55634
+rect 83925 55610 83926 55634
+rect 84006 55610 84007 55634
+rect 84479 55610 84480 55634
+rect 84560 55610 84561 55634
+rect 85033 55610 85034 55634
+rect 85114 55610 85115 55634
+rect 85587 55610 85588 55634
+rect 85668 55610 85669 55634
+rect 86141 55610 86142 55634
+rect 86222 55610 86223 55634
+rect 86695 55610 86696 55634
+rect 86776 55610 86777 55634
+rect 87249 55610 87250 55634
+rect 87330 55610 87331 55634
+rect 87803 55610 87804 55634
+rect 87884 55610 87885 55634
+rect 88357 55610 88358 55634
+rect 88438 55610 88439 55634
+rect 88911 55610 88912 55634
+rect 88992 55610 88993 55634
+rect 89465 55610 89466 55634
+rect 89546 55610 89547 55634
+rect 90019 55610 90020 55634
+rect 90100 55610 90101 55634
+rect 90573 55610 90574 55634
+rect 90654 55610 90655 55634
+rect 91127 55610 91128 55634
+rect 91208 55610 91209 55634
+rect 91681 55610 91682 55634
+rect 91762 55610 91763 55634
+rect 92235 55610 92236 55634
+rect 92316 55610 92317 55634
+rect 81733 55586 81767 55598
+rect 82287 55586 82321 55598
+rect 82841 55586 82875 55598
+rect 83395 55586 83429 55598
+rect 83949 55586 83983 55598
+rect 84503 55586 84537 55598
+rect 85057 55586 85091 55598
+rect 85611 55586 85645 55598
+rect 86165 55586 86199 55598
+rect 86719 55586 86753 55598
+rect 87273 55586 87307 55598
+rect 87827 55586 87861 55598
+rect 88381 55586 88415 55598
+rect 88935 55586 88969 55598
+rect 89489 55586 89523 55598
+rect 90043 55586 90077 55598
+rect 90597 55586 90631 55598
+rect 91151 55586 91185 55598
+rect 91705 55586 91739 55598
+rect 92259 55586 92293 55598
+rect 2211 55550 2212 55574
+rect 2292 55550 2293 55574
+rect 2765 55550 2766 55574
+rect 2846 55550 2847 55574
+rect 3319 55550 3320 55574
+rect 3400 55550 3401 55574
+rect 3873 55550 3874 55574
+rect 3954 55550 3955 55574
+rect 4427 55550 4428 55574
+rect 4508 55550 4509 55574
+rect 4981 55550 4982 55574
+rect 5062 55550 5063 55574
+rect 5535 55550 5536 55574
+rect 5616 55550 5617 55574
+rect 6089 55550 6090 55574
+rect 6170 55550 6171 55574
+rect 6643 55550 6644 55574
+rect 6724 55550 6725 55574
+rect 7197 55550 7198 55574
+rect 7278 55550 7279 55574
+rect 7751 55550 7752 55574
+rect 7832 55550 7833 55574
+rect 8305 55550 8306 55574
+rect 8386 55550 8387 55574
+rect 8859 55550 8860 55574
+rect 8940 55550 8941 55574
+rect 9413 55550 9414 55574
+rect 9494 55550 9495 55574
+rect 9967 55550 9968 55574
+rect 10048 55550 10049 55574
+rect 10521 55550 10522 55574
+rect 10602 55550 10603 55574
+rect 11075 55550 11076 55574
+rect 11156 55550 11157 55574
+rect 11629 55550 11630 55574
+rect 11710 55550 11711 55574
+rect 12183 55550 12184 55574
+rect 12264 55550 12265 55574
+rect 12737 55550 12738 55574
+rect 12818 55550 12819 55574
+rect 2235 55526 2269 55538
+rect 2789 55526 2823 55538
+rect 3343 55526 3377 55538
+rect 3897 55526 3931 55538
+rect 4451 55526 4485 55538
+rect 5005 55526 5039 55538
+rect 5559 55526 5593 55538
+rect 6113 55526 6147 55538
+rect 6667 55526 6701 55538
+rect 7221 55526 7255 55538
+rect 7775 55526 7809 55538
+rect 8329 55526 8363 55538
+rect 8883 55526 8917 55538
+rect 9437 55526 9471 55538
+rect 9991 55526 10025 55538
+rect 10545 55526 10579 55538
+rect 11099 55526 11133 55538
+rect 11653 55526 11687 55538
+rect 12207 55526 12241 55538
+rect 12761 55526 12795 55538
+rect 2211 53550 2212 53574
+rect 2292 53550 2293 53574
+rect 2765 53550 2766 53574
+rect 2846 53550 2847 53574
+rect 3319 53550 3320 53574
+rect 3400 53550 3401 53574
+rect 3873 53550 3874 53574
+rect 3954 53550 3955 53574
+rect 4427 53550 4428 53574
+rect 4508 53550 4509 53574
+rect 4981 53550 4982 53574
+rect 5062 53550 5063 53574
+rect 5535 53550 5536 53574
+rect 5616 53550 5617 53574
+rect 6089 53550 6090 53574
+rect 6170 53550 6171 53574
+rect 6643 53550 6644 53574
+rect 6724 53550 6725 53574
+rect 7197 53550 7198 53574
+rect 7278 53550 7279 53574
+rect 7751 53550 7752 53574
+rect 7832 53550 7833 53574
+rect 8305 53550 8306 53574
+rect 8386 53550 8387 53574
+rect 8859 53550 8860 53574
+rect 8940 53550 8941 53574
+rect 9413 53550 9414 53574
+rect 9494 53550 9495 53574
+rect 9967 53550 9968 53574
+rect 10048 53550 10049 53574
+rect 10521 53550 10522 53574
+rect 10602 53550 10603 53574
+rect 11075 53550 11076 53574
+rect 11156 53550 11157 53574
+rect 11629 53550 11630 53574
+rect 11710 53550 11711 53574
+rect 12183 53550 12184 53574
+rect 12264 53550 12265 53574
+rect 12737 53550 12738 53574
+rect 12818 53550 12819 53574
+rect 2235 53526 2269 53538
+rect 2789 53526 2823 53538
+rect 3343 53526 3377 53538
+rect 3897 53526 3931 53538
+rect 4451 53526 4485 53538
+rect 5005 53526 5039 53538
+rect 5559 53526 5593 53538
+rect 6113 53526 6147 53538
+rect 6667 53526 6701 53538
+rect 7221 53526 7255 53538
+rect 7775 53526 7809 53538
+rect 8329 53526 8363 53538
+rect 8883 53526 8917 53538
+rect 9437 53526 9471 53538
+rect 9991 53526 10025 53538
+rect 10545 53526 10579 53538
+rect 11099 53526 11133 53538
+rect 11653 53526 11687 53538
+rect 12207 53526 12241 53538
+rect 12761 53526 12795 53538
+rect 19352 52294 19402 53694
+rect 19502 52294 19630 53694
+rect 19658 52294 19786 53694
+rect 19814 52294 19942 53694
+rect 19970 52294 20098 53694
+rect 20126 52294 20254 53694
+rect 20282 52294 20410 53694
+rect 20438 52294 20566 53694
+rect 20594 52294 20722 53694
+rect 20750 52294 20878 53694
+rect 20906 52294 21034 53694
+rect 21062 52294 21190 53694
+rect 21218 52294 21346 53694
+rect 21374 52294 21502 53694
+rect 21530 52294 21658 53694
+rect 21686 52294 21814 53694
+rect 21842 52294 21970 53694
+rect 21998 52294 22126 53694
+rect 22154 52294 22282 53694
+rect 22310 52294 22438 53694
+rect 22466 52294 22594 53694
+rect 22622 52294 22750 53694
+rect 22778 52294 22906 53694
+rect 22934 52294 23062 53694
+rect 23090 52294 23218 53694
+rect 23246 52294 23374 53694
+rect 23402 52294 23530 53694
+rect 23558 52294 23686 53694
+rect 23714 52294 23842 53694
+rect 23870 52294 23998 53694
+rect 24026 52294 24154 53694
+rect 24182 52294 24310 53694
+rect 24338 52294 24466 53694
+rect 24494 52294 24622 53694
+rect 24650 52294 24778 53694
+rect 24806 52294 24934 53694
+rect 24962 52294 25090 53694
+rect 25118 52294 25246 53694
+rect 25274 52294 25402 53694
+rect 25430 52294 25558 53694
+rect 25586 52294 25714 53694
+rect 25742 52294 25870 53694
+rect 25898 52294 26026 53694
+rect 26054 52294 26182 53694
+rect 26210 52294 26338 53694
+rect 26366 52294 26494 53694
+rect 26522 52294 26650 53694
+rect 26678 52294 26806 53694
+rect 26834 52294 26962 53694
+rect 26990 52294 27118 53694
+rect 27146 52294 27196 53694
+rect 29067 52850 29117 54250
+rect 29217 52850 29345 54250
+rect 29373 52850 29501 54250
+rect 29529 52850 29657 54250
+rect 29685 52850 29813 54250
+rect 29841 52850 29969 54250
+rect 29997 52850 30125 54250
+rect 30153 52850 30281 54250
+rect 30309 52850 30437 54250
+rect 30465 52850 30593 54250
+rect 30621 52850 30749 54250
+rect 30777 52850 30905 54250
+rect 30933 52850 31061 54250
+rect 31089 52850 31217 54250
+rect 31245 52850 31373 54250
+rect 31401 52850 31451 54250
+rect 39130 52488 39180 53888
+rect 39280 52488 39408 53888
+rect 39436 52488 39564 53888
+rect 39592 52488 39720 53888
+rect 39748 52488 39876 53888
+rect 39904 52488 40032 53888
+rect 40060 52488 40188 53888
+rect 40216 52488 40344 53888
+rect 40372 52488 40500 53888
+rect 40528 52488 40656 53888
+rect 40684 52488 40812 53888
+rect 40840 52488 40968 53888
+rect 40996 52488 41124 53888
+rect 41152 52488 41280 53888
+rect 41308 52488 41436 53888
+rect 41464 52488 41592 53888
+rect 41620 52488 41748 53888
+rect 41776 52488 41904 53888
+rect 41932 52488 42060 53888
+rect 42088 52488 42216 53888
+rect 42244 52488 42372 53888
+rect 42400 52488 42528 53888
+rect 42556 52488 42684 53888
+rect 42712 52488 42840 53888
+rect 42868 52488 42996 53888
+rect 43024 52488 43152 53888
+rect 43180 52488 43308 53888
+rect 43336 52488 43464 53888
+rect 43492 52488 43620 53888
+rect 43648 52488 43776 53888
+rect 43804 52488 43932 53888
+rect 43960 52488 44088 53888
+rect 44116 52488 44244 53888
+rect 44272 52488 44400 53888
+rect 44428 52488 44556 53888
+rect 44584 52488 44712 53888
+rect 44740 52488 44868 53888
+rect 44896 52488 45024 53888
+rect 45052 52488 45180 53888
+rect 45208 52488 45336 53888
+rect 45364 52488 45492 53888
+rect 45520 52488 45648 53888
+rect 45676 52488 45804 53888
+rect 45832 52488 45960 53888
+rect 45988 52488 46116 53888
+rect 46144 52488 46272 53888
+rect 46300 52488 46428 53888
+rect 46456 52488 46584 53888
+rect 46612 52488 46740 53888
+rect 46768 52488 46896 53888
+rect 46924 52488 46974 53888
+rect 48845 53044 48895 54444
+rect 48995 53044 49123 54444
+rect 49151 53044 49279 54444
+rect 49307 53044 49435 54444
+rect 49463 53044 49591 54444
+rect 49619 53044 49747 54444
+rect 49775 53044 49903 54444
+rect 49931 53044 50059 54444
+rect 50087 53044 50215 54444
+rect 50243 53044 50371 54444
+rect 50399 53044 50527 54444
+rect 50555 53044 50683 54444
+rect 50711 53044 50839 54444
+rect 50867 53044 50995 54444
+rect 51023 53044 51151 54444
+rect 51179 53044 51229 54444
+rect 103638 53996 103710 57996
+rect 103909 54029 104027 57963
+rect 104298 53996 104358 57996
+rect 104558 53996 104630 57996
+rect 104829 54029 104947 57963
+rect 105218 53996 105278 57996
+rect 105478 53996 105550 57996
+rect 105749 54029 105867 57963
+rect 106138 53996 106198 57996
+rect 106398 53996 106470 57996
+rect 106669 54029 106787 57963
+rect 107058 53996 107118 57996
+rect 107318 53996 107390 57996
+rect 107589 54029 107707 57963
+rect 107978 53996 108038 57996
+rect 108238 53996 108310 57996
+rect 108509 54029 108627 57963
+rect 108898 53996 108958 57996
+rect 109158 53996 109230 57996
+rect 109429 54029 109547 57963
+rect 109818 53996 109878 57996
+rect 110078 53996 110150 57996
+rect 110349 54029 110467 57963
+rect 110738 53996 110798 57996
+rect 110998 53996 111070 57996
+rect 111269 54029 111387 57963
+rect 111658 53996 111718 57996
+rect 111918 53996 111990 57996
+rect 112189 54029 112307 57963
+rect 112578 53996 112638 57996
+rect 112838 53996 112910 57996
+rect 113109 54029 113227 57963
+rect 113498 53996 113558 57996
+rect 127615 55792 127617 55917
+rect 62707 53804 62708 53828
+rect 62788 53804 62789 53828
+rect 63261 53804 63262 53828
+rect 63342 53804 63343 53828
+rect 63815 53804 63816 53828
+rect 63896 53804 63897 53828
+rect 64369 53804 64370 53828
+rect 64450 53804 64451 53828
+rect 64923 53804 64924 53828
+rect 65004 53804 65005 53828
+rect 65477 53804 65478 53828
+rect 65558 53804 65559 53828
+rect 66031 53804 66032 53828
+rect 66112 53804 66113 53828
+rect 66585 53804 66586 53828
+rect 66666 53804 66667 53828
+rect 67139 53804 67140 53828
+rect 67220 53804 67221 53828
+rect 67693 53804 67694 53828
+rect 67774 53804 67775 53828
+rect 68247 53804 68248 53828
+rect 68328 53804 68329 53828
+rect 68801 53804 68802 53828
+rect 68882 53804 68883 53828
+rect 69355 53804 69356 53828
+rect 69436 53804 69437 53828
+rect 69909 53804 69910 53828
+rect 69990 53804 69991 53828
+rect 70463 53804 70464 53828
+rect 70544 53804 70545 53828
+rect 71017 53804 71018 53828
+rect 71098 53804 71099 53828
+rect 71571 53804 71572 53828
+rect 71652 53804 71653 53828
+rect 72125 53804 72126 53828
+rect 72206 53804 72207 53828
+rect 72679 53804 72680 53828
+rect 72760 53804 72761 53828
+rect 73233 53804 73234 53828
+rect 73314 53804 73315 53828
+rect 62731 53780 62765 53792
+rect 63285 53780 63319 53792
+rect 63839 53780 63873 53792
+rect 64393 53780 64427 53792
+rect 64947 53780 64981 53792
+rect 65501 53780 65535 53792
+rect 66055 53780 66089 53792
+rect 66609 53780 66643 53792
+rect 67163 53780 67197 53792
+rect 67717 53780 67751 53792
+rect 68271 53780 68305 53792
+rect 68825 53780 68859 53792
+rect 69379 53780 69413 53792
+rect 69933 53780 69967 53792
+rect 70487 53780 70521 53792
+rect 71041 53780 71075 53792
+rect 71595 53780 71629 53792
+rect 72149 53780 72183 53792
+rect 72703 53780 72737 53792
+rect 73257 53780 73291 53792
+rect 81709 53610 81710 53634
+rect 81790 53610 81791 53634
+rect 82263 53610 82264 53634
+rect 82344 53610 82345 53634
+rect 82817 53610 82818 53634
+rect 82898 53610 82899 53634
+rect 83371 53610 83372 53634
+rect 83452 53610 83453 53634
+rect 83925 53610 83926 53634
+rect 84006 53610 84007 53634
+rect 84479 53610 84480 53634
+rect 84560 53610 84561 53634
+rect 85033 53610 85034 53634
+rect 85114 53610 85115 53634
+rect 85587 53610 85588 53634
+rect 85668 53610 85669 53634
+rect 86141 53610 86142 53634
+rect 86222 53610 86223 53634
+rect 86695 53610 86696 53634
+rect 86776 53610 86777 53634
+rect 87249 53610 87250 53634
+rect 87330 53610 87331 53634
+rect 87803 53610 87804 53634
+rect 87884 53610 87885 53634
+rect 88357 53610 88358 53634
+rect 88438 53610 88439 53634
+rect 88911 53610 88912 53634
+rect 88992 53610 88993 53634
+rect 89465 53610 89466 53634
+rect 89546 53610 89547 53634
+rect 90019 53610 90020 53634
+rect 90100 53610 90101 53634
+rect 90573 53610 90574 53634
+rect 90654 53610 90655 53634
+rect 91127 53610 91128 53634
+rect 91208 53610 91209 53634
+rect 91681 53610 91682 53634
+rect 91762 53610 91763 53634
+rect 92235 53610 92236 53634
+rect 92316 53610 92317 53634
+rect 81733 53586 81767 53598
+rect 82287 53586 82321 53598
+rect 82841 53586 82875 53598
+rect 83395 53586 83429 53598
+rect 83949 53586 83983 53598
+rect 84503 53586 84537 53598
+rect 85057 53586 85091 53598
+rect 85611 53586 85645 53598
+rect 86165 53586 86199 53598
+rect 86719 53586 86753 53598
+rect 87273 53586 87307 53598
+rect 87827 53586 87861 53598
+rect 88381 53586 88415 53598
+rect 88935 53586 88969 53598
+rect 89489 53586 89523 53598
+rect 90043 53586 90077 53598
+rect 90597 53586 90631 53598
+rect 91151 53586 91185 53598
+rect 91705 53586 91739 53598
+rect 92259 53586 92293 53598
+rect 2211 51550 2212 51574
+rect 2292 51550 2293 51574
+rect 2765 51550 2766 51574
+rect 2846 51550 2847 51574
+rect 3319 51550 3320 51574
+rect 3400 51550 3401 51574
+rect 3873 51550 3874 51574
+rect 3954 51550 3955 51574
+rect 4427 51550 4428 51574
+rect 4508 51550 4509 51574
+rect 4981 51550 4982 51574
+rect 5062 51550 5063 51574
+rect 5535 51550 5536 51574
+rect 5616 51550 5617 51574
+rect 6089 51550 6090 51574
+rect 6170 51550 6171 51574
+rect 6643 51550 6644 51574
+rect 6724 51550 6725 51574
+rect 7197 51550 7198 51574
+rect 7278 51550 7279 51574
+rect 7751 51550 7752 51574
+rect 7832 51550 7833 51574
+rect 8305 51550 8306 51574
+rect 8386 51550 8387 51574
+rect 8859 51550 8860 51574
+rect 8940 51550 8941 51574
+rect 9413 51550 9414 51574
+rect 9494 51550 9495 51574
+rect 9967 51550 9968 51574
+rect 10048 51550 10049 51574
+rect 10521 51550 10522 51574
+rect 10602 51550 10603 51574
+rect 11075 51550 11076 51574
+rect 11156 51550 11157 51574
+rect 11629 51550 11630 51574
+rect 11710 51550 11711 51574
+rect 12183 51550 12184 51574
+rect 12264 51550 12265 51574
+rect 12737 51550 12738 51574
+rect 12818 51550 12819 51574
+rect 2235 51526 2269 51538
+rect 2789 51526 2823 51538
+rect 3343 51526 3377 51538
+rect 3897 51526 3931 51538
+rect 4451 51526 4485 51538
+rect 5005 51526 5039 51538
+rect 5559 51526 5593 51538
+rect 6113 51526 6147 51538
+rect 6667 51526 6701 51538
+rect 7221 51526 7255 51538
+rect 7775 51526 7809 51538
+rect 8329 51526 8363 51538
+rect 8883 51526 8917 51538
+rect 9437 51526 9471 51538
+rect 9991 51526 10025 51538
+rect 10545 51526 10579 51538
+rect 11099 51526 11133 51538
+rect 11653 51526 11687 51538
+rect 12207 51526 12241 51538
+rect 12761 51526 12795 51538
+rect 29647 50763 29697 51763
+rect 30497 50763 30547 51763
+rect 30799 50763 30849 51763
+rect 31649 50763 31699 51763
+rect 49425 50957 49475 51957
+rect 50275 50957 50325 51957
+rect 50577 50957 50627 51957
+rect 51427 50957 51477 51957
+rect 62707 51804 62708 51828
+rect 62788 51804 62789 51828
+rect 63261 51804 63262 51828
+rect 63342 51804 63343 51828
+rect 63815 51804 63816 51828
+rect 63896 51804 63897 51828
+rect 64369 51804 64370 51828
+rect 64450 51804 64451 51828
+rect 64923 51804 64924 51828
+rect 65004 51804 65005 51828
+rect 65477 51804 65478 51828
+rect 65558 51804 65559 51828
+rect 66031 51804 66032 51828
+rect 66112 51804 66113 51828
+rect 66585 51804 66586 51828
+rect 66666 51804 66667 51828
+rect 67139 51804 67140 51828
+rect 67220 51804 67221 51828
+rect 67693 51804 67694 51828
+rect 67774 51804 67775 51828
+rect 68247 51804 68248 51828
+rect 68328 51804 68329 51828
+rect 68801 51804 68802 51828
+rect 68882 51804 68883 51828
+rect 69355 51804 69356 51828
+rect 69436 51804 69437 51828
+rect 69909 51804 69910 51828
+rect 69990 51804 69991 51828
+rect 70463 51804 70464 51828
+rect 70544 51804 70545 51828
+rect 71017 51804 71018 51828
+rect 71098 51804 71099 51828
+rect 71571 51804 71572 51828
+rect 71652 51804 71653 51828
+rect 72125 51804 72126 51828
+rect 72206 51804 72207 51828
+rect 72679 51804 72680 51828
+rect 72760 51804 72761 51828
+rect 73233 51804 73234 51828
+rect 73314 51804 73315 51828
+rect 62731 51780 62765 51792
+rect 63285 51780 63319 51792
+rect 63839 51780 63873 51792
+rect 64393 51780 64427 51792
+rect 64947 51780 64981 51792
+rect 65501 51780 65535 51792
+rect 66055 51780 66089 51792
+rect 66609 51780 66643 51792
+rect 67163 51780 67197 51792
+rect 67717 51780 67751 51792
+rect 68271 51780 68305 51792
+rect 68825 51780 68859 51792
+rect 69379 51780 69413 51792
+rect 69933 51780 69967 51792
+rect 70487 51780 70521 51792
+rect 71041 51780 71075 51792
+rect 71595 51780 71629 51792
+rect 72149 51780 72183 51792
+rect 72703 51780 72737 51792
+rect 73257 51780 73291 51792
+rect 81709 51610 81710 51634
+rect 81790 51610 81791 51634
+rect 82263 51610 82264 51634
+rect 82344 51610 82345 51634
+rect 82817 51610 82818 51634
+rect 82898 51610 82899 51634
+rect 83371 51610 83372 51634
+rect 83452 51610 83453 51634
+rect 83925 51610 83926 51634
+rect 84006 51610 84007 51634
+rect 84479 51610 84480 51634
+rect 84560 51610 84561 51634
+rect 85033 51610 85034 51634
+rect 85114 51610 85115 51634
+rect 85587 51610 85588 51634
+rect 85668 51610 85669 51634
+rect 86141 51610 86142 51634
+rect 86222 51610 86223 51634
+rect 86695 51610 86696 51634
+rect 86776 51610 86777 51634
+rect 87249 51610 87250 51634
+rect 87330 51610 87331 51634
+rect 87803 51610 87804 51634
+rect 87884 51610 87885 51634
+rect 88357 51610 88358 51634
+rect 88438 51610 88439 51634
+rect 88911 51610 88912 51634
+rect 88992 51610 88993 51634
+rect 89465 51610 89466 51634
+rect 89546 51610 89547 51634
+rect 90019 51610 90020 51634
+rect 90100 51610 90101 51634
+rect 90573 51610 90574 51634
+rect 90654 51610 90655 51634
+rect 91127 51610 91128 51634
+rect 91208 51610 91209 51634
+rect 91681 51610 91682 51634
+rect 91762 51610 91763 51634
+rect 92235 51610 92236 51634
+rect 92316 51610 92317 51634
+rect 81733 51586 81767 51598
+rect 82287 51586 82321 51598
+rect 82841 51586 82875 51598
+rect 83395 51586 83429 51598
+rect 83949 51586 83983 51598
+rect 84503 51586 84537 51598
+rect 85057 51586 85091 51598
+rect 85611 51586 85645 51598
+rect 86165 51586 86199 51598
+rect 86719 51586 86753 51598
+rect 87273 51586 87307 51598
+rect 87827 51586 87861 51598
+rect 88381 51586 88415 51598
+rect 88935 51586 88969 51598
+rect 89489 51586 89523 51598
+rect 90043 51586 90077 51598
+rect 90597 51586 90631 51598
+rect 91151 51586 91185 51598
+rect 91705 51586 91739 51598
+rect 92259 51586 92293 51598
+rect -432 50006 -366 50022
+rect 6799 49836 6885 49872
+rect 3431 49642 3783 49668
+rect 4255 49642 4607 49668
+rect 5079 49642 5431 49668
+rect 5903 49642 6255 49668
+rect 3457 46643 3458 49642
+rect 3757 46643 3783 49642
+rect 3457 46642 3783 46643
+rect 4281 46643 4282 49642
+rect 4581 46643 4607 49642
+rect 4281 46642 4607 46643
+rect 5105 46643 5106 49642
+rect 5405 46643 5431 49642
+rect 5105 46642 5431 46643
+rect 5929 46643 5930 49642
+rect 6229 46643 6255 49642
+rect 5929 46642 6255 46643
+rect 6799 46448 6835 49836
+rect 6849 46448 6885 49836
+rect 7429 49642 7781 49668
+rect 8253 49642 8605 49668
+rect 9077 49642 9429 49668
+rect 9901 49642 10253 49668
+rect 7455 46643 7456 49642
+rect 7755 46643 7781 49642
+rect 7455 46642 7781 46643
+rect 8279 46643 8280 49642
+rect 8579 46643 8605 49642
+rect 8279 46642 8605 46643
+rect 9103 46643 9104 49642
+rect 9403 46643 9429 49642
+rect 9103 46642 9429 46643
+rect 9927 46643 9928 49642
+rect 10227 46643 10253 49642
+rect 21039 49519 21089 50519
+rect 21889 49519 21939 50519
+rect 22191 49519 22241 50519
+rect 23841 49519 23891 50519
+rect 24143 49519 24193 50519
+rect 25793 49519 25843 50519
+rect 26095 49519 26145 50519
+rect 27745 49519 27795 50519
+rect 28047 49519 28097 50519
+rect 29697 49519 29747 50519
+rect 29999 49519 30049 50519
+rect 31649 49519 31699 50519
+rect 40817 49713 40867 50713
+rect 41667 49713 41717 50713
+rect 41969 49713 42019 50713
+rect 43619 49713 43669 50713
+rect 43921 49713 43971 50713
+rect 45571 49713 45621 50713
+rect 45873 49713 45923 50713
+rect 47523 49713 47573 50713
+rect 47825 49713 47875 50713
+rect 49475 49713 49525 50713
+rect 49777 49713 49827 50713
+rect 51427 49713 51477 50713
+rect 101758 50520 101808 51920
+rect 101908 50520 102036 51920
+rect 102064 50520 102192 51920
+rect 102220 50520 102348 51920
+rect 102376 50520 102504 51920
+rect 102532 50520 102660 51920
+rect 102688 50520 102816 51920
+rect 102844 50520 102972 51920
+rect 103000 50520 103128 51920
+rect 103156 50520 103284 51920
+rect 103312 50520 103440 51920
+rect 103468 50520 103596 51920
+rect 103624 50520 103752 51920
+rect 103780 50520 103908 51920
+rect 103936 50520 104064 51920
+rect 104092 50520 104220 51920
+rect 104248 50520 104376 51920
+rect 104404 50520 104532 51920
+rect 104560 50520 104688 51920
+rect 104716 50520 104844 51920
+rect 104872 50520 105000 51920
+rect 105028 50520 105156 51920
+rect 105184 50520 105312 51920
+rect 105340 50520 105468 51920
+rect 105496 50520 105624 51920
+rect 105652 50520 105780 51920
+rect 105808 50520 105936 51920
+rect 105964 50520 106092 51920
+rect 106120 50520 106248 51920
+rect 106276 50520 106404 51920
+rect 106432 50520 106560 51920
+rect 106588 50520 106716 51920
+rect 106744 50520 106872 51920
+rect 106900 50520 107028 51920
+rect 107056 50520 107184 51920
+rect 107212 50520 107340 51920
+rect 107368 50520 107496 51920
+rect 107524 50520 107652 51920
+rect 107680 50520 107808 51920
+rect 107836 50520 107964 51920
+rect 107992 50520 108120 51920
+rect 108148 50520 108276 51920
+rect 108304 50520 108432 51920
+rect 108460 50520 108588 51920
+rect 108616 50520 108744 51920
+rect 108772 50520 108900 51920
+rect 108928 50520 109056 51920
+rect 109084 50520 109212 51920
+rect 109240 50520 109368 51920
+rect 109396 50520 109524 51920
+rect 109552 50520 109602 51920
+rect 111473 51076 111523 52476
+rect 111623 51076 111751 52476
+rect 111779 51076 111907 52476
+rect 111935 51076 112063 52476
+rect 112091 51076 112219 52476
+rect 112247 51076 112375 52476
+rect 112403 51076 112531 52476
+rect 112559 51076 112687 52476
+rect 112715 51076 112843 52476
+rect 112871 51076 112999 52476
+rect 113027 51076 113155 52476
+rect 113183 51076 113311 52476
+rect 113339 51076 113467 52476
+rect 113495 51076 113623 52476
+rect 113651 51076 113779 52476
+rect 113807 51076 113857 52476
+rect 62707 49804 62708 49828
+rect 62788 49804 62789 49828
+rect 63261 49804 63262 49828
+rect 63342 49804 63343 49828
+rect 63815 49804 63816 49828
+rect 63896 49804 63897 49828
+rect 64369 49804 64370 49828
+rect 64450 49804 64451 49828
+rect 64923 49804 64924 49828
+rect 65004 49804 65005 49828
+rect 65477 49804 65478 49828
+rect 65558 49804 65559 49828
+rect 66031 49804 66032 49828
+rect 66112 49804 66113 49828
+rect 66585 49804 66586 49828
+rect 66666 49804 66667 49828
+rect 67139 49804 67140 49828
+rect 67220 49804 67221 49828
+rect 67693 49804 67694 49828
+rect 67774 49804 67775 49828
+rect 68247 49804 68248 49828
+rect 68328 49804 68329 49828
+rect 68801 49804 68802 49828
+rect 68882 49804 68883 49828
+rect 69355 49804 69356 49828
+rect 69436 49804 69437 49828
+rect 69909 49804 69910 49828
+rect 69990 49804 69991 49828
+rect 70463 49804 70464 49828
+rect 70544 49804 70545 49828
+rect 71017 49804 71018 49828
+rect 71098 49804 71099 49828
+rect 71571 49804 71572 49828
+rect 71652 49804 71653 49828
+rect 72125 49804 72126 49828
+rect 72206 49804 72207 49828
+rect 72679 49804 72680 49828
+rect 72760 49804 72761 49828
+rect 73233 49804 73234 49828
+rect 73314 49804 73315 49828
+rect 62731 49780 62765 49792
+rect 63285 49780 63319 49792
+rect 63839 49780 63873 49792
+rect 64393 49780 64427 49792
+rect 64947 49780 64981 49792
+rect 65501 49780 65535 49792
+rect 66055 49780 66089 49792
+rect 66609 49780 66643 49792
+rect 67163 49780 67197 49792
+rect 67717 49780 67751 49792
+rect 68271 49780 68305 49792
+rect 68825 49780 68859 49792
+rect 69379 49780 69413 49792
+rect 69933 49780 69967 49792
+rect 70487 49780 70521 49792
+rect 71041 49780 71075 49792
+rect 71595 49780 71629 49792
+rect 72149 49780 72183 49792
+rect 72703 49780 72737 49792
+rect 73257 49780 73291 49792
+rect 81709 49610 81710 49634
+rect 81790 49610 81791 49634
+rect 82263 49610 82264 49634
+rect 82344 49610 82345 49634
+rect 82817 49610 82818 49634
+rect 82898 49610 82899 49634
+rect 83371 49610 83372 49634
+rect 83452 49610 83453 49634
+rect 83925 49610 83926 49634
+rect 84006 49610 84007 49634
+rect 84479 49610 84480 49634
+rect 84560 49610 84561 49634
+rect 85033 49610 85034 49634
+rect 85114 49610 85115 49634
+rect 85587 49610 85588 49634
+rect 85668 49610 85669 49634
+rect 86141 49610 86142 49634
+rect 86222 49610 86223 49634
+rect 86695 49610 86696 49634
+rect 86776 49610 86777 49634
+rect 87249 49610 87250 49634
+rect 87330 49610 87331 49634
+rect 87803 49610 87804 49634
+rect 87884 49610 87885 49634
+rect 88357 49610 88358 49634
+rect 88438 49610 88439 49634
+rect 88911 49610 88912 49634
+rect 88992 49610 88993 49634
+rect 89465 49610 89466 49634
+rect 89546 49610 89547 49634
+rect 90019 49610 90020 49634
+rect 90100 49610 90101 49634
+rect 90573 49610 90574 49634
+rect 90654 49610 90655 49634
+rect 91127 49610 91128 49634
+rect 91208 49610 91209 49634
+rect 91681 49610 91682 49634
+rect 91762 49610 91763 49634
+rect 92235 49610 92236 49634
+rect 92316 49610 92317 49634
+rect 81733 49586 81767 49598
+rect 82287 49586 82321 49598
+rect 82841 49586 82875 49598
+rect 83395 49586 83429 49598
+rect 83949 49586 83983 49598
+rect 84503 49586 84537 49598
+rect 85057 49586 85091 49598
+rect 85611 49586 85645 49598
+rect 86165 49586 86199 49598
+rect 86719 49586 86753 49598
+rect 87273 49586 87307 49598
+rect 87827 49586 87861 49598
+rect 88381 49586 88415 49598
+rect 88935 49586 88969 49598
+rect 89489 49586 89523 49598
+rect 90043 49586 90077 49598
+rect 90597 49586 90631 49598
+rect 91151 49586 91185 49598
+rect 91705 49586 91739 49598
+rect 92259 49586 92293 49598
+rect 21039 48275 21089 49275
+rect 21889 48275 21939 49275
+rect 22191 48275 22241 49275
+rect 23841 48275 23891 49275
+rect 24143 48275 24193 49275
+rect 25793 48275 25843 49275
+rect 26095 48275 26145 49275
+rect 27745 48275 27795 49275
+rect 28047 48275 28097 49275
+rect 29697 48275 29747 49275
+rect 29999 48275 30049 49275
+rect 31649 48275 31699 49275
+rect 40817 48469 40867 49469
+rect 41667 48469 41717 49469
+rect 41969 48469 42019 49469
+rect 43619 48469 43669 49469
+rect 43921 48469 43971 49469
+rect 45571 48469 45621 49469
+rect 45873 48469 45923 49469
+rect 47523 48469 47573 49469
+rect 47825 48469 47875 49469
+rect 49475 48469 49525 49469
+rect 49777 48469 49827 49469
+rect 51427 48469 51477 49469
+rect 112053 48989 112103 49989
+rect 112903 48989 112953 49989
+rect 113205 48989 113255 49989
+rect 114055 48989 114105 49989
+rect 60064 48260 60130 48276
+rect 21039 47031 21089 48031
+rect 21889 47031 21939 48031
+rect 22191 47031 22241 48031
+rect 23841 47031 23891 48031
+rect 24143 47031 24193 48031
+rect 25793 47031 25843 48031
+rect 26095 47031 26145 48031
+rect 27745 47031 27795 48031
+rect 28047 47031 28097 48031
+rect 29697 47031 29747 48031
+rect 29999 47031 30049 48031
+rect 31649 47031 31699 48031
+rect 40817 47225 40867 48225
+rect 41667 47225 41717 48225
+rect 41969 47225 42019 48225
+rect 43619 47225 43669 48225
+rect 43921 47225 43971 48225
+rect 45571 47225 45621 48225
+rect 45873 47225 45923 48225
+rect 47523 47225 47573 48225
+rect 47825 47225 47875 48225
+rect 49475 47225 49525 48225
+rect 49777 47225 49827 48225
+rect 51427 47225 51477 48225
+rect 67295 48090 67381 48126
+rect 63927 47896 64279 47922
+rect 64751 47896 65103 47922
+rect 65575 47896 65927 47922
+rect 66399 47896 66751 47922
+rect 9927 46642 10253 46643
+rect 6799 46412 6885 46448
+rect 63953 44897 63954 47896
+rect 64253 44897 64279 47896
+rect 63953 44896 64279 44897
+rect 64777 44897 64778 47896
+rect 65077 44897 65103 47896
+rect 64777 44896 65103 44897
+rect 65601 44897 65602 47896
+rect 65901 44897 65927 47896
+rect 65601 44896 65927 44897
+rect 66425 44897 66426 47896
+rect 66725 44897 66751 47896
+rect 66425 44896 66751 44897
+rect 67295 44702 67331 48090
+rect 67345 44702 67381 48090
+rect 79066 48066 79132 48082
+rect 67925 47896 68277 47922
+rect 68749 47896 69101 47922
+rect 69573 47896 69925 47922
+rect 70397 47896 70749 47922
+rect 67951 44897 67952 47896
+rect 68251 44897 68277 47896
+rect 67951 44896 68277 44897
+rect 68775 44897 68776 47896
+rect 69075 44897 69101 47896
+rect 68775 44896 69101 44897
+rect 69599 44897 69600 47896
+rect 69899 44897 69925 47896
+rect 69599 44896 69925 44897
+rect 70423 44897 70424 47896
+rect 70723 44897 70749 47896
+rect 86297 47896 86383 47932
+rect 82929 47702 83281 47728
+rect 83753 47702 84105 47728
+rect 84577 47702 84929 47728
+rect 85401 47702 85753 47728
+rect 70423 44896 70749 44897
+rect 82955 44703 82956 47702
+rect 83255 44703 83281 47702
+rect 82955 44702 83281 44703
+rect 83779 44703 83780 47702
+rect 84079 44703 84105 47702
+rect 83779 44702 84105 44703
+rect 84603 44703 84604 47702
+rect 84903 44703 84929 47702
+rect 84603 44702 84929 44703
+rect 85427 44703 85428 47702
+rect 85727 44703 85753 47702
+rect 85427 44702 85753 44703
+rect 67295 44666 67381 44702
+rect 86297 44508 86333 47896
+rect 86347 44508 86383 47896
+rect 103445 47745 103495 48745
+rect 104295 47745 104345 48745
+rect 104597 47745 104647 48745
+rect 106247 47745 106297 48745
+rect 106549 47745 106599 48745
+rect 108199 47745 108249 48745
+rect 108501 47745 108551 48745
+rect 110151 47745 110201 48745
+rect 110453 47745 110503 48745
+rect 112103 47745 112153 48745
+rect 112405 47745 112455 48745
+rect 114055 47745 114105 48745
+rect 86927 47702 87279 47728
+rect 87751 47702 88103 47728
+rect 88575 47702 88927 47728
+rect 89399 47702 89751 47728
+rect 86953 44703 86954 47702
+rect 87253 44703 87279 47702
+rect 86953 44702 87279 44703
+rect 87777 44703 87778 47702
+rect 88077 44703 88103 47702
+rect 87777 44702 88103 44703
+rect 88601 44703 88602 47702
+rect 88901 44703 88927 47702
+rect 88601 44702 88927 44703
+rect 89425 44703 89426 47702
+rect 89725 44703 89751 47702
+rect 103445 46501 103495 47501
+rect 104295 46501 104345 47501
+rect 104597 46501 104647 47501
+rect 106247 46501 106297 47501
+rect 106549 46501 106599 47501
+rect 108199 46501 108249 47501
+rect 108501 46501 108551 47501
+rect 110151 46501 110201 47501
+rect 110453 46501 110503 47501
+rect 112103 46501 112153 47501
+rect 112405 46501 112455 47501
+rect 114055 46501 114105 47501
+rect 103445 45257 103495 46257
+rect 104295 45257 104345 46257
+rect 104597 45257 104647 46257
+rect 106247 45257 106297 46257
+rect 106549 45257 106599 46257
+rect 108199 45257 108249 46257
+rect 108501 45257 108551 46257
+rect 110151 45257 110201 46257
+rect 110453 45257 110503 46257
+rect 112103 45257 112153 46257
+rect 112405 45257 112455 46257
+rect 114055 45257 114105 46257
+rect 89425 44702 89751 44703
+rect 86297 44472 86383 44508
+use s8iom0_vdda_lvc_pad s8iom0_vdda_lvc_pad_0
+timestamp 1584383356
+transform 1 0 -868 0 1 91931
+box 0 -61 15000 39593
+use s8iom0_vdda_hvc_pad s8iom0_vdda_hvc_pad_0
+timestamp 1584383356
+transform 1 0 19686 0 1 92471
+box 0 -407 15000 39593
+use s8iom0_vccd_lvc_pad s8iom0_vccd_lvc_pad_0
+timestamp 1584383356
+transform 1 0 38106 0 1 91155
+box 0 -61 15000 39593
+use s8iom0_vccd_hvc_pad s8iom0_vccd_hvc_pad_0
+timestamp 1584383356
+transform 1 0 56526 0 1 91335
+box 0 -435 15000 39593
+use s8iom0_vddio_hvc_pad s8iom0_vddio_hvc_pad_0
+timestamp 1584383356
+transform 1 0 77078 0 1 92305
+box 0 -435 15000 39593
+use s8iom0_vddio_lvc_pad s8iom0_vddio_lvc_pad_0
+timestamp 1584383356
+transform 1 0 97048 0 1 92319
+box 0 -61 15000 39593
+use s8iom0_gpiov2_pad s8iom0_gpiov2_pad_0
+timestamp 1584383356
+transform 1 0 119295 0 1 92724
+box -143 -466 16134 39593
+use s8iom0s8_top_xres4v2 s8iom0s8_top_xres4v2_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 140197 0 1 92452
+box -103 0 15124 40000
+use s8iom0s8_top_gpio_ovtv2 s8iom0s8_top_gpio_ovtv2_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 160920 0 1 92540
+box -80 -88 28211 40076
+use s8iom0_vssd_lvc_pad s8iom0_vssd_lvc_pad_0
+timestamp 1584383356
+transform 1 0 -480 0 1 46173
+box 0 -61 15000 39593
+use s8iom0_vssd_hvc_pad s8iom0_vssd_hvc_pad_0
+timestamp 1584383356
+transform 1 0 18134 0 1 46741
+box 0 -435 15000 39593
+use s8iom0_vssa_hvc_pad s8iom0_vssa_hvc_pad_0
+timestamp 1584383356
+transform 1 0 37912 0 1 46935
+box 0 -435 15000 39593
+use s8iom0_vssa_lvc_pad s8iom0_vssa_lvc_pad_0
+timestamp 1584383356
+transform 1 0 60016 0 1 44427
+box 0 -61 15000 39593
+use s8iom0_vssio_lvc_pad s8iom0_vssio_lvc_pad_0
+timestamp 1584383356
+transform 1 0 79018 0 1 44233
+box 0 -61 15000 39593
+use s8iom0_vssio_hvc_pad s8iom0_vssio_hvc_pad_0
+timestamp 1584383356
+transform 1 0 100540 0 1 44967
+box 0 -407 15000 39593
+use s8iom0_corner_pad s8iom0_corner_pad_0
+timestamp 1584383356
+transform 1 0 123795 0 1 46420
+box -181 -114 40000 40800
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/power_pads_lib.mag b/sky130/custom/sky130_fd_io/mag/power_pads_lib.mag
new file mode 100644
index 0000000..a8876fa
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/power_pads_lib.mag
@@ -0,0 +1,65 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1585845698
+use s8iom0_vssd_lvc_pad s8iom0_vssd_lvc_pad_0
+timestamp 1585845698
+transform 1 0 1268 0 1 -42858
+box 0 -61 15000 39593
+use s8iom0_vssd_hvc_pad s8iom0_vssd_hvc_pad_0
+timestamp 1585845698
+transform 1 0 18322 0 1 -43322
+box 0 -435 15000 39593
+use s8iom0_vssa_hvc_pad s8iom0_vssa_hvc_pad_0
+timestamp 1585845698
+transform 1 0 36302 0 1 -43582
+box 0 -435 15000 39593
+use s8iom0_vssa_lvc_pad s8iom0_vssa_lvc_pad_0
+timestamp 1585845698
+transform 1 0 54022 0 1 -43956
+box 0 -61 15000 39593
+use s8iom0_vssio_lvc_pad s8iom0_vssio_lvc_pad_0
+timestamp 1585845698
+transform 1 0 71611 0 1 -43826
+box 0 -7 15000 39593
+use s8iom0_corner_pad s8iom0_corner_pad_0
+timestamp 1585845698
+transform 1 0 111407 0 1 -43193
+box -181 -114 40000 40800
+use s8iom0_vssio_hvc_pad s8iom0_vssio_hvc_pad_0
+timestamp 1585845698
+transform 1 0 89461 0 1 -43192
+box 0 -407 15000 39593
+use s8iom0s8_com_bus_slice_1um s8iom0s8_com_bus_slice_1um_0
+timestamp 1576684134
+transform 1 0 108518 0 1 -43389
+box 0 0 200 39593
+use s8iom0_vdda_lvc_pad s8iom0_vdda_lvc_pad_0
+timestamp 1585845698
+transform 1 0 1952 0 1 -313
+box 0 -61 15000 39593
+use s8iom0_vdda_hvc_pad s8iom0_vdda_hvc_pad_0
+timestamp 1585845698
+transform 1 0 20277 0 1 195
+box 0 -435 15000 39593
+use s8iom0_vccd_lvc_pad s8iom0_vccd_lvc_pad_0
+timestamp 1585845698
+transform 1 0 37605 0 1 -49
+box 0 -61 15000 39593
+use s8iom0_vddio_hvc_pad s8iom0_vddio_hvc_pad_0
+timestamp 1585845698
+transform 1 0 73415 0 1 258
+box 0 -435 15000 39593
+use s8iom0_vccd_hvc_pad s8iom0_vccd_hvc_pad_0
+timestamp 1585845698
+transform 1 0 55455 0 1 325
+box 0 -435 15000 39593
+use s8iom0_gpiov2_pad s8iom0_gpiov2_pad_0
+timestamp 1585845698
+transform 1 0 110622 0 1 590
+box -143 -466 16134 39593
+use s8iom0_vddio_lvc_pad s8iom0_vddio_lvc_pad_0
+timestamp 1585845698
+transform 1 0 91354 0 1 -208
+box 0 -7 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_corner_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_corner_pad.mag
new file mode 100644
index 0000000..8da430c
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_corner_pad.mag
@@ -0,0 +1,199 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1576765820
+<< metal4 >>
+rect 0 35957 254 40800
+rect 0 14807 254 19800
+rect 0 13617 254 14507
+rect 0 12447 254 13337
+rect 0 12081 254 12147
+rect 0 11425 100 12021
+rect 0 11129 254 11365
+rect 0 10473 116 11069
+rect 0 10347 254 10413
+rect 0 9117 254 10047
+rect 0 8147 254 8837
+rect 0 7177 254 7867
+rect 0 5967 254 6897
+rect 0 4757 254 5687
+rect 0 3787 254 4477
+rect 0 2577 254 3507
+rect 0 1207 254 2297
+rect 407 0 1497 254
+rect 1777 0 2707 254
+rect 2987 0 3677 254
+rect 3957 0 4887 254
+rect 5167 0 6097 254
+rect 6377 0 7067 254
+rect 7347 0 8037 254
+rect 8317 0 9247 254
+rect 9547 0 9613 254
+rect 9673 0 10269 115
+rect 10329 0 10565 254
+rect 10625 0 11221 100
+rect 11281 0 11347 254
+rect 11647 0 12537 254
+rect 12817 0 13707 254
+rect 14007 0 19000 254
+rect 35157 0 40000 254
+<< metal5 >>
+rect 0 35957 254 40800
+rect 0 14807 254 19797
+rect 0 13637 254 14487
+rect 0 12467 254 13317
+rect 0 10347 254 12147
+rect 0 9137 254 10027
+rect 0 8167 254 8817
+rect 0 7197 254 7847
+rect 0 5987 254 6877
+rect 0 4777 254 5667
+rect 0 3807 254 4457
+rect 0 2597 254 3487
+rect 0 1227 254 2277
+rect 427 0 1477 254
+rect 1797 0 2687 254
+rect 3007 0 3657 254
+rect 3977 0 4867 254
+rect 5187 0 6077 254
+rect 6397 0 7047 254
+rect 7367 0 8017 254
+rect 8337 0 9227 254
+rect 9547 0 11347 254
+rect 11667 0 12517 254
+rect 12837 0 13687 254
+rect 14007 0 18997 254
+rect 35157 0 40000 254
+use s8iom0s8_corner_bus_overlay s8iom0s8_corner_bus_overlay_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1576765096
+transform 1 0 0 0 1 67
+box 0 0 40000 40733
+<< labels >>
+flabel metal5 s 0 10347 254 12147 3 FreeSans 520 0 0 0 vssa
+port 2 nsew
+flabel metal5 s 127 11205 127 11205 3 FreeSans 520 180 0 0 vssa
+port 2 nsew
+flabel metal5 s 0 7197 254 7847 3 FreeSans 520 180 0 0 vswitch
+port 4 nsew
+flabel metal5 s 0 5987 254 6877 3 FreeSans 520 180 0 0 vssio
+port 9 nsew
+flabel metal5 s 0 9137 254 10027 3 FreeSans 520 180 0 0 vssd
+port 10 nsew
+flabel metal5 s 0 8168 254 8817 3 FreeSans 520 180 0 0 vssa
+port 2 nsew
+flabel metal5 s 0 12467 254 13317 3 FreeSans 520 180 0 0 vssio_q
+port 11 nsew
+flabel metal5 s 0 13637 254 14487 3 FreeSans 520 180 0 0 vddio_q
+port 5 nsew
+flabel metal5 s 0 14807 254 19797 3 FreeSans 520 180 0 0 vddio
+port 7 nsew
+flabel metal5 s 0 3807 251 4457 3 FreeSans 520 180 0 0 vdda
+port 3 nsew
+flabel metal5 s 0 1227 254 2277 3 FreeSans 520 180 0 0 vcchib
+port 6 nsew
+flabel metal5 s 0 2597 254 3487 3 FreeSans 520 180 0 0 vccd
+port 8 nsew
+flabel metal5 s 0 4777 254 5667 3 FreeSans 520 180 0 0 vddio
+port 7 nsew
+flabel metal4 s 0 11425 100 12021 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10473 115 11069 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 0 10347 254 10413 3 FreeSans 520 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 1207 254 2297 3 FreeSans 520 180 0 0 vcchib
+port 6 nsew
+flabel metal4 s 0 2577 254 3507 3 FreeSans 520 180 0 0 vccd
+port 8 nsew
+flabel metal4 s 0 3787 251 4477 3 FreeSans 520 180 0 0 vdda
+port 3 nsew
+flabel metal4 s 0 4757 254 5687 3 FreeSans 520 180 0 0 vddio
+port 7 nsew
+flabel metal4 s 0 5967 254 6897 3 FreeSans 520 180 0 0 vssio
+port 9 nsew
+flabel metal4 s 0 7177 254 7867 3 FreeSans 520 180 0 0 vswitch
+port 4 nsew
+flabel metal4 s 0 8147 254 8837 3 FreeSans 520 180 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 9117 254 10047 3 FreeSans 520 180 0 0 vssd
+port 10 nsew
+flabel metal4 s 0 11129 254 11365 3 FreeSans 520 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 12081 254 12147 3 FreeSans 520 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 12447 254 13337 3 FreeSans 520 180 0 0 vssio_q
+port 11 nsew
+flabel metal4 s 0 13617 254 14507 3 FreeSans 520 180 0 0 vddio_q
+port 5 nsew
+flabel metal4 s 0 14808 254 19800 3 FreeSans 520 180 0 0 vddio
+port 7 nsew
+flabel metal4 s 0 35957 254 40800 3 FreeSans 520 180 0 0 vssio
+port 9 nsew
+flabel metal4 s 127 38974 127 38974 3 FreeSans 520 180 0 0 vssio
+port 9 nsew
+flabel metal5 s 3977 0 4867 254 3 FreeSans 520 270 0 0 vddio
+port 7 nsew
+flabel metal5 s 1797 0 2687 254 3 FreeSans 520 270 0 0 vccd
+port 8 nsew
+flabel metal5 s 427 0 1477 254 3 FreeSans 520 270 0 0 vcchib
+port 6 nsew
+flabel metal5 s 3007 0 3657 251 3 FreeSans 520 270 0 0 vdda
+port 3 nsew
+flabel metal5 s 14007 0 18997 254 3 FreeSans 520 270 0 0 vddio
+port 7 nsew
+flabel metal5 s 12837 0 13687 254 3 FreeSans 520 270 0 0 vddio_q
+port 5 nsew
+flabel metal5 s 11667 0 12517 254 3 FreeSans 520 270 0 0 vssio_q
+port 11 nsew
+flabel metal5 s 7368 0 8017 254 3 FreeSans 520 270 0 0 vssa
+port 2 nsew
+flabel metal5 s 8337 0 9227 254 3 FreeSans 520 270 0 0 vssd
+port 10 nsew
+flabel metal5 s 5187 0 6077 254 3 FreeSans 520 270 0 0 vssio
+port 9 nsew
+flabel metal5 s 6397 0 7047 254 3 FreeSans 520 270 0 0 vswitch
+port 4 nsew
+flabel metal5 s 9547 0 11347 254 3 FreeSans 520 270 0 0 vssa
+port 2 nsew
+flabel metal5 s 10258 127 10258 127 3 FreeSans 520 90 0 0 vssa
+port 2 nsew
+flabel metal4 s 14008 0 19000 254 3 FreeSans 520 270 0 0 vddio
+port 7 nsew
+flabel metal4 s 12817 0 13707 254 3 FreeSans 520 270 0 0 vddio_q
+port 5 nsew
+flabel metal4 s 11647 0 12537 254 3 FreeSans 520 270 0 0 vssio_q
+port 11 nsew
+flabel metal4 s 11281 0 11347 254 3 FreeSans 520 90 0 0 vssa
+port 2 nsew
+flabel metal4 s 10329 0 10565 254 3 FreeSans 520 90 0 0 vssa
+port 2 nsew
+flabel metal4 s 8317 0 9247 254 3 FreeSans 520 270 0 0 vssd
+port 10 nsew
+flabel metal4 s 7347 0 8037 254 3 FreeSans 520 270 0 0 vssa
+port 2 nsew
+flabel metal4 s 6377 0 7067 254 3 FreeSans 520 270 0 0 vswitch
+port 4 nsew
+flabel metal4 s 5167 0 6097 254 3 FreeSans 520 270 0 0 vssio
+port 9 nsew
+flabel metal4 s 3957 0 4887 254 3 FreeSans 520 270 0 0 vddio
+port 7 nsew
+flabel metal4 s 2987 0 3677 251 3 FreeSans 520 270 0 0 vdda
+port 3 nsew
+flabel metal4 s 1777 0 2707 254 3 FreeSans 520 270 0 0 vccd
+port 8 nsew
+flabel metal4 s 407 0 1497 254 3 FreeSans 520 270 0 0 vcchib
+port 6 nsew
+flabel metal4 s 9547 0 9613 254 3 FreeSans 520 90 0 0 vssa
+port 2 nsew
+flabel metal4 s 10625 0 11221 100 3 FreeSans 520 90 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 9673 0 10269 115 3 FreeSans 520 90 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 35157 0 40000 254 3 FreeSans 520 270 0 0 vssio
+port 9 nsew
+flabel metal4 s 38174 127 38174 127 3 FreeSans 520 270 0 0 vssio
+port 9 nsew
+<< properties >>
+string LEFclass ENDCAP TOPRIGHT
+string FIXED_BBOX 0 0 40000 40800
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_gpiov2_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_gpiov2_pad.mag
new file mode 100644
index 0000000..1fea0c1
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_gpiov2_pad.mag
@@ -0,0 +1,286 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 12486 -407 12538 -351
+<< metal2 >>
+rect 7956 15977 8019 15991
+rect 7956 15927 7969 15977
+tri 7969 15927 8019 15977 nw
+rect 675 -407 721 -361
+rect 1084 -407 1130 -328
+rect 1226 -407 1278 -355
+rect 2551 -407 2603 -363
+rect 3262 -407 3314 -306
+rect 4471 -407 4523 -340
+rect 5320 -407 5372 -379
+rect 5698 -407 5750 -355
+rect 6150 -407 6202 -351
+rect 6363 -407 6415 -363
+rect 7092 -407 7144 -351
+rect 7678 -407 7730 -318
+rect 9049 -407 9101 -355
+rect 9971 -407 10023 -355
+rect 13367 -407 13419 -355
+rect 13655 -407 13785 -363
+rect 15256 -407 15384 -363
+rect 15522 -407 15574 -363
+rect 15741 -407 15781 -363
+rect 15943 -407 15983 -215
+<< metal3 >>
+rect 80 -407 204 -244
+rect 9173 -407 9239 -355
+rect 12564 -407 12778 -260
+rect 15716 -407 15782 -254
+rect 15848 -407 15914 -244
+<< metal4 >>
+rect 0 34750 254 39593
+rect 15746 34750 16000 39593
+rect 0 13600 254 18593
+rect 15746 13600 16000 18593
+rect 0 12410 254 13300
+rect 15746 12410 16000 13300
+rect 0 11240 254 12130
+rect 15746 11240 16000 12130
+rect 0 10874 254 10940
+rect 15746 10874 16000 10940
+rect 0 10218 100 10814
+rect 15746 10218 15846 10814
+rect 0 9922 254 10158
+rect 15746 9922 16000 10158
+rect 0 9266 116 9862
+rect 15746 9266 15862 9862
+rect 0 9140 254 9206
+rect 15746 9140 16000 9206
+rect 0 7910 254 8840
+rect 15746 7910 16000 8840
+rect 0 6940 254 7630
+rect 15746 6940 16000 7630
+rect 0 5970 254 6660
+rect 15746 5970 16000 6660
+rect 0 4760 254 5690
+rect 15746 4760 16000 5690
+rect 0 3550 254 4480
+rect 15746 3550 16000 4480
+rect 0 2580 254 3270
+rect 15746 2580 16000 3270
+rect 0 1370 254 2300
+rect 15746 1370 16000 2300
+rect 0 0 254 1090
+rect 15746 0 16000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 15746 34750 16000 39593
+rect 6423 24687 10731 28996
+rect 0 13600 254 18590
+rect 15746 13600 16000 18590
+rect 0 12430 254 13280
+rect 15746 12430 16000 13280
+rect 0 11260 254 12110
+rect 15746 11260 16000 12110
+rect 0 9140 254 10940
+rect 15746 9140 16000 10940
+rect 0 7930 254 8820
+rect 15746 7930 16000 8820
+rect 0 6960 254 7610
+rect 15746 6960 16000 7610
+rect 0 5990 254 6640
+rect 15746 5990 16000 6640
+rect 0 4780 254 5670
+rect 15746 4780 16000 5670
+rect 0 3570 254 4460
+rect 15746 3570 16000 4460
+rect 0 2600 254 3250
+rect 15746 2600 16000 3250
+rect 0 1390 254 2280
+rect 15746 1390 16000 2280
+rect 0 20 254 1070
+rect 15746 20 16000 1070
+use s8iom0s8_overlay_gpiov2 s8iom0s8_overlay_gpiov2_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 407 16000 40000
+use s8iom0s8_top_gpiov2 s8iom0s8_top_gpiov2_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box -143 -7 16134 40000
+<< labels >>
+flabel metal4 s 127 37925 127 37925 3 FreeSans 520 0 0 0 vssio
+port 35 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 31 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 34 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 36 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 37 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 35 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 30 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 31 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 28 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 32 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 29 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 35 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 31 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 32 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 31 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 28 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 37 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 36 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 35 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 30 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 33 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 34 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 29 nsew
+flabel metal4 s 15873 37925 15873 37925 3 FreeSans 520 180 0 0 vssio
+port 35 nsew
+flabel metal5 s 15746 9140 16000 10940 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal5 s 15807 2600 16000 3250 3 FreeSans 520 180 0 0 vdda
+port 30 nsew
+flabel metal5 s 15746 7930 16000 8820 3 FreeSans 520 180 0 0 vssd
+port 34 nsew
+flabel metal5 s 15746 11260 16000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 36 nsew
+flabel metal5 s 15746 4780 16000 5670 3 FreeSans 520 180 0 0 vssio
+port 35 nsew
+flabel metal5 s 15746 5990 16000 6640 3 FreeSans 520 180 0 0 vswitch
+port 37 nsew
+flabel metal5 s 15746 6961 16000 7610 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal5 s 15746 1390 16000 2280 3 FreeSans 520 180 0 0 vccd
+port 28 nsew
+flabel metal5 s 15746 12430 16000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 32 nsew
+flabel metal5 s 15746 13600 16000 18590 3 FreeSans 520 180 0 0 vddio
+port 31 nsew
+flabel metal5 s 15746 20 16000 1070 3 FreeSans 520 180 0 0 vcchib
+port 29 nsew
+flabel metal5 s 15746 3570 16000 4460 3 FreeSans 520 180 0 0 vddio
+port 31 nsew
+flabel metal4 s 15746 7910 16000 8840 3 FreeSans 520 180 0 0 vssd
+port 34 nsew
+flabel metal4 s 15807 2580 16000 3270 3 FreeSans 520 180 0 0 vdda
+port 30 nsew
+flabel metal4 s 15746 11240 16000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 36 nsew
+flabel metal4 s 15746 4760 16000 5690 3 FreeSans 520 180 0 0 vssio
+port 35 nsew
+flabel metal4 s 15746 5970 16000 6660 3 FreeSans 520 180 0 0 vswitch
+port 37 nsew
+flabel metal4 s 15746 9922 16000 10158 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal4 s 15746 10874 16000 10940 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal4 s 15746 3550 16000 4480 3 FreeSans 520 180 0 0 vddio
+port 31 nsew
+flabel metal4 s 15746 9140 16000 9206 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal4 s 15746 6940 16000 7630 3 FreeSans 520 180 0 0 vssa
+port 33 nsew
+flabel metal4 s 15746 12410 16000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 32 nsew
+flabel metal4 s 15746 1370 16000 2300 3 FreeSans 520 180 0 0 vccd
+port 28 nsew
+flabel metal4 s 15746 9266 16000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 15746 34750 16000 39593 3 FreeSans 520 180 0 0 vssio
+port 35 nsew
+flabel metal4 s 15746 10218 16000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 15746 13600 16000 18593 3 FreeSans 520 180 0 0 vddio
+port 31 nsew
+flabel metal4 s 15746 0 16000 1090 3 FreeSans 520 180 0 0 vcchib
+port 29 nsew
+flabel metal5 s 6423 24687 10731 28996 0 FreeSans 1600 0 0 0 pad
+port 21 nsew
+flabel metal3 s 80 -407 204 -244 0 FreeSans 640 0 0 0 in_h
+port 17 nsew
+flabel metal2 s 675 -407 721 -361 0 FreeSans 400 270 0 0 oe_n
+port 19 nsew
+flabel metal2 s 1084 -407 1130 -328 0 FreeSans 400 270 0 0 ib_mode_sel
+port 15 nsew
+flabel metal2 s 1226 -407 1278 -355 0 FreeSans 400 270 0 0 vtrip_sel
+port 38 nsew
+flabel metal2 s 2551 -407 2603 -363 0 FreeSans 400 270 0 0 enable_vdda_h
+port 10 nsew
+flabel metal2 s 3262 -407 3314 -306 0 FreeSans 400 270 0 0 enable_vswitch_h
+port 12 nsew
+flabel metal2 s 4471 -407 4523 -340 0 FreeSans 400 0 0 0 out
+port 20 nsew
+flabel metal2 s 5320 -407 5372 -379 0 FreeSans 400 270 0 0 hld_ovr
+port 14 nsew
+flabel metal2 s 5698 -407 5750 -355 0 FreeSans 400 270 0 0 dm<2>
+port 5 nsew
+flabel metal2 s 6150 -407 6202 -351 0 FreeSans 400 270 0 0 analog_sel
+port 4 nsew
+flabel metal2 s 6363 -407 6415 -363 0 FreeSans 400 270 0 0 hld_h_n
+port 13 nsew
+flabel metal2 s 7092 -407 7144 -351 0 FreeSans 400 270 0 0 enable_h
+port 8 nsew
+flabel metal2 s 7678 -407 7730 -318 0 FreeSans 400 270 0 0 enable_inp_h
+port 9 nsew
+flabel metal2 s 9049 -407 9101 -355 0 FreeSans 400 270 0 0 inp_dis
+port 18 nsew
+flabel metal3 s 9173 -407 9239 -355 0 FreeSans 400 270 0 0 analog_pol
+port 3 nsew
+flabel metal2 s 9971 -407 10023 -355 0 FreeSans 400 270 0 0 dm<0>
+port 7 nsew
+flabel metal1 s 12486 -407 12538 -351 0 FreeSans 400 270 0 0 analog_en
+port 2 nsew
+flabel metal2 s 13367 -407 13419 -355 0 FreeSans 400 270 0 0 dm<1>
+port 6 nsew
+flabel metal2 s 15522 -407 15574 -363 0 FreeSans 400 270 0 0 slow
+port 25 nsew
+flabel metal3 s 15848 -407 15914 -244 0 FreeSans 400 270 0 0 in
+port 16 nsew
+flabel metal3 s 12564 -407 12778 -260 0 FreeSans 400 270 0 0 pad_a_noesd_h
+port 24 nsew
+flabel metal2 s 13655 -407 13785 -363 0 FreeSans 400 270 0 0 pad_a_esd_1_h
+port 23 nsew
+flabel metal2 s 15256 -407 15384 -363 0 FreeSans 400 270 0 0 pad_a_esd_0_h
+port 22 nsew
+flabel metal2 s 15943 -407 15983 -215 0 FreeSans 400 270 0 0 tie_lo_esd
+port 27 nsew
+flabel metal2 s 15741 -407 15781 -363 0 FreeSans 400 270 0 0 tie_hi_esd
+port 26 nsew
+flabel metal3 s 15716 -407 15782 -254 0 FreeSans 400 270 0 0 enable_vddio
+port 11 nsew
+<< properties >>
+string LEFclass PAD INOUT
+string FIXED_BBOX 0 0 16000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_hvc_pad.mag
new file mode 100644
index 0000000..1e654d6
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_hvc_pad.mag
@@ -0,0 +1,223 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1585845698
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -193
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vccd_hvc s8iom0s8_overlay_vccd_hvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1585749841
+transform 1 0 0 0 1 -407
+box 0 407 15000 40000
+use s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_wpad_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1585749839
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vccd
+port 11 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vccd
+port 11 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_lvc_pad.mag
new file mode 100644
index 0000000..c3127e9
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vccd_lvc_pad.mag
@@ -0,0 +1,230 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 69
+<< metal2 >>
+rect 98 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 98 0 4900 862
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 6339 32546 10468 33417
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vccd_lvc s8iom0s8_overlay_vccd_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_wpad_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal4 s 14873 37925 14873 37925 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 127 37925 127 37925 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vccd
+port 15 nsew
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vccd
+port 15 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vccd
+port 15 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_hvc_pad.mag
new file mode 100644
index 0000000..b81c352
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_hvc_pad.mag
@@ -0,0 +1,227 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -211
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vccd_lvc s8iom0s8_overlay_vccd_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_wpad_1 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal4 s 14873 37925 14873 37925 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 127 37925 127 37925 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vdda
+port 6 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vdda
+port 6 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_lvc_pad.mag
new file mode 100644
index 0000000..6cd80a1
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vdda_lvc_pad.mag
@@ -0,0 +1,226 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 61
+<< metal2 >>
+rect 98 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 98 0 4900 862
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 6339 32546 10467 33417
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vdda_lvc s8iom0s8_overlay_vdda_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_wpad_1 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vdda
+port 10 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vdda
+port 10 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vdda
+port 10 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_hvc_pad.mag
new file mode 100644
index 0000000..2f50667
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_hvc_pad.mag
@@ -0,0 +1,223 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1585845698
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -210
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vddio_hvc s8iom0s8_overlay_vddio_hvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1585749841
+transform 1 0 0 0 1 -407
+box 0 407 15000 40000
+use s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_wpad_2 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1585749839
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vddio
+port 10 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vddio
+port 10 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_lvc_pad.mag
new file mode 100644
index 0000000..d2e943c
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vddio_lvc_pad.mag
@@ -0,0 +1,225 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 78
+<< metal2 >>
+rect 98 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 98 0 4900 862
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vddio_lvc s8iom0s8_overlay_vddio_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_wpad_2 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vddio
+port 14 nsew
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vddio
+port 14 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vddio
+port 14 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD POWER
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_hvc_pad.mag
new file mode 100644
index 0000000..dc6ca8d
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_hvc_pad.mag
@@ -0,0 +1,225 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -184
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 6 15000 1090
+rect 14746 0 14928 6
+rect 14939 3 15000 6
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssa_hvc s8iom0s8_overlay_vssa_hvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 407 15000 40000
+use s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_wpad_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 15 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vssa
+port 5 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vssa
+port 5 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_lvc_pad.mag
new file mode 100644
index 0000000..c832fc1
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssa_lvc_pad.mag
@@ -0,0 +1,227 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 84
+<< metal2 >>
+rect 100 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 98 309 4900 862
+rect 100 0 4900 309
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 6339 32546 10468 33417
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssa_lvc s8iom0s8_overlay_vssa_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_wpad_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vssa
+port 9 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vssa
+port 9 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vssa
+port 9 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_hvc_pad.mag
new file mode 100644
index 0000000..108c5f7
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_hvc_pad.mag
@@ -0,0 +1,223 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -182
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssd_hvc s8iom0s8_overlay_vssd_hvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 407 15000 40000
+use s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_wpad_1 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vssd
+port 13 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vssd
+port 13 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_lvc_pad.mag
new file mode 100644
index 0000000..7781fa8
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssd_lvc_pad.mag
@@ -0,0 +1,230 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 83
+<< metal2 >>
+rect 101 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 101 0 4900 862
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 6339 32546 10468 33417
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssd_lvc s8iom0s8_overlay_vssd_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_wpad_1 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal4 s 14873 37925 14873 37925 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 127 37925 127 37925 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vssd
+port 17 nsew
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vssd
+port 17 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_hvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_hvc_pad.mag
new file mode 100644
index 0000000..db38a6c
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_hvc_pad.mag
@@ -0,0 +1,226 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal2 >>
+rect 99 -407 4879 -259
+rect 5179 -407 5579 -181
+rect 10078 -407 14858 -259
+<< metal3 >>
+rect 99 -407 4879 -16
+rect 5179 -407 7379 -259
+rect 7578 -407 9778 -89
+rect 10078 -407 14858 -16
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 6 254 1090
+rect 14746 6 15000 1090
+rect 14934 5 15000 6
+rect 0 0 254 5
+rect 14746 0 15000 5
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 7329 27458 7594 28780
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssio_hvc s8iom0s8_overlay_vssio_hvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 407 15000 40000
+use s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_wpad_2 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -407
+box 0 0 15000 40000
+<< labels >>
+flabel metal5 s 7329 27458 7594 28780 0 FreeSans 2000 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 127 37914 127 37914 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 14873 37914 14873 37914 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal2 s 10078 -407 14858 -259 2 FreeSans 2000 90 0 0 drn_hvc
+port 2 nsew
+flabel metal2 s 99 -407 4879 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal3 s 7578 -407 9778 -89 0 FreeSans 2000 0 0 0 drn_hvc
+port 2 nsew
+flabel metal3 s 99 -407 4879 -16 0 FreeSans 2000 0 0 0 vssio
+port 12 nsew
+flabel metal3 s 10078 -407 14858 -16 0 FreeSans 2000 0 0 0 vssio
+port 12 nsew
+flabel metal3 s 5179 -407 7379 -259 2 FreeSans 2000 90 0 0 src_bdy_hvc
+port 4 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 13 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 6 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 7 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 9 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 5 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 11 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 12 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 8 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 10 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 11 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 7 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 9 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 14 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 12 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 6 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 5 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 13 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_lvc_pad.mag b/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_lvc_pad.mag
new file mode 100644
index 0000000..b467e36
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0_vssio_lvc_pad.mag
@@ -0,0 +1,227 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1584473789
+<< metal1 >>
+rect 6867 95 7067 195
+rect 5242 -7 5540 74
+<< metal2 >>
+rect 100 0 4099 287
+rect 6888 -7 8888 58
+rect 10953 -7 14940 715
+<< metal3 >>
+rect 98 339 4900 862
+rect 100 0 4900 339
+rect 5200 -7 7374 918
+rect 7676 -7 9850 918
+rect 10151 -7 14940 862
+<< metal4 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 0 13600 254 18593
+rect 14746 13600 15000 18593
+rect 0 12410 254 13300
+rect 14746 12410 15000 13300
+rect 0 11240 254 12130
+rect 14746 11240 15000 12130
+rect 0 10874 254 10940
+rect 14746 10874 15000 10940
+rect 0 10218 100 10814
+rect 14746 10218 14846 10814
+rect 0 9922 254 10158
+rect 14746 9922 15000 10158
+rect 0 9266 116 9862
+rect 14746 9266 14862 9862
+rect 0 9140 254 9206
+rect 14746 9140 15000 9206
+rect 0 7910 254 8840
+rect 14746 7910 15000 8840
+rect 0 6940 254 7630
+rect 14746 6940 15000 7630
+rect 0 5970 254 6660
+rect 14746 5970 15000 6660
+rect 0 4760 254 5690
+rect 14746 4760 15000 5690
+rect 0 3550 254 4480
+rect 14746 3550 15000 4480
+rect 0 2580 254 3270
+rect 14746 2580 15000 3270
+rect 0 1370 254 2300
+rect 14746 1370 15000 2300
+rect 0 0 254 1090
+rect 14746 0 15000 1090
+<< metal5 >>
+rect 0 34750 254 39593
+rect 14746 34750 15000 39593
+rect 6339 32546 10468 33417
+rect 0 13600 254 18590
+rect 14746 13600 15000 18590
+rect 0 12430 254 13280
+rect 14746 12430 15000 13280
+rect 0 11260 254 12110
+rect 14746 11260 15000 12110
+rect 0 9140 254 10940
+rect 14746 9140 15000 10940
+rect 0 7930 254 8820
+rect 14746 7930 15000 8820
+rect 0 6960 254 7610
+rect 14746 6960 15000 7610
+rect 0 5990 254 6640
+rect 14746 5990 15000 6640
+rect 0 4780 254 5670
+rect 14746 4780 15000 5670
+rect 0 3570 254 4460
+rect 14746 3570 15000 4460
+rect 0 2600 254 3250
+rect 14746 2600 15000 3250
+rect 0 1390 254 2280
+rect 14746 1390 15000 2280
+rect 0 20 254 1070
+rect 14746 20 15000 1070
+use s8iom0s8_overlay_vssio_lvc s8iom0s8_overlay_vssio_lvc_0 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 7 15000 39600
+use s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_wpad_2 ~/projects/efabless/tech/SW/EFS8A/libs.ref/s8iom0s8/mag
+timestamp 1584046481
+transform 1 0 0 0 1 -7
+box 0 0 15000 39600
+<< labels >>
+flabel metal5 s 6339 32546 10468 33417 0 FreeSans 2000 0 0 0 vssio
+port 16 nsew
+flabel metal2 s 100 -7 4099 287 0 FreeSans 2000 0 0 0 src_bdy_lvc1
+port 4 nsew
+flabel metal2 s 10953 -7 14940 715 0 FreeSans 2000 0 0 0 src_bdy_lvc2
+port 5 nsew
+flabel metal2 s 6888 -7 8888 58 0 FreeSans 400 0 0 0 bdy2_b2b
+port 6 nsew
+flabel metal3 s 7676 -7 9850 918 0 FreeSans 2000 0 0 0 drn_lvc2
+port 3 nsew
+flabel metal3 s 5200 -7 7374 918 0 FreeSans 2000 0 0 0 drn_lvc1
+port 2 nsew
+flabel metal3 s 10151 -7 14940 862 0 FreeSans 4000 0 0 0 vssio
+port 16 nsew
+flabel metal3 s 100 -7 4900 862 0 FreeSans 2000 0 0 0 vssio
+port 16 nsew
+flabel metal1 s 6867 95 7067 195 0 FreeSans 300 0 0 0 vssi
+port 7 nsew
+flabel metal5 s 14746 9140 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14807 2600 15000 3250 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal5 s 14746 7930 15000 8820 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal5 s 14746 11260 15000 12110 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 14746 4780 15000 5670 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal5 s 14746 5990 15000 6640 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal5 s 14746 6961 15000 7610 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal5 s 14746 1390 15000 2280 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal5 s 14746 12430 15000 13280 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 14746 13600 15000 18590 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 14746 20 15000 1070 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal5 s 14746 3570 15000 4460 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 13600 254 18590 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 7930 254 8820 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal5 s 0 11260 254 12110 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal5 s 0 5990 254 6640 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal5 s 0 4780 254 5670 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal5 s 0 2600 193 3250 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal5 s 0 3570 254 4460 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal5 s 0 1390 254 2280 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal5 s 0 12430 254 13280 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal5 s 0 9140 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 6961 254 7610 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal5 s 0 20 254 1070 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 7910 15000 8840 3 FreeSans 520 180 0 0 vssd
+port 17 nsew
+flabel metal4 s 14807 2580 15000 3270 3 FreeSans 520 180 0 0 vdda
+port 10 nsew
+flabel metal4 s 14746 11240 15000 12130 3 FreeSans 520 180 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 14746 4760 15000 5690 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 5970 15000 6660 3 FreeSans 520 180 0 0 vswitch
+port 11 nsew
+flabel metal4 s 14746 9922 15000 10158 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 10874 15000 10940 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 0 15000 1090 3 FreeSans 520 180 0 0 vcchib
+port 13 nsew
+flabel metal4 s 14746 3550 15000 4480 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 14746 9140 15000 9206 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 6940 15000 7630 3 FreeSans 520 180 0 0 vssa
+port 9 nsew
+flabel metal4 s 14746 12410 15000 13300 3 FreeSans 520 180 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 14746 1370 15000 2300 3 FreeSans 520 180 0 0 vccd
+port 15 nsew
+flabel metal4 s 14746 9266 15000 9862 3 FreeSans 520 180 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 14746 34750 15000 39593 3 FreeSans 520 180 0 0 vssio
+port 16 nsew
+flabel metal4 s 14746 10218 15000 10814 3 FreeSans 520 180 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 14746 13600 15000 18593 3 FreeSans 520 180 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 34750 254 39593 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 3550 254 4480 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 12410 254 13300 3 FreeSans 520 0 0 0 vddio_q
+port 12 nsew
+flabel metal4 s 0 13600 254 18593 3 FreeSans 520 0 0 0 vddio
+port 14 nsew
+flabel metal4 s 0 1370 254 2300 3 FreeSans 520 0 0 0 vccd
+port 15 nsew
+flabel metal4 s 0 9140 254 9206 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 5970 254 6660 3 FreeSans 520 0 0 0 vswitch
+port 11 nsew
+flabel metal4 s 0 0 254 1090 3 FreeSans 520 0 0 0 vcchib
+port 13 nsew
+flabel metal4 s 0 9922 254 10158 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 11240 254 12130 3 FreeSans 520 0 0 0 vssio_q
+port 18 nsew
+flabel metal4 s 0 4760 254 5690 3 FreeSans 520 0 0 0 vssio
+port 16 nsew
+flabel metal4 s 0 2580 193 3270 3 FreeSans 520 0 0 0 vdda
+port 10 nsew
+flabel metal4 s 0 10218 254 10814 3 FreeSans 520 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 10874 254 10940 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 6940 254 7630 3 FreeSans 520 0 0 0 vssa
+port 9 nsew
+flabel metal4 s 0 7910 254 8840 3 FreeSans 520 0 0 0 vssd
+port 17 nsew
+flabel metal4 s 0 9266 254 9862 3 FreeSans 520 0 0 0 amuxbus_b
+port 1 nsew
+<< properties >>
+string LEFclass PAD GROUND
+string FIXED_BBOX 0 0 15000 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/mag/s8iom0s8_com_bus_slice_1um.mag b/sky130/custom/sky130_fd_io/mag/s8iom0s8_com_bus_slice_1um.mag
new file mode 100644
index 0000000..2349822
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/mag/s8iom0s8_com_bus_slice_1um.mag
@@ -0,0 +1,99 @@
+magic
+tech EFS8A
+magscale 1 2
+timestamp 1586352185
+<< metal4 >>
+rect 0 34750 200 39593
+rect 0 13600 200 18593
+rect 0 12410 200 13300
+rect 0 11240 200 12130
+rect 0 10874 200 10940
+rect 0 10218 200 10814
+rect 0 9922 200 10158
+rect 0 9266 200 9862
+rect 0 9140 200 9206
+rect 0 7910 200 8840
+rect 0 6940 200 7630
+rect 0 5970 200 6660
+rect 0 4760 200 5690
+rect 0 3550 200 4480
+rect 0 2580 200 3270
+rect 0 1370 200 2300
+rect 0 0 200 1090
+<< metal5 >>
+rect 0 34750 200 39593
+rect 0 13600 200 18590
+rect 0 12430 200 13280
+rect 0 11260 200 12110
+rect 0 9140 200 10940
+rect 0 7930 200 8820
+rect 0 6960 200 7610
+rect 0 5990 200 6640
+rect 0 4780 200 5670
+rect 0 3570 200 4460
+rect 0 2600 200 3250
+rect 0 1390 200 2280
+rect 0 20 200 1070
+<< labels >>
+flabel metal4 s 0 13600 200 18593 0 FreeSans 640 0 0 0 vddio
+port 7 nsew
+flabel metal5 s 0 12430 200 13280 0 FreeSans 640 0 0 0 vddio_q
+port 5 nsew
+flabel metal4 s 0 12410 200 13300 0 FreeSans 640 0 0 0 vddio_q
+port 5 nsew
+flabel metal5 s 0 11260 200 12110 0 FreeSans 640 0 0 0 vssio_q
+port 11 nsew
+flabel metal4 s 0 11240 200 12130 0 FreeSans 640 0 0 0 vssio_q
+port 11 nsew
+flabel metal5 s 0 9140 200 10940 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 10874 200 10940 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 10218 200 10814 0 FreeSans 640 0 0 0 amuxbus_a
+port 0 nsew
+flabel metal4 s 0 9266 200 9862 0 FreeSans 640 0 0 0 amuxbus_b
+port 1 nsew
+flabel metal4 s 0 9140 200 9206 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+flabel metal5 s 0 7930 200 8820 0 FreeSans 640 0 0 0 vssd
+port 10 nsew
+flabel metal4 s 0 7910 200 8840 0 FreeSans 640 0 0 0 vssd
+port 10 nsew
+flabel metal5 s 0 6960 200 7610 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+flabel metal4 s 0 6940 200 7630 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+flabel metal5 s 0 5990 200 6640 0 FreeSans 640 0 0 0 vswitch
+port 4 nsew
+flabel metal4 s 0 5970 200 6660 0 FreeSans 640 0 0 0 vswitch
+port 4 nsew
+flabel metal5 s 0 4780 200 5670 0 FreeSans 640 0 0 0 vssio
+port 9 nsew
+flabel metal4 s 0 4760 200 5690 0 FreeSans 640 0 0 0 vssio
+port 9 nsew
+flabel metal5 s 0 3570 200 4460 0 FreeSans 640 0 0 0 vddio
+port 7 nsew
+flabel metal4 s 0 3550 200 4480 0 FreeSans 640 0 0 0 vddio
+port 7 nsew
+flabel metal5 s 0 2600 200 3250 0 FreeSans 640 0 0 0 vdda
+port 3 nsew
+flabel metal4 s 0 2580 200 3270 0 FreeSans 640 0 0 0 vdda
+port 3 nsew
+flabel metal5 s 0 1390 200 2280 0 FreeSans 640 0 0 0 vccd
+port 8 nsew
+flabel metal4 s 0 1370 200 2300 0 FreeSans 640 0 0 0 vccd
+port 8 nsew
+flabel metal5 s 0 20 200 1070 0 FreeSans 640 0 0 0 vcchib
+port 6 nsew
+flabel metal4 s 0 0 200 1090 0 FreeSans 640 0 0 0 vcchib
+port 6 nsew
+flabel metal5 s 0 34750 200 39593 0 FreeSans 640 0 0 0 vssio
+port 9 nsew
+flabel metal5 s 0 13600 200 18590 0 FreeSans 640 0 0 0 vddio
+port 7 nsew
+flabel metal4 s 0 9922 200 10158 0 FreeSans 640 0 0 0 vssa
+port 2 nsew
+<< properties >>
+string LEFclass PAD SPACER
+string FIXED_BBOX 0 0 200 39593
+<< end >>
diff --git a/sky130/custom/sky130_fd_io/verilog/power_pads_lib.v b/sky130/custom/sky130_fd_io/verilog/power_pads_lib.v
new file mode 100644
index 0000000..f12b529
--- /dev/null
+++ b/sky130/custom/sky130_fd_io/verilog/power_pads_lib.v
@@ -0,0 +1,714 @@
+//-----------------------------------------------------------------------
+// Verilog entries for standard power pads (s8 power pads + overlays)
+// Also includes stub entries for the corner and fill cells
+// Also includes the custom gpiov2 cell (adds m5 on buses), which is a wrapper
+// for the s8 gpiov2 cell.
+//
+// This file is distributed as open source under the Apache 2.0 license
+// Copyright 2019 efabless, Inc.
+// Written by Tim Edwards
+//-----------------------------------------------------------------------
+
+module s8iom0_vccd_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc, vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad to vccd)
+ s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vccd),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+endmodule
+
+module s8iom0_vccd_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad to vccd)
+ s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vccd),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+endmodule
+
+module s8iom0_vdda_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad to vdda)
+ s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vdda),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+endmodule
+
+module s8iom0_vdda_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc,vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad to vdda)
+ s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vdda),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+endmodule
+
+module s8iom0_vddio_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad and vddio_q to vddio)
+ s8iom0s8_top_power_lvc_wpad s8iom0s8_top_power_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vddio),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+ assign vddio_q = vddio;
+
+endmodule
+
+module s8iom0_vddio_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc,vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying power pad (connects p_pad and vddio_q to vddio)
+ s8iom0s8_top_power_hvc_wpad s8iom0s8_top_power_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .p_pad(vddio),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+ assign vddio_q = vddio;
+
+endmodule
+
+module s8iom0_vssd_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad to vssd)
+ s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssd),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+endmodule
+
+module s8iom0_vssd_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc, vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad to vssd)
+ s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssd),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+endmodule
+
+module s8iom0_vssio_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad and vssio_q to vssio)
+ s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssio),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+ assign vssio_q = vssio;
+
+endmodule
+
+
+module s8iom0_vssio_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc,vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad and vssio_q to vssio)
+ s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssio),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+ assign vssio_q = vssio;
+
+endmodule
+
+module s8iom0_vssa_lvc_pad (amuxbus_a, amuxbus_b,
+ drn_lvc1, drn_lvc2, src_bdy_lvc1, src_bdy_lvc2, bdy2_b2b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_lvc1;
+ inout drn_lvc2;
+ inout src_bdy_lvc1;
+ inout src_bdy_lvc2;
+ inout bdy2_b2b;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad to vssa)
+ s8iom0s8_top_ground_lvc_wpad s8iom0s8_top_ground_lvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssa),
+ .ogc_lvc(),
+ .bdy2_b2b(bdy2_b2b),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_lvc1(drn_lvc1),
+ .drn_lvc2(drn_lvc2),
+ .src_bdy_lvc1(src_bdy_lvc1),
+ .src_bdy_lvc2(src_bdy_lvc2)
+ );
+
+endmodule
+
+module s8iom0_vssa_hvc_pad (amuxbus_a, amuxbus_b, drn_hvc,
+ src_bdy_hvc,vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout drn_hvc;
+ inout src_bdy_hvc;
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+ // Instantiate the underlying ground pad (connects g_pad to vssa)
+ s8iom0s8_top_ground_hvc_wpad s8iom0s8_top_ground_hvc_base (
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q),
+ .g_pad(vssa),
+ .ogc_hvc(),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b),
+ .drn_hvc(drn_hvc),
+ .src_bdy_hvc(src_bdy_hvc)
+ );
+
+endmodule
+
+module s8iom0_corner_pad (amuxbus_a, amuxbus_b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+endmodule
+
+module s8iom0s8_com_bus_slice (amuxbus_a, amuxbus_b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+endmodule
+
+module s8iom0s8_com_bus_slice_1um (amuxbus_a, amuxbus_b,
+ vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+);
+ inout amuxbus_a;
+ inout amuxbus_b;
+
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+endmodule
+
+module s8iom0_gpiov2_pad (in_h, pad_a_noesd_h, pad_a_esd_0_h, pad_a_esd_1_h,
+ pad, dm, hld_h_n, in, inp_dis, ib_mode_sel, enable_h, enable_vdda_h,
+ enable_inp_h, oe_n, tie_hi_esd, tie_lo_esd, slow, vtrip_sel, hld_ovr,
+ analog_en, analog_sel, enable_vddio, enable_vswitch_h, analog_pol, out,
+ amuxbus_a, amuxbus_b,vssa, vdda, vswitch, vddio_q, vcchib, vddio, vccd,
+ vssio, vssd, vssio_q
+ );
+
+input out;
+input oe_n;
+input hld_h_n;
+input enable_h;
+input enable_inp_h;
+input enable_vdda_h;
+input enable_vswitch_h;
+input enable_vddio;
+input inp_dis;
+input ib_mode_sel;
+input vtrip_sel;
+input slow;
+input hld_ovr;
+input analog_en;
+input analog_sel;
+input analog_pol;
+input [2:0] dm;
+
+ inout vddio;
+ inout vddio_q;
+ inout vdda;
+ inout vccd;
+ inout vswitch;
+ inout vcchib;
+ inout vssa;
+ inout vssd;
+ inout vssio_q;
+ inout vssio;
+
+inout pad;
+inout pad_a_noesd_h,pad_a_esd_0_h,pad_a_esd_1_h;
+inout amuxbus_a;
+inout amuxbus_b;
+
+output in;
+output in_h;
+output tie_hi_esd, tie_lo_esd;
+
+// Instantiate original version with metal4-only power bus
+s8iom0s8_top_gpiov2 gpiov2_base (
+ .in_h(in_h),
+ .pad_a_noesd_h(pad_a_noesd_h),
+ .pad_a_esd_0_h(pad_a_esd_0_h),
+ .pad_a_esd_1_h(pad_a_esd_1_h),
+ .pad(pad),
+ .dm(dm),
+ .hld_h_n(hld_h_n),
+ .in(in),
+ .inp_dis(inp_dis),
+ .ib_mode_sel(ib_mode_sel),
+ .enable_h(enable_h),
+ .enable_vdda_h(enable_vdda_h),
+ .enable_inp_h(enable_inp_h),
+ .oe_n(oe_n),
+ .tie_hi_esd(tie_hi_esd),
+ .tie_lo_esd(tie_lo_esd),
+ .slow(slow),
+ .vtrip_sel(vtrip_sel),
+ .hld_ovr(hld_ovr),
+ .analog_en(analog_en),
+ .analog_sel(analog_sel),
+ .enable_vddio(enable_vddio),
+ .enable_vswitch_h(enable_vswitch_h),
+ .analog_pol(analog_pol),
+ .out(out),
+ .amuxbus_a(amuxbus_a),
+ .amuxbus_b(amuxbus_b) ,
+ .vssa(vssa),
+ .vdda(vdda),
+ .vswitch(vswitch),
+ .vddio_q(vddio_q),
+ .vcchib(vcchib),
+ .vddio(vddio),
+ .vccd(vccd),
+ .vssio(vssio),
+ .vssd(vssd),
+ .vssio_q(vssio_q)
+);
+
+endmodule
diff --git a/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_1.cdl b/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_1.cdl
new file mode 100644
index 0000000..2ae2f88
--- /dev/null
+++ b/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_1.cdl
@@ -0,0 +1,7 @@
+* Additional subcircuits not in the vendor CDL library
+
+.SUBCKT scs8hd_diode_1 DIODE vgnd vnb vpb vpwr
+*.PININFO DIODE:I vgnd:I vnb:I vpb:I vpwr:I
+* NOTE: Tap diode is not represented here.
+.ENDS
+
diff --git a/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_2.cdl b/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_2.cdl
new file mode 100644
index 0000000..2abb8b4
--- /dev/null
+++ b/sky130/custom/sky130_fd_sc_hd/scs8hd_diode_2.cdl
@@ -0,0 +1,6 @@
+* Additional subcircuits not in the vendor CDL library
+
+.SUBCKT scs8hd_diode_2 DIODE vgnd vnb vpb vpwr
+*.PININFO DIODE:I vgnd:I vnb:I vpb:I vpwr:I
+* NOTE: Tap diode is not represented here.
+.ENDS
diff --git a/sky130/custom/techLEF/sky130_fd_sc_hd_tech.lef b/sky130/custom/techLEF/sky130_fd_sc_hd_tech.lef
new file mode 100644
index 0000000..d5e0b31
--- /dev/null
+++ b/sky130/custom/techLEF/sky130_fd_sc_hd_tech.lef
@@ -0,0 +1,746 @@
+VERSION 5.7 ;
+BUSBITCHARS "[]" ;
+DIVIDERCHAR "/" ;
+UNITS
+ TIME NANOSECONDS 1 ;
+ CAPACITANCE PICOFARADS 1 ;
+ RESISTANCE OHMS 1 ;
+ DATABASE MICRONS 1000 ;
+END UNITS
+MANUFACTURINGGRID 0.005 ;
+
+SITE unithd
+ SYMMETRY Y ;
+ CLASS CORE ;
+ SIZE 0.460 BY 2.720 ;
+END unithd
+
+LAYER li1
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+
+ PITCH 0.46 0.34 ;
+ OFFSET 0.23 0.17 ;
+
+ WIDTH 0.170 ; # LI 1
+ # SPACING 0.170 ; # LI 2
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 0.170000 ;
+ AREA 0.0561 ; # LI 6
+ THICKNESS 0.10 ;
+
+ RESISTANCE RPERSQ 12.2 ;
+
+ ANTENNAMODEL OXIDE1 ;
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.0 75.0 ) ( 0.0125 75.0 ) ( 0.0225 85.125 ) ( 22.5 10200.0 ) ) ;
+
+
+END li1
+
+LAYER mcon
+ TYPE CUT ;
+ WIDTH 0.17 ; # Mcon 1
+ SPACING 0.19 ; # Mcon 2
+ ENCLOSURE BELOW 0.0 0.0 ; # Mcon 4
+ ENCLOSURE ABOVE 0.030 0.060 ; # Met1 4 / Met1 5
+
+ DCCURRENTDENSITY AVERAGE 0.36 ; # mA per via Iavg_max at Tj = 90oC
+ ANTENNADIFFAREARATIO PWL ( ( 0.0 3.0 ) ( 0.0125 3.0 ) ( 0.0225 3.405 ) ( 22.5 408.0 ) ) ;
+
+END mcon
+
+LAYER met1
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+
+ PITCH 0.34 ;
+ OFFSET 0.17 ;
+
+ WIDTH 0.140 ; # Met1 1
+ #SPACING 0.140 ; # Met1 2
+ #SPACING 0.280 RANGE 3.001 100 ; # Met1 3b
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.140000
+ WIDTH 3.000000 0.280000
+ ;
+ AREA 0.083 ; # Met1 6
+ THICKNESS 0.35 ;
+
+ ANTENNAMODEL OXIDE1 ;
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+
+ EDGECAPACITANCE 1.79E-6 ;
+ CAPACITANCE CPERSQDIST 25.8E-6 ;
+ DCCURRENTDENSITY AVERAGE 2.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 6.1 ; # mA/um Irms_max at Tj = 90oC
+ MAXIMUMDENSITY 70.0 ;
+ DENSITYCHECKWINDOW 700.0 700.0 ;
+ DENSITYCHECKSTEP 70.0 ;
+
+ RESISTANCE RPERSQ 0.125 ;
+END met1
+
+LAYER via
+ TYPE CUT ;
+ WIDTH 0.15 ; # Via 1a
+ SPACING 0.17 ; # Via 2
+ ENCLOSURE BELOW 0.055 0.085 ; # Via 4a / Via 5a
+ ENCLOSURE ABOVE 0.055 0.085 ; # Met2 4 / Met2 5
+ ANTENNADIFFAREARATIO PWL ( ( 0.0 6.0 ) ( 0.0125 6.0 ) ( 0.0225 6.81 ) ( 22.5 816.0 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.29 ; # mA per via Iavg_max at Tj = 90oC
+END via
+
+LAYER met2
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+
+ PITCH 0.46 ;
+ OFFSET 0.23 ;
+
+ WIDTH 0.140 ; # Met2 1
+ #SPACING 0.140 ; # Met2 2
+ #SPACING 0.280 RANGE 3.001 100 ; # Met2 3b
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.140000
+ WIDTH 3.000000 0.28000 ;
+ AREA 0.0676 ; # Met2 6
+ THICKNESS 0.35 ;
+
+ ANTENNAMODEL OXIDE1 ;
+ CAPACITANCE CPERSQDIST 17.5E-6 ;
+ DCCURRENTDENSITY AVERAGE 2.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 6.1 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.0 400.0 ) ( 0.0125 400.0 ) ( 0.0225 2609.0 ) ( 22.5 11600.0 ) ) ;
+
+ MAXIMUMDENSITY 70.0 ;
+ DENSITYCHECKWINDOW 700.0 700.0 ;
+ DENSITYCHECKSTEP 70.0 ;
+ RESISTANCE RPERSQ 0.125 ;
+END met2
+
+LAYER via2
+ TYPE CUT ;
+ WIDTH 0.20 ; # Via2 1
+ SPACING 0.20 ; # Via2 2
+ ENCLOSURE BELOW 0.040 0.085 ; # Via2 4
+ ENCLOSURE ABOVE 0.065 0.065 ; # Met3 4
+ ANTENNADIFFAREARATIO PWL ( ( 0.0 6.0 ) ( 0.0125 6.0 ) ( 0.0225 6.81 ) ( 22.5 816.0 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.48 ; # mA per via Iavg_max at Tj = 90oC
+
+END via2
+
+LAYER met3
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+
+ PITCH 0.68 ;
+ OFFSET 0.34 ;
+
+ WIDTH 0.300 ; # Met3 1
+ #SPACING 0.300 ; # Met3 2
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 0.30
+ WIDTH 3.0 0.40 ;
+ AREA 0.240 ; # Met3 6
+ THICKNESS 0.8 ;
+
+ EDGECAPACITANCE 1.86E-6 ;
+ CAPACITANCE CPERSQDIST 12.6E-6 ;
+ DCCURRENTDENSITY AVERAGE 6.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 14.9 ; # mA/um Irms_max at Tj = 90oC
+
+ ANTENNAMODEL OXIDE1 ;
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.0 400.0 ) ( 0.0125 400.0 ) ( 0.0225 2609.0 ) ( 22.5 11600.0 ) ) ;
+
+ MAXIMUMDENSITY 70.0 ;
+ DENSITYCHECKWINDOW 700.0 700.0 ;
+ DENSITYCHECKSTEP 70.0 ;
+ RESISTANCE RPERSQ 0.047 ;
+END met3
+
+LAYER via3
+ TYPE CUT ;
+
+ WIDTH 0.20 ; # Via3 1
+ SPACING 0.20 ; # Via3 2
+ ENCLOSURE BELOW 0.060 0.090 ; # Via3 4 / Via3 5
+ ENCLOSURE ABOVE 0.065 0.065 ; # Met4 3
+ ANTENNADIFFAREARATIO PWL ( ( 0.0 6.0 ) ( 0.0125 6.0 ) ( 0.0225 6.81 ) ( 22.5 816.0 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.48 ; # mA per via Iavg_max at Tj = 90oC
+END via3
+
+LAYER met4
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+
+ PITCH 0.92 ;
+ OFFSET 0.46 ;
+
+ WIDTH 0.300 ; # Met4 1
+ #SPACING 0.300 ; # Met4 2
+
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 0.30
+ WIDTH 3.0 0.40 ;
+ AREA 0.240 ; # Met4 4a
+
+ THICKNESS 0.8 ;
+
+ EDGECAPACITANCE 1.29E-6 ;
+ CAPACITANCE CPERSQDIST 8.67E-6 ;
+ DCCURRENTDENSITY AVERAGE 6.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 14.9 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNAMODEL OXIDE1 ;
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.0 400.0 ) ( 0.0125 400.0 ) ( 0.0225 2609.0 ) ( 22.5 11600.0 ) ) ;
+
+ MAXIMUMDENSITY 70.0 ;
+ DENSITYCHECKWINDOW 700.0 700.0 ;
+ DENSITYCHECKSTEP 70.0 ;
+ RESISTANCE RPERSQ 0.047 ;
+END met4
+
+LAYER via4
+ TYPE CUT ;
+
+ WIDTH 0.80 ; # Via4 1
+ SPACING 0.80 ; # Via4 2
+ ENCLOSURE BELOW 0.190 0.190 ; # Via4 4
+ ENCLOSURE ABOVE 0.310 0.310 ; # Met5 3
+ ANTENNADIFFAREARATIO PWL ( ( 0.0 6.0 ) ( 0.0125 6.0 ) ( 0.0225 6.81 ) ( 22.5 816.0 ) ) ;
+ DCCURRENTDENSITY AVERAGE 2.49 ; # mA per via Iavg_max at Tj = 90oC
+END via4
+
+LAYER met5
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+
+ PITCH 3.4 ;
+ OFFSET 1.7 ;
+
+ WIDTH 1.600 ; # Met5 1
+ #SPACING 1.600 ; # Met5 2
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 1.600 ;
+ AREA 4.000 ; # Met5 4
+
+ THICKNESS 1.2 ;
+
+ ANTENNAMODEL OXIDE1 ;
+ EDGECAPACITANCE 4.96E-6 ;
+ CAPACITANCE CPERSQDIST 6.48E-6 ;
+ DCCURRENTDENSITY AVERAGE 10.17 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 22.34 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.0 400.0 ) ( 0.0125 400.0 ) ( 0.0225 2609.0 ) ( 22.5 11600.0 ) ) ;
+
+ RESISTANCE RPERSQ 0.0285 ;
+END met5
+
+### Routing via cells section ###
+# Plus via rule, metals are along the prefered direction
+VIA L1M1_PR DEFAULT
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER li1 ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER met1 ;
+ RECT -0.145000 -0.115000 0.145000 0.115000 ;
+END L1M1_PR
+
+VIARULE L1M1_PR GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000000 0.000000 ;
+ LAYER met1 ;
+ ENCLOSURE 0.060000 0.030000 ;
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ SPACING 0.360000 BY 0.360000 ;
+END L1M1_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA L1M1_PR_R DEFAULT
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER li1 ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER met1 ;
+ RECT -0.115000 -0.145000 0.115000 0.145000 ;
+END L1M1_PR_R
+
+VIARULE L1M1_PR_R GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000000 0.000000 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030000 0.060000 ;
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ SPACING 0.360000 BY 0.360000 ;
+END L1M1_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA L1M1_PR_M DEFAULT
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER li1 ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER met1 ;
+ RECT -0.115000 -0.145000 0.115000 0.145000 ;
+END L1M1_PR_M
+
+VIARULE L1M1_PR_M GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000000 0.000000 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030000 0.060000 ;
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ SPACING 0.360000 BY 0.360000 ;
+END L1M1_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA L1M1_PR_MR DEFAULT
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER li1 ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER met1 ;
+ RECT -0.145000 -0.115000 0.145000 0.115000 ;
+END L1M1_PR_MR
+
+VIARULE L1M1_PR_MR GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000000 0.000000 ;
+ LAYER met1 ;
+ ENCLOSURE 0.060000 0.030000 ;
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ SPACING 0.360000 BY 0.360000 ;
+END L1M1_PR_MR
+
+# Centered via rule, we really do not want to use it
+VIA L1M1_PR_C DEFAULT
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER li1 ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ LAYER met1 ;
+ RECT -0.145000 -0.145000 0.145000 0.145000 ;
+END L1M1_PR_C
+
+VIARULE L1M1_PR_C GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000000 0.000000 ;
+ LAYER met1 ;
+ ENCLOSURE 0.060000 0.060000 ;
+ LAYER mcon ;
+ RECT -0.085000 -0.085000 0.085000 0.085000 ;
+ SPACING 0.360000 BY 0.360000 ;
+END L1M1_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M1M2_PR DEFAULT
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ LAYER met1 ;
+ RECT -0.160000 -0.130000 0.160000 0.130000 ;
+ LAYER met2 ;
+ RECT -0.130000 -0.160000 0.130000 0.160000 ;
+END M1M2_PR
+
+VIARULE M1M2_PR GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.085000 0.055000 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055000 0.085000 ;
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ SPACING 0.320000 BY 0.320000 ;
+END M1M2_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M1M2_PR_R DEFAULT
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ LAYER met1 ;
+ RECT -0.130000 -0.160000 0.130000 0.160000 ;
+ LAYER met2 ;
+ RECT -0.160000 -0.130000 0.160000 0.130000 ;
+END M1M2_PR_R
+
+VIARULE M1M2_PR_R GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055000 0.085000 ;
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.055000 ;
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ SPACING 0.320000 BY 0.320000 ;
+END M1M2_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M1M2_PR_M DEFAULT
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ LAYER met1 ;
+ RECT -0.160000 -0.130000 0.160000 0.130000 ;
+ LAYER met2 ;
+ RECT -0.160000 -0.130000 0.160000 0.130000 ;
+END M1M2_PR_M
+
+VIARULE M1M2_PR_M GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.085000 0.055000 ;
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.055000 ;
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ SPACING 0.320000 BY 0.320000 ;
+END M1M2_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M1M2_PR_MR DEFAULT
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ LAYER met1 ;
+ RECT -0.130000 -0.160000 0.130000 0.160000 ;
+ LAYER met2 ;
+ RECT -0.130000 -0.160000 0.130000 0.160000 ;
+END M1M2_PR_MR
+
+VIARULE M1M2_PR_MR GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055000 0.085000 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055000 0.085000 ;
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ SPACING 0.320000 BY 0.320000 ;
+END M1M2_PR_MR
+
+# Centered via rule, we really do not want to use it
+VIA M1M2_PR_C DEFAULT
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ LAYER met1 ;
+ RECT -0.160000 -0.160000 0.160000 0.160000 ;
+ LAYER met2 ;
+ RECT -0.160000 -0.160000 0.160000 0.160000 ;
+END M1M2_PR_C
+
+VIARULE M1M2_PR_C GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.085000 0.085000 ;
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.085000 ;
+ LAYER via ;
+ RECT -0.075000 -0.075000 0.075000 0.075000 ;
+ SPACING 0.320000 BY 0.320000 ;
+END M1M2_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M2M3_PR DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.140000 -0.185000 0.140000 0.185000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR
+
+VIARULE M2M3_PR GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.040000 0.085000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M2M3_PR_R DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.185000 -0.140000 0.185000 0.140000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_R
+
+VIARULE M2M3_PR_R GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.040000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M2M3_PR_M DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.140000 -0.185000 0.140000 0.185000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_M
+
+VIARULE M2M3_PR_M GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.040000 0.085000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M2M3_PR_MR DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.185000 -0.140000 0.185000 0.140000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_MR
+
+VIARULE M2M3_PR_MR GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.040000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_MR
+
+# Centered via rule, we really do not want to use it
+VIA M2M3_PR_C DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.185000 -0.185000 0.185000 0.185000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_C
+
+VIARULE M2M3_PR_C GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.085000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M3M4_PR DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.190000 -0.160000 0.190000 0.160000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR
+
+VIARULE M3M4_PR GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.090000 0.060000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M3M4_PR_R DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.160000 -0.190000 0.160000 0.190000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_R
+
+VIARULE M3M4_PR_R GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.060000 0.090000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M3M4_PR_M DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.190000 -0.160000 0.190000 0.160000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_M
+
+VIARULE M3M4_PR_M GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.090000 0.060000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M3M4_PR_MR DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.160000 -0.190000 0.160000 0.190000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_MR
+
+VIARULE M3M4_PR_MR GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.060000 0.090000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_MR
+
+# Centered via rule, we really do not want to use it
+VIA M3M4_PR_C DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.190000 -0.190000 0.190000 0.190000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_C
+
+VIARULE M3M4_PR_C GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.090000 0.090000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M4M5_PR DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR
+
+VIARULE M4M5_PR GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M4M5_PR_R DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_R
+
+VIARULE M4M5_PR_R GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M4M5_PR_M DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_M
+
+VIARULE M4M5_PR_M GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M4M5_PR_MR DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_MR
+
+VIARULE M4M5_PR_MR GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_MR
+
+# Centered via rule, we really do not want to use it
+VIA M4M5_PR_C DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_C
+
+VIARULE M4M5_PR_C GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_C
+### end of single via cells ###
+
+END LIBRARY
diff --git a/sky130/custom/techLEF/sky130_fd_sc_hs_tech.lef b/sky130/custom/techLEF/sky130_fd_sc_hs_tech.lef
new file mode 100644
index 0000000..7f8f3af
--- /dev/null
+++ b/sky130/custom/techLEF/sky130_fd_sc_hs_tech.lef
@@ -0,0 +1,712 @@
+
+NAMESCASESENSITIVE ON ;
+BUSBITCHARS "[]" ;
+DIVIDERCHAR "/" ;
+UNITS
+ TIME NANOSECONDS 1 ;
+ CAPACITANCE PICOFARADS 1 ;
+ RESISTANCE OHMS 1 ;
+ DATABASE MICRONS 1000 ;
+END UNITS
+MANUFACTURINGGRID 0.005 ;
+
+SITE unitehd
+ SYMMETRY Y ;
+ CLASS CORE ;
+ SIZE 0.460 BY 3.400 ;
+END unitehd
+
+###### Starting overlap layers #####
+# ******** Layer OverlapCheck, type blockage, number 90 **************
+LAYER OverlapCheck
+ TYPE OVERLAP ;
+END OverlapCheck
+
+###### Starting routing layers - metal and via #####
+# ******** Layer li1, type routing, number 56 **************
+LAYER li1
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+ PITCH 0.48 ;
+ MINWIDTH 0.170000 ;
+ WIDTH 0.170000 ;
+ AREA 0.028900 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 0.170000 ;
+ THICKNESS 0.100000 ;
+ EDGECAPACITANCE 3.26E-6 ;
+ CAPACITANCE CPERSQDIST 36.9E-6 ;
+ RESISTANCE RPERSQ 12.2 ;
+# DCCURRENTDENSITY AVERAGE (no limit on this layer) ;
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 75.000000 ) ( 0.012500 75.000000 ) ( 0.022500 85.125000 ) ( 22.500000 10200.000000 ) ) ;
+END li1
+
+# ******** Layer mcon, type routing, number 35 **************
+LAYER mcon
+ TYPE CUT ;
+ SPACING 0.190000 ;
+ WIDTH 0.170000 ;
+ ANTENNADIFFAREARATIO PWL ( ( 0.000000 3.000000 ) ( 0.012500 3.000000 ) ( 0.022500 3.405000 ) ( 22.500000 408.000000 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.36 ; # mA per via Iavg_max at Tj = 90oC
+ ENCLOSURE BELOW 0.000000 0.000000 ;
+ ENCLOSURE ABOVE 0.000000 0.000000 ;
+END mcon
+
+# ******** Layer met1, type routing, number 36 **************
+LAYER met1
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+ PITCH 0.37 ;
+ MINENCLOSEDAREA 0.140000 ;
+ MINWIDTH 0.140000 ;
+ WIDTH 0.140000 ;
+ AREA 0.083000 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.140000
+ WIDTH 3.000000 0.280000
+ ;
+ THICKNESS 0.350000 ;
+ EDGECAPACITANCE 1.79E-6 ;
+ CAPACITANCE CPERSQDIST 25.8E-6 ;
+ RESISTANCE RPERSQ 0.125 ;
+ DCCURRENTDENSITY AVERAGE 2.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 6.1 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+END met1
+
+# ******** Layer via, type routing, number 40 **************
+LAYER via1
+ TYPE CUT ;
+ SPACING 0.170000 ;
+ WIDTH 0.150000 ;
+ ANTENNADIFFAREARATIO PWL ( ( 0.000000 6.000000 ) ( 0.012500 6.000000 ) ( 0.022500 6.810000 ) ( 22.500000 816.000000 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.29 ; # mA per via Iavg_max at Tj = 90oC
+ ENCLOSURE BELOW 0.000000 0.000000 ;
+ ENCLOSURE ABOVE 0.000000 0.000000 ;
+END via1
+
+# ******** Layer met2, type routing, number 41 **************
+LAYER met2
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+ PITCH 0.48 ;
+ MINENCLOSEDAREA 0.140000 ;
+ MINWIDTH 0.140000 ;
+ WIDTH 0.140000 ;
+ AREA 0.067600 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.140000
+ WIDTH 3.000000 0.280000
+ ;
+ THICKNESS 0.350000 ;
+ EDGECAPACITANCE 1.22E-6 ;
+ CAPACITANCE CPERSQDIST 17.5E-6 ;
+ RESISTANCE RPERSQ 0.125 ;
+ DCCURRENTDENSITY AVERAGE 2.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 6.1 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+END met2
+
+# ******** Layer via2, type routing, number 44 **************
+LAYER via2
+ TYPE CUT ;
+ SPACING 0.200000 ;
+ WIDTH 0.200000 ;
+ ANTENNADIFFAREARATIO PWL ( ( 0.000000 6.000000 ) ( 0.012500 6.000000 ) ( 0.022500 6.810000 ) ( 22.500000 816.000000 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.48 ; # mA per via Iavg_max at Tj = 90oC
+ ENCLOSURE BELOW 0.000000 0.000000 ;
+ ENCLOSURE ABOVE 0.000000 0.000000 ;
+END via2
+
+# ******** Layer met3, type routing, number 34 **************
+LAYER met3
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+ PITCH 0.666 ;
+ MINWIDTH 0.300000 ;
+ WIDTH 0.300000 ;
+ AREA 0.240000 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.300000
+ WIDTH 3.000000 0.400000
+ ;
+ THICKNESS 0.800000 ;
+ EDGECAPACITANCE 1.86E-6 ;
+ CAPACITANCE CPERSQDIST 12.6E-6 ;
+ RESISTANCE RPERSQ 0.047 ;
+ DCCURRENTDENSITY AVERAGE 6.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 14.9 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+END met3
+
+# ******** Layer via3, type routing, number 70 **************
+LAYER via3
+ TYPE CUT ;
+ SPACING 0.200000 ;
+ WIDTH 0.200000 ;
+ ANTENNADIFFAREARATIO PWL ( ( 0.000000 6.000000 ) ( 0.012500 6.000000 ) ( 0.022500 6.810000 ) ( 22.500000 816.000000 ) ) ;
+ DCCURRENTDENSITY AVERAGE 0.48 ; # mA per via Iavg_max at Tj = 90oC
+ ENCLOSURE BELOW 0.000000 0.000000 ;
+ ENCLOSURE ABOVE 0.000000 0.000000 ;
+END via3
+
+# ******** Layer met4, type routing, number 71 **************
+LAYER met4
+ TYPE ROUTING ;
+ DIRECTION VERTICAL ;
+ PITCH 0.96 ;
+ MINWIDTH 0.300000 ;
+ WIDTH 0.300000 ;
+ AREA 0.240000 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0.000
+ WIDTH 0.000 0.300000
+ WIDTH 3.000000 0.400000
+ ;
+ THICKNESS 0.800000 ;
+ EDGECAPACITANCE 1.29E-6 ;
+ CAPACITANCE CPERSQDIST 8.67E-6 ;
+ RESISTANCE RPERSQ 0.047 ;
+ DCCURRENTDENSITY AVERAGE 6.8 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 14.9 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+END met4
+
+# ******** Layer via4, type routing, number 58 **************
+LAYER via4
+ TYPE CUT ;
+ SPACING 0.800000 ;
+ WIDTH 0.800000 ;
+ ANTENNADIFFAREARATIO PWL ( ( 0.000000 6.000000 ) ( 0.012500 6.000000 ) ( 0.022500 6.810000 ) ( 22.500000 816.000000 ) ) ;
+ DCCURRENTDENSITY AVERAGE 2.49 ; # mA per via Iavg_max at Tj = 90oC
+ ENCLOSURE BELOW 0.000000 0.000000 ;
+ ENCLOSURE ABOVE 0.000000 0.000000 ;
+END via4
+
+# ******** Layer met5, type routing, number 72 **************
+LAYER met5
+ TYPE ROUTING ;
+ DIRECTION HORIZONTAL ;
+ PITCH 3.3 ;
+ MINWIDTH 1.600000 ;
+ WIDTH 1.600000 ;
+ AREA 2.560000 ;
+ SPACINGTABLE
+ PARALLELRUNLENGTH 0
+ WIDTH 0 1.600000 ;
+ THICKNESS 1.200000 ;
+ EDGECAPACITANCE 4.96E-6 ;
+ CAPACITANCE CPERSQDIST 6.48E-6 ;
+ RESISTANCE RPERSQ 0.047 ;
+ DCCURRENTDENSITY AVERAGE 10.17 ; # mA/um Iavg_max at Tj = 90oC
+ ACCURRENTDENSITY RMS 22.34 ; # mA/um Irms_max at Tj = 90oC
+ ANTENNADIFFSIDEAREARATIO PWL ( ( 0.000000 400.000000 ) ( 0.012500 400.000000 ) ( 0.022500 2609.000000 ) ( 22.500000 11600.000000 ) ) ;
+END met5
+
+###### completed routing layers - metal and via #####
+
+### Routing via cells section ###
+# Plus via rule, metals are along the prefered direction
+VIA L1M1_PR DEFAULT
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ LAYER li1 ;
+ RECT -0.085 -0.165 0.085 0.165 ;
+ LAYER met1 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+END L1M1_PR
+
+VIARULE L1M1_PR GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000 0.080 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030 0.060 ;
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ SPACING 0.360 BY 0.360 ;
+END L1M1_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA L1M1_PR_R DEFAULT
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ LAYER li1 ;
+ RECT -0.165 -0.085 0.165 0.085 ;
+ LAYER met1 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+END L1M1_PR_R
+
+VIARULE L1M1_PR_R GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000 0.080 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030 0.060 ;
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ SPACING 0.360 BY 0.360 ;
+END L1M1_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA L1M1_PR_M DEFAULT
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ LAYER li1 ;
+ RECT -0.085 -0.165 0.085 0.165 ;
+ LAYER met1 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+END L1M1_PR_M
+
+VIARULE L1M1_PR_M GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000 0.080 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030 0.060 ;
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ SPACING 0.360 BY 0.360 ;
+END L1M1_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA L1M1_PR_MR DEFAULT
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ LAYER li1 ;
+ RECT -0.165 -0.085 0.165 0.085 ;
+ LAYER met1 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+END L1M1_PR_MR
+
+VIARULE L1M1_PR_MR GENERATE
+ LAYER li1 ;
+ ENCLOSURE 0.000 0.080 ;
+ LAYER met1 ;
+ ENCLOSURE 0.030 0.060 ;
+ LAYER mcon ;
+ RECT -0.085 -0.085 0.085 0.085 ;
+ SPACING 0.360 BY 0.360 ;
+END L1M1_PR_MR
+
+# Centered via rule, we really do not want to use it
+# VIA L1M1_PR_C DEFAULT
+# LAYER mcon ;
+# RECT -0.085000 -0.085000 0.085000 0.085000 ;
+# LAYER li1 ;
+# RECT -0.085000 -0.085000 0.085000 0.085000 ;
+# LAYER met1 ;
+# RECT -0.145000 -0.145000 0.145000 0.145000 ;
+# END L1M1_PR_C
+
+# VIARULE L1M1_PR_C GENERATE
+# LAYER li1 ;
+# ENCLOSURE 0.000000 0.000000 ;
+# LAYER met1 ;
+# ENCLOSURE 0.060000 0.060000 ;
+# LAYER mcon ;
+# RECT -0.085000 -0.085000 0.085000 0.085000 ;
+# SPACING 0.360000 BY 0.360000 ;
+# END L1M1_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M1M2_PR DEFAULT
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ LAYER met1 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+ LAYER met2 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+END M1M2_PR
+
+VIARULE M1M2_PR GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ SPACING 0.320 BY 0.320 ;
+END M1M2_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M1M2_PR_R DEFAULT
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ LAYER met1 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+ LAYER met2 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+END M1M2_PR_R
+
+VIARULE M1M2_PR_R GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ SPACING 0.320 BY 0.320 ;
+END M1M2_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M1M2_PR_M DEFAULT
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ LAYER met1 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+ LAYER met2 ;
+ RECT -0.16 -0.13 0.16 0.13 ;
+END M1M2_PR_M
+
+VIARULE M1M2_PR_M GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ SPACING 0.320 BY 0.320 ;
+END M1M2_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M1M2_PR_MR DEFAULT
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ LAYER met1 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+ LAYER met2 ;
+ RECT -0.13 -0.16 0.13 0.16 ;
+END M1M2_PR_MR
+
+VIARULE M1M2_PR_MR GENERATE
+ LAYER met1 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER met2 ;
+ ENCLOSURE 0.055 0.085 ;
+ LAYER via1 ;
+ RECT -0.075 -0.075 0.075 0.075 ;
+ SPACING 0.320 BY 0.320 ;
+END M1M2_PR_MR
+
+# # Centered via rule, we really do not want to use it
+# VIA M1M2_PR_C DEFAULT
+# LAYER via ;
+# RECT -0.075000 -0.075000 0.075000 0.075000 ;
+# LAYER met1 ;
+# RECT -0.160000 -0.160000 0.160000 0.160000 ;
+# LAYER met2 ;
+# RECT -0.160000 -0.160000 0.160000 0.160000 ;
+# END M1M2_PR_C
+
+# VIARULE M1M2_PR_C GENERATE
+# LAYER met1 ;
+# ENCLOSURE 0.085000 0.085000 ;
+# LAYER met2 ;
+# ENCLOSURE 0.085000 0.085000 ;
+# LAYER via ;
+# RECT -0.075000 -0.075000 0.075000 0.075000 ;
+# SPACING 0.320000 BY 0.320000 ;
+# END M1M2_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M2M3_PR DEFAULT
+ LAYER via2 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ LAYER met2 ;
+ RECT -0.14 -0.185 0.14 0.185 ;
+ LAYER met3 ;
+ RECT -0.165 -0.165 0.165 0.165 ;
+END M2M3_PR
+
+VIARULE M2M3_PR GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.040 0.085 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065 0.065 ;
+ LAYER via2 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ SPACING 0.40 BY 0.40 ;
+END M2M3_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M2M3_PR_R DEFAULT
+ LAYER via2 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ LAYER met2 ;
+ RECT -0.185 -0.14 0.185 0.14 ;
+ LAYER met3 ;
+ RECT -0.165 -0.165 0.165 0.165 ;
+END M2M3_PR_R
+
+VIARULE M2M3_PR_R GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.040 0.085 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065 0.065 ;
+ LAYER via2 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ SPACING 0.40 BY 0.40 ;
+END M2M3_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M2M3_PR_M DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.140000 -0.185000 0.140000 0.185000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_M
+
+VIARULE M2M3_PR_M GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.040000 0.085000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M2M3_PR_MR DEFAULT
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met2 ;
+ RECT -0.185000 -0.140000 0.185000 0.140000 ;
+ LAYER met3 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M2M3_PR_MR
+
+VIARULE M2M3_PR_MR GENERATE
+ LAYER met2 ;
+ ENCLOSURE 0.085000 0.040000 ;
+ LAYER met3 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via2 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M2M3_PR_MR
+
+# # Centered via rule, we really do not want to use it
+# VIA M2M3_PR_C DEFAULT
+# LAYER via2 ;
+# RECT -0.100000 -0.100000 0.100000 0.100000 ;
+# LAYER met2 ;
+# RECT -0.185000 -0.185000 0.185000 0.185000 ;
+# LAYER met3 ;
+# RECT -0.165000 -0.165000 0.165000 0.165000 ;
+# END M2M3_PR_C
+
+# VIARULE M2M3_PR_C GENERATE
+# LAYER met2 ;
+# ENCLOSURE 0.085000 0.085000 ;
+# LAYER met3 ;
+# ENCLOSURE 0.065000 0.065000 ;
+# LAYER via2 ;
+# RECT -0.100000 -0.100000 0.100000 0.100000 ;
+# SPACING 0.400000 BY 0.400000 ;
+# END M2M3_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M3M4_PR DEFAULT
+ LAYER via3 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ LAYER met3 ;
+ RECT -0.19 -0.16 0.19 0.16 ;
+ LAYER met4 ;
+ RECT -0.165 -0.165 0.165 0.165 ;
+END M3M4_PR
+
+VIARULE M3M4_PR GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.06 0.09 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065 0.065 ;
+ LAYER via3 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ SPACING 0.40 BY 0.40 ;
+END M3M4_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M3M4_PR_R DEFAULT
+ LAYER via3 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ LAYER met3 ;
+ RECT -0.16 -0.19 0.16 0.19 ;
+ LAYER met4 ;
+ RECT -0.165 -0.165 0.165 0.165 ;
+END M3M4_PR_R
+
+VIARULE M3M4_PR_R GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.06 0.09 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065 0.065 ;
+ LAYER via3 ;
+ RECT -0.1 -0.1 0.1 0.1 ;
+ SPACING 0.40 BY 0.40 ;
+END M3M4_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M3M4_PR_M DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.190000 -0.160000 0.190000 0.160000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_M
+
+VIARULE M3M4_PR_M GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.090000 0.060000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M3M4_PR_MR DEFAULT
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ LAYER met3 ;
+ RECT -0.160000 -0.190000 0.160000 0.190000 ;
+ LAYER met4 ;
+ RECT -0.165000 -0.165000 0.165000 0.165000 ;
+END M3M4_PR_MR
+
+VIARULE M3M4_PR_MR GENERATE
+ LAYER met3 ;
+ ENCLOSURE 0.060000 0.090000 ;
+ LAYER met4 ;
+ ENCLOSURE 0.065000 0.065000 ;
+ LAYER via3 ;
+ RECT -0.100000 -0.100000 0.100000 0.100000 ;
+ SPACING 0.400000 BY 0.400000 ;
+END M3M4_PR_MR
+
+# # Centered via rule, we really do not want to use it
+# VIA M3M4_PR_C DEFAULT
+# LAYER via3 ;
+# RECT -0.100000 -0.100000 0.100000 0.100000 ;
+# LAYER met3 ;
+# RECT -0.190000 -0.190000 0.190000 0.190000 ;
+# LAYER met4 ;
+# RECT -0.165000 -0.165000 0.165000 0.165000 ;
+# END M3M4_PR_C
+
+# VIARULE M3M4_PR_C GENERATE
+# LAYER met3 ;
+# ENCLOSURE 0.090000 0.090000 ;
+# LAYER met4 ;
+# ENCLOSURE 0.065000 0.065000 ;
+# LAYER via3 ;
+# RECT -0.100000 -0.100000 0.100000 0.100000 ;
+# SPACING 0.400000 BY 0.400000 ;
+# END M3M4_PR_C
+
+# Plus via rule, metals are along the prefered direction
+VIA M4M5_PR DEFAULT
+ LAYER via4 ;
+ RECT -0.4 -0.4 0.4 0.4 ;
+ LAYER met4 ;
+ RECT -0.59 -0.59 0.59 0.59 ;
+ LAYER met5 ;
+ RECT -0.71 -0.71 0.71 0.71 ;
+END M4M5_PR
+
+VIARULE M4M5_PR GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190 0.190 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310 0.310 ;
+ LAYER via4 ;
+ RECT -0.4 -0.4 0.4 0.4 ;
+ SPACING 1.60 BY 1.60 ;
+END M4M5_PR
+
+# Plus via rule, metals are along the non prefered direction
+VIA M4M5_PR_R DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_R
+
+VIARULE M4M5_PR_R GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_R
+
+# Minus via rule, lower layer metal is along prefered direction
+VIA M4M5_PR_M DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_M
+
+VIARULE M4M5_PR_M GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_M
+
+# Minus via rule, upper layer metal is along prefered direction
+VIA M4M5_PR_MR DEFAULT
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ LAYER met4 ;
+ RECT -0.590000 -0.590000 0.590000 0.590000 ;
+ LAYER met5 ;
+ RECT -0.710000 -0.710000 0.710000 0.710000 ;
+END M4M5_PR_MR
+
+VIARULE M4M5_PR_MR GENERATE
+ LAYER met4 ;
+ ENCLOSURE 0.190000 0.190000 ;
+ LAYER met5 ;
+ ENCLOSURE 0.310000 0.310000 ;
+ LAYER via4 ;
+ RECT -0.400000 -0.400000 0.400000 0.400000 ;
+ SPACING 1.600000 BY 1.600000 ;
+END M4M5_PR_MR
+
+# # Centered via rule, we really do not want to use it
+# VIA M4M5_PR_C DEFAULT
+# LAYER via4 ;
+# RECT -0.400000 -0.400000 0.400000 0.400000 ;
+# LAYER met4 ;
+# RECT -0.590000 -0.590000 0.590000 0.590000 ;
+# LAYER met5 ;
+# RECT -0.710000 -0.710000 0.710000 0.710000 ;
+# END M4M5_PR_C
+
+# VIARULE M4M5_PR_C GENERATE
+# LAYER met4 ;
+# ENCLOSURE 0.190000 0.190000 ;
+# LAYER met5 ;
+# ENCLOSURE 0.310000 0.310000 ;
+# LAYER via4 ;
+# RECT -0.400000 -0.400000 0.400000 0.400000 ;
+# SPACING 1.600000 BY 1.600000 ;
+# END M4M5_PR_C
+
diff --git a/sky130/sky130.json b/sky130/sky130.json
new file mode 100644
index 0000000..bf54238
--- /dev/null
+++ b/sky130/sky130.json
@@ -0,0 +1,53 @@
+#define DESCRIPTION Skywater 0.13um CMOS, local interconntect + high-resistance poly
+#ifdef METAL5
+#define OPTION1 + 5 metal layer backend stack
+#endif (METAL5)
+#ifdef MIM
+#define OPTION2 + MiM caps
+#endif (MIM)
+#ifdef REDISTRIBUTION
+#define OPTION3 + redistribution layer
+#endif (REDISTRIBUTION)
+{
+ "foundry" : "SW",
+ "foundry-name" : "SkyWater",
+ "node" : "TECHNAME",
+ "feature-size" : "130nm",
+ "status" : "active",
+ "description" : "DESCRIPTION OPTION1 OPTION2 OPTION3",
+ "options" : [
+#ifdef METAL5
+#undef METAL5
+#ifdef MIM || REDISTRIBUTION
+ "METAL5",
+#else (!(MIM || REDISTRIBUTION))
+ "METAL5"
+#endif (!(MIM || REDISTRIBUTION))
+#endif (METAL5)
+#ifdef MIM
+#undef MIM
+#ifdef REDISTRIBUTION
+ "MIM",
+#else
+ "MIM"
+#endif (REDISTRIBUTION)
+#endif (MIM)
+#ifdef REDISTRIBUTION
+#undef REDISTRIBUTION
+ "REDISTRIBUTION"
+#endif (REDISTRIBUTION)
+ ],
+ "stdcells" : [
+ "sky130_fd_sc_hd",
+ "sky130_fd_sc_hdll",
+ "sky130_fd_sc_hs",
+ "sky130_fd_sc_hvl",
+ "sky130_fd_sc_lp",
+ "sky130_fd_sc_ls",
+ "sky130_fd_sc_ms",
+ "sky130_osu130"
+ ],
+ "iocells" : [
+ "sky130_fd_io"
+ ]
+}
diff --git a/sky130/sky130.lyp b/sky130/sky130.lyp
new file mode 100644
index 0000000..cf7ec0b
--- /dev/null
+++ b/sky130/sky130.lyp
@@ -0,0 +1,8241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>prBoundary.boundary - 235/4</name>
+ <source>235/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwell.drawing - 64/44</name>
+ <source>64/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C39</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwell.pin - 122/16</name>
+ <source>122/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwell.label - 64/59</name>
+ <source>64/59@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwell.res - 64/13</name>
+ <source>64/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwell.cut - 64/14</name>
+ <source>64/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#96c8ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C39</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwelliso.pin - 44/16</name>
+ <source>44/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pwelliso.label - 44/5</name>
+ <source>44/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nwell.drawing - 64/20</name>
+ <source>64/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C2</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nwell.net - 84/23</name>
+ <source>84/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nwell.pin - 64/16</name>
+ <source>64/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nwell.label - 64/5</name>
+ <source>64/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#c8ffc8</frame-color>
+ <fill-color>#c8ffc8</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C48</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>dnwell.drawing - 64/18</name>
+ <source>64/18@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>vhvi.drawing - 74/21</name>
+ <source>74/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.drawing - 65/20</name>
+ <source>65/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.res - 65/13</name>
+ <source>65/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.cut - 65/14</name>
+ <source>65/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.pin - 65/16</name>
+ <source>65/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#c8ffc8</frame-color>
+ <fill-color>#c8ffc8</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.label - 65/6</name>
+ <source>65/6@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.net - 65/23</name>
+ <source>65/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.boundary - 65/4</name>
+ <source>65/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>diff.hv - 65/8</name>
+ <source>65/8@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tap.drawing - 65/44</name>
+ <source>65/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tap.pin - 65/48</name>
+ <source>65/48@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tap.net - 65/41</name>
+ <source>65/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tap.boundary - 65/60</name>
+ <source>65/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff464</frame-color>
+ <fill-color>#fff464</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tap.label - 65/5</name>
+ <source>65/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C23</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>psdm.drawing - 94/20</name>
+ <source>94/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C22</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nsdm.drawing - 93/44</name>
+ <source>93/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C42</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.drawing - 66/20</name>
+ <source>66/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C39</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.pin - 66/16</name>
+ <source>66/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.res - 66/13</name>
+ <source>66/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.cut - 66/14</name>
+ <source>66/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.gate - 66/9</name>
+ <source>66/9@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffafaf</frame-color>
+ <fill-color>#ffafaf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.label - 66/5</name>
+ <source>66/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.boundary - 66/4</name>
+ <source>66/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.probe - 66/25</name>
+ <source>66/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.short - 66/15</name>
+ <source>66/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.net - 66/23</name>
+ <source>66/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>poly.model - 66/83</name>
+ <source>66/83@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C51</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ldntm.drawing - 11/44</name>
+ <source>11/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>lvtn.drawing - 125/44</name>
+ <source>125/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>hvtp.drawing - 78/44</name>
+ <source>78/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>hvtr.drawing - 18/20</name>
+ <source>18/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C42</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>tunm.drawing - 80/20</name>
+ <source>80/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C24</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>licon1.drawing - 66/44</name>
+ <source>66/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>licon1.boundary - 66/60</name>
+ <source>66/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#c8ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>licon1.pin - 66/58</name>
+ <source>66/58@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>licon1.net - 66/41</name>
+ <source>66/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>npc.drawing - 95/20</name>
+ <source>95/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.drawing - 67/20</name>
+ <source>67/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C47</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.pin - 67/16</name>
+ <source>67/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.res - 67/13</name>
+ <source>67/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.cut - 67/14</name>
+ <source>67/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.label - 67/5</name>
+ <source>67/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.net - 67/23</name>
+ <source>67/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.boundary - 67/4</name>
+ <source>67/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.blockage - 67/10</name>
+ <source>67/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.short - 67/15</name>
+ <source>67/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>li1.probe - 67/25</name>
+ <source>67/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>mcon.drawing - 67/44</name>
+ <source>67/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>mcon.boundary - 67/60</name>
+ <source>67/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>mcon.pin - 67/48</name>
+ <source>67/48@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>mcon.net - 67/41</name>
+ <source>67/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.drawing - 68/20</name>
+ <source>68/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.res - 68/13</name>
+ <source>68/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.cut - 68/14</name>
+ <source>68/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.pin - 68/16</name>
+ <source>68/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#96c8ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.label - 68/5</name>
+ <source>68/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.net - 68/23</name>
+ <source>68/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.boundary - 68/4</name>
+ <source>68/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.blockage - 68/10</name>
+ <source>68/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.short - 68/15</name>
+ <source>68/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.probe - 68/25</name>
+ <source>68/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option1 - 68/32</name>
+ <source>68/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option2 - 68/33</name>
+ <source>68/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option3 - 68/34</name>
+ <source>68/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option4 - 68/35</name>
+ <source>68/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option5 - 68/36</name>
+ <source>68/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option6 - 68/37</name>
+ <source>68/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option7 - 68/38</name>
+ <source>68/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.option8 - 68/39</name>
+ <source>68/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via.drawing - 68/44</name>
+ <source>68/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via.boundary - 68/60</name>
+ <source>68/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via.net - 68/41</name>
+ <source>68/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ae7dff</frame-color>
+ <fill-color>#ae7dff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via.pin - 68/58</name>
+ <source>68/58@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.drawing - 69/20</name>
+ <source>69/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.res - 69/13</name>
+ <source>69/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.cut - 69/14</name>
+ <source>69/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C46</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.pin - 69/16</name>
+ <source>69/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffc8ff</frame-color>
+ <fill-color>#ffc8ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.label - 69/5</name>
+ <source>69/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.net - 69/23</name>
+ <source>69/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.boundary - 69/4</name>
+ <source>69/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.blockage - 69/10</name>
+ <source>69/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.short - 69/15</name>
+ <source>69/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.probe - 69/25</name>
+ <source>69/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option1 - 69/32</name>
+ <source>69/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option2 - 69/33</name>
+ <source>69/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option3 - 69/34</name>
+ <source>69/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option4 - 69/35</name>
+ <source>69/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option5 - 69/36</name>
+ <source>69/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option6 - 69/37</name>
+ <source>69/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option7 - 69/38</name>
+ <source>69/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.option8 - 69/39</name>
+ <source>69/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via2.drawing - 69/44</name>
+ <source>69/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via2.boundary - 69/60</name>
+ <source>69/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via2.pin - 69/58</name>
+ <source>69/58@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via2.net - 69/41</name>
+ <source>69/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.drawing - 70/20</name>
+ <source>70/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.res - 70/13</name>
+ <source>70/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.cut - 70/14</name>
+ <source>70/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.pin - 70/16</name>
+ <source>70/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#c8ffff</frame-color>
+ <fill-color>#c8ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.label - 70/5</name>
+ <source>70/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.net - 70/23</name>
+ <source>70/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.boundary - 70/4</name>
+ <source>70/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.blockage - 70/10</name>
+ <source>70/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.short - 70/15</name>
+ <source>70/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.fuse - 70/17</name>
+ <source>70/17@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.probe - 70/25</name>
+ <source>70/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option1 - 70/32</name>
+ <source>70/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option2 - 70/33</name>
+ <source>70/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option3 - 70/34</name>
+ <source>70/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option4 - 70/35</name>
+ <source>70/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option5 - 70/36</name>
+ <source>70/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option6 - 70/37</name>
+ <source>70/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option7 - 70/38</name>
+ <source>70/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.option8 - 70/39</name>
+ <source>70/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via3.drawing - 70/44</name>
+ <source>70/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via3.boundary - 70/60</name>
+ <source>70/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via3.pin - 70/48</name>
+ <source>70/48@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via3.net - 70/41</name>
+ <source>70/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.drawing - 71/20</name>
+ <source>71/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.res - 71/13</name>
+ <source>71/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.cut - 71/14</name>
+ <source>71/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.pin - 71/16</name>
+ <source>71/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ae7dff</frame-color>
+ <fill-color>#ae7dff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.label - 71/5</name>
+ <source>71/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.net - 71/23</name>
+ <source>71/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.boundary - 71/4</name>
+ <source>71/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.blockage - 71/10</name>
+ <source>71/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.short - 71/15</name>
+ <source>71/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.fuse - 71/17</name>
+ <source>71/17@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.probe - 71/25</name>
+ <source>71/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option1 - 71/32</name>
+ <source>71/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option2 - 71/33</name>
+ <source>71/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option3 - 71/34</name>
+ <source>71/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option4 - 71/35</name>
+ <source>71/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option5 - 71/36</name>
+ <source>71/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option6 - 71/37</name>
+ <source>71/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option7 - 71/38</name>
+ <source>71/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.option8 - 71/39</name>
+ <source>71/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via4.drawing - 71/44</name>
+ <source>71/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via4.boundary - 71/60</name>
+ <source>71/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C6</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via4.pin - 71/48</name>
+ <source>71/48@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>via4.net - 71/41</name>
+ <source>71/41@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.drawing - 72/20</name>
+ <source>72/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.res - 72/13</name>
+ <source>72/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.cut - 72/14</name>
+ <source>72/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.pin - 72/16</name>
+ <source>72/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff464</frame-color>
+ <fill-color>#fff464</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.label - 72/5</name>
+ <source>72/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C5</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.net - 72/23</name>
+ <source>72/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.boundary - 72/4</name>
+ <source>72/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C54</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.blockage - 72/10</name>
+ <source>72/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.short - 72/15</name>
+ <source>72/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.fuse - 72/17</name>
+ <source>72/17@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.probe - 72/25</name>
+ <source>72/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option1 - 72/32</name>
+ <source>72/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option2 - 72/33</name>
+ <source>72/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option3 - 72/34</name>
+ <source>72/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option4 - 72/35</name>
+ <source>72/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option5 - 72/36</name>
+ <source>72/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option6 - 72/37</name>
+ <source>72/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option7 - 72/38</name>
+ <source>72/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.option8 - 72/39</name>
+ <source>72/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C51</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>nsm.drawing - 61/20</name>
+ <source>61/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pad.drawing - 76/20</name>
+ <source>76/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pad.label - 76/5</name>
+ <source>76/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pad.pin - 76/16</name>
+ <source>76/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pnp.drawing - 82/44</name>
+ <source>82/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffc8ff</frame-color>
+ <fill-color>#ffc8ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pnp.label - 82/59</name>
+ <source>82/59@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>npn.drawing - 82/20</name>
+ <source>82/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#c8ffff</frame-color>
+ <fill-color>#c8ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>npn.label - 82/5</name>
+ <source>82/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#96c8ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C39</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rpm.drawing - 86/20</name>
+ <source>86/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C4</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>hvi.drawing - 75/20</name>
+ <source>75/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffb232</frame-color>
+ <fill-color>#ffb232</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>capacitor.drawing - 82/64</name>
+ <source>82/64@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ncm.drawing - 92/44</name>
+ <source>92/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cncm.drawing - 96/44</name>
+ <source>96/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cncm.mask - 17/0</name>
+ <source>17/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C1</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pmm.drawing - 85/44</name>
+ <source>85/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C41</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>pmm2.drawing - 77/20</name>
+ <source>77/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C48</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.drawing - 74/20</name>
+ <source>74/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C35</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.pin - 74/16</name>
+ <source>74/16@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff6464</frame-color>
+ <fill-color>#ff6464</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.label - 74/5</name>
+ <source>74/5@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.res - 74/13</name>
+ <source>74/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.cut - 74/14</name>
+ <source>74/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C37</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.short - 74/15</name>
+ <source>74/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option1 - 89/32</name>
+ <source>89/32@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option2 - 89/33</name>
+ <source>89/33@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option3 - 89/34</name>
+ <source>89/34@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C29</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option4 - 89/35</name>
+ <source>89/35@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C30</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option5 - 89/36</name>
+ <source>89/36@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C31</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option6 - 89/37</name>
+ <source>89/37@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C32</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option7 - 89/38</name>
+ <source>89/38@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C33</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.option8 - 89/39</name>
+ <source>89/39@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ubm.drawing - 127/21</name>
+ <source>127/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>bump.drawing - 127/22</name>
+ <source>127/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>inductor.drawing - 82/24</name>
+ <source>82/24@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff464</frame-color>
+ <fill-color>#fff464</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>inductor.label - 82/25</name>
+ <source>82/25@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C26</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>inductor.term1 - 82/26</name>
+ <source>82/26@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C27</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>inductor.term2 - 82/27</name>
+ <source>82/27@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C28</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>inductor.term3 - 82/28</name>
+ <source>82/28@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cfom.drawing - 22/20</name>
+ <source>22/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cfom.mask - 23/0</name>
+ <source>23/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cfom.maskAdd - 22/21</name>
+ <source>22/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cfom.maskDrop - 22/22</name>
+ <source>22/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cfom.waffleDrop - 22/24</name>
+ <source>22/24@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>fom.dummy - 22/23</name>
+ <source>22/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnwm.drawing - 109/44</name>
+ <source>109/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnwm.mask - 21/0</name>
+ <source>21/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnwm.maskAdd - 109/43</name>
+ <source>109/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnwm.maskDrop - 109/42</name>
+ <source>109/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cdnm.drawing - 110/20</name>
+ <source>110/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cdnm.mask - 48/0</name>
+ <source>48/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cdnm.maskAdd - 110/21</name>
+ <source>110/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cdnm.maskDrop - 110/22</name>
+ <source>110/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvtnm.drawing - 25/44</name>
+ <source>25/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvtnm.mask - 25/0</name>
+ <source>25/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvtnm.maskAdd - 25/43</name>
+ <source>25/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#96c8ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvtnm.maskDrop - 25/42</name>
+ <source>25/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtpm.drawing - 88/44</name>
+ <source>88/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtpm.mask - 97/0</name>
+ <source>97/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtpm.maskAdd - 97/43</name>
+ <source>97/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtpm.maskDrop - 97/42</name>
+ <source>97/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtrm.drawing - 98/44</name>
+ <source>98/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtrm.mask - 98/0</name>
+ <source>98/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtrm.maskAdd - 98/43</name>
+ <source>98/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvtrm.maskDrop - 98/42</name>
+ <source>98/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ctunm.drawing - 96/20</name>
+ <source>96/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ctunm.mask - 20/0</name>
+ <source>20/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ctunm.maskAdd - 96/21</name>
+ <source>96/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ctunm.maskDrop - 96/22</name>
+ <source>96/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>conom.drawing - 87/44</name>
+ <source>87/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>conom.mask - 88/0</name>
+ <source>88/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>conom.maskAdd - 87/43</name>
+ <source>87/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>conom.maskDrop - 87/42</name>
+ <source>87/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnsdm.drawing - 29/20</name>
+ <source>29/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnsdm.mask - 30/0</name>
+ <source>30/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnsdm.maskAdd - 29/21</name>
+ <source>29/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnsdm.maskDrop - 29/22</name>
+ <source>29/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpsdm.drawing - 31/20</name>
+ <source>31/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpsdm.mask - 32/0</name>
+ <source>32/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpsdm.maskAdd - 31/21</name>
+ <source>31/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpsdm.maskDrop - 31/22</name>
+ <source>31/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cntm.drawing - 26/20</name>
+ <source>26/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cntm.mask - 27/0</name>
+ <source>27/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cntm.maskAdd - 26/21</name>
+ <source>26/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cntm.maskDrop - 26/22</name>
+ <source>26/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>hvntm.drawing - 125/20</name>
+ <source>125/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff5e6</frame-color>
+ <fill-color>#fff5e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvntm.drawing - 38/20</name>
+ <source>38/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff5e6</frame-color>
+ <fill-color>#fff5e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvntm.mask - 39/0</name>
+ <source>39/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff5e6</frame-color>
+ <fill-color>#fff5e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvntm.maskAdd - 38/21</name>
+ <source>38/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fff5e6</frame-color>
+ <fill-color>#fff5e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>chvntm.maskDrop - 38/22</name>
+ <source>38/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cldntm.drawing - 11/20</name>
+ <source>11/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cldntm.mask - 11/0</name>
+ <source>11/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvom.drawing - 45/20</name>
+ <source>45/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvom.mask - 46/0</name>
+ <source>46/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvom.maskAdd - 45/21</name>
+ <source>45/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clvom.maskDrop - 45/22</name>
+ <source>45/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cp1m.drawing - 33/44</name>
+ <source>33/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cp1m.mask - 28/0</name>
+ <source>28/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cp1m.maskAdd - 33/43</name>
+ <source>33/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cp1m.waffleDrop - 33/24</name>
+ <source>33/24@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cp1m.maskDrop - 33/42</name>
+ <source>33/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cli1m.drawing - 115/44</name>
+ <source>115/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cli1m.mask - 56/0</name>
+ <source>56/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cli1m.maskAdd - 115/43</name>
+ <source>115/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cli1m.maskDrop - 115/42</name>
+ <source>115/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clicm1.drawing - 106/44</name>
+ <source>106/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clicm1.mask - 43/0</name>
+ <source>43/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clicm1.maskAdd - 106/43</name>
+ <source>106/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>clicm1.maskDrop - 106/42</name>
+ <source>106/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm1.drawing - 62/20</name>
+ <source>62/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm1.mask - 36/0</name>
+ <source>36/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm1.maskAdd - 62/21</name>
+ <source>62/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm1.maskDrop - 62/22</name>
+ <source>62/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm1.waffleDrop - 62/24</name>
+ <source>62/24@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam.drawing - 105/20</name>
+ <source>105/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam.mask - 40/0</name>
+ <source>40/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam.maskAdd - 105/21</name>
+ <source>105/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam.maskDrop - 105/22</name>
+ <source>105/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm2.drawing - 105/44</name>
+ <source>105/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm2.mask - 41/0</name>
+ <source>41/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm2.maskAdd - 105/43</name>
+ <source>105/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm2.maskDrop - 105/42</name>
+ <source>105/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm2.waffleDrop - 105/52</name>
+ <source>105/52@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam2.drawing - 108/20</name>
+ <source>108/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam2.mask - 44/0</name>
+ <source>44/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam2.maskAdd - 108/21</name>
+ <source>108/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam2.maskDrop - 108/22</name>
+ <source>108/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm3.drawing - 107/20</name>
+ <source>107/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm3.mask - 34/0</name>
+ <source>34/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm3.maskAdd - 107/21</name>
+ <source>107/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm3.maskDrop - 107/22</name>
+ <source>107/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#5e00e6</frame-color>
+ <fill-color>#5e00e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm3.waffleDrop - 107/24</name>
+ <source>107/24@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnpc.drawing - 44/20</name>
+ <source>44/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C40</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnpc.mask - 49/0</name>
+ <source>49/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnpc.maskAdd - 44/43</name>
+ <source>44/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnpc.maskDrop - 44/42</name>
+ <source>44/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam3.drawing - 112/20</name>
+ <source>112/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam3.mask - 50/0</name>
+ <source>50/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam3.maskAdd - 112/21</name>
+ <source>112/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#268c6b</frame-color>
+ <fill-color>#268c6b</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam3.maskDrop - 112/22</name>
+ <source>112/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cnsm.mask - 22/0</name>
+ <source>22/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpdm.drawing - 104/44</name>
+ <source>104/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpdm.mask - 37/0</name>
+ <source>37/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpdm.maskAdd - 104/43</name>
+ <source>104/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpdm.maskDrop - 104/42</name>
+ <source>104/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpmm.drawing - 91/44</name>
+ <source>91/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpbo.mask - 99/0</name>
+ <source>99/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm4.mask - 51/0</name>
+ <source>51/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm4.maskAdd - 112/43</name>
+ <source>112/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C11</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm4.maskDrop - 112/42</name>
+ <source>112/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm4.waffleDrop - 112/4</name>
+ <source>112/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam4.drawing - 117/20</name>
+ <source>117/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam4.mask - 58/0</name>
+ <source>58/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam4.maskAdd - 117/21</name>
+ <source>117/21@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cviam4.maskDrop - 117/22</name>
+ <source>117/22@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C13</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm5.mask - 59/0</name>
+ <source>59/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>I1</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cmm5.waffleDrop - 117/4</name>
+ <source>117/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>target.drawing - 76/44</name>
+ <source>76/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cctm1.drawing - 101/44</name>
+ <source>101/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C17</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cctm1.mask - 35/0</name>
+ <source>35/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cctm1.maskAdd - 101/43</name>
+ <source>101/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cctm1.maskDrop - 101/42</name>
+ <source>101/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>crpm.drawing - 53/44</name>
+ <source>53/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>crpm.mask - 96/0</name>
+ <source>96/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C14</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>crpm.maskAdd - 53/43</name>
+ <source>53/43@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C3</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>crpm.maskDrop - 53/42</name>
+ <source>53/42@1</source>
+ </properties>
+ <properties>
+ <frame-color>#e61f0d</frame-color>
+ <fill-color>#e61f0d</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C48</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>ccu1m.mask - 93/0</name>
+ <source>93/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C41</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cpmm2.mask - 94/0</name>
+ <source>94/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ccccd9</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cubm.mask - 100/0</name>
+ <source>100/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>cbump.mask - 101/0</name>
+ <source>101/0@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00bfff</frame-color>
+ <fill-color>#00bfff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>overlap.drawing - 90/20</name>
+ <source>90/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff7f50</frame-color>
+ <fill-color>#ff7f50</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>overlap.boundary - 90/4</name>
+ <source>90/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.lowTapDensity - 81/14</name>
+ <source>81/14@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.notCritSide - 81/15</name>
+ <source>81/15@1</source>
+ </properties>
+ <properties>
+ <frame-color>#adff2f</frame-color>
+ <fill-color>#adff2f</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C2</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.injection - 81/17</name>
+ <source>81/17@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bebed8</frame-color>
+ <fill-color>#bebed8</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C2</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.rfdiode - 81/125</name>
+ <source>81/125@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.seal - 81/1</name>
+ <source>81/1@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9e6ff</frame-color>
+ <fill-color>#d9e6ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.core - 81/2</name>
+ <source>81/2@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.frame - 81/3</name>
+ <source>81/3@1</source>
+ </properties>
+ <properties>
+ <frame-color>#d9cc00</frame-color>
+ <fill-color>#d9cc00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.esd - 81/19</name>
+ <source>81/19@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.dieCut - 81/11</name>
+ <source>81/11@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ff00</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.moduleCut - 81/10</name>
+ <source>81/10@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffff</frame-color>
+ <fill-color>#00ffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.frameRect - 81/12</name>
+ <source>81/12@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#ccccd9</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C23</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.substrateCut - 81/53</name>
+ <source>81/53@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.diode - 81/23</name>
+ <source>81/23@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#ff00ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.standardc - 81/4</name>
+ <source>81/4@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C5</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.deadZon - 81/50</name>
+ <source>81/50@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff8000</frame-color>
+ <fill-color>#ff8000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C5</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.critCorner - 81/51</name>
+ <source>81/51@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C5</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.critSid - 81/52</name>
+ <source>81/52@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#c8ffc8</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.opcDrop - 81/54</name>
+ <source>81/54@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00bfff</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C1</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.waffleWindow - 81/13</name>
+ <source>81/13@1</source>
+ </properties>
+ <properties>
+ <frame-color>#daa520</frame-color>
+ <fill-color>#daa520</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.extendedDrain - 81/57</name>
+ <source>81/57@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffbff2</frame-color>
+ <fill-color>#ffbff2</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.lvNative - 81/60</name>
+ <source>81/60@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.photo - 81/81</name>
+ <source>81/81@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff00ff</frame-color>
+ <fill-color>#00ff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.etest - 81/101</name>
+ <source>81/101@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.hvnwell - 81/63</name>
+ <source>81/63@1</source>
+ </properties>
+ <properties>
+ <frame-color>#9900e6</frame-color>
+ <fill-color>#9900e6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.rdlprobepad - 81/27</name>
+ <source>81/27@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00bfff</frame-color>
+ <fill-color>#00bfff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.sigPadDiff - 81/6</name>
+ <source>81/6@1</source>
+ </properties>
+ <properties>
+ <frame-color>#c8ffc8</frame-color>
+ <fill-color>#c8ffc8</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.sigPadWell - 81/7</name>
+ <source>81/7@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff7f50</frame-color>
+ <fill-color>#ff7f50</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.sigPadMetNtr - 81/8</name>
+ <source>81/8@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff6464</frame-color>
+ <fill-color>#ff6464</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C7</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>3</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>areaid.analog - 81/79</name>
+ <source>81/79@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>prune.drawing - 84/44</name>
+ <source>84/44@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C0</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>padCenter.drawing - 81/20</name>
+ <source>81/20@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa1 - 68/88</name>
+ <source>68/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa1 - 69/88</name>
+ <source>69/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa1 - 70/88</name>
+ <source>70/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa1 - 71/88</name>
+ <source>71/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#8c8ca6</frame-color>
+ <fill-color>#8c8ca6</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa1 - 72/88</name>
+ <source>72/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffe7</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa2 - 68/89</name>
+ <source>68/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffe7</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa2 - 69/89</name>
+ <source>69/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffe7</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa2 - 70/89</name>
+ <source>70/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffe7</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa2 - 71/89</name>
+ <source>71/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00ffe7</frame-color>
+ <fill-color>#00ffe7</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa2 - 72/89</name>
+ <source>72/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa3 - 68/90</name>
+ <source>68/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa3 - 69/90</name>
+ <source>69/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa3 - 70/90</name>
+ <source>70/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa3 - 71/90</name>
+ <source>71/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffcc</frame-color>
+ <fill-color>#ffffcc</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa3 - 72/90</name>
+ <source>72/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#802626</frame-color>
+ <fill-color>#802626</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa4 - 68/91</name>
+ <source>68/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#802626</frame-color>
+ <fill-color>#802626</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa4 - 69/91</name>
+ <source>69/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#802626</frame-color>
+ <fill-color>#802626</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa4 - 70/91</name>
+ <source>70/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#802626</frame-color>
+ <fill-color>#802626</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa4 - 71/91</name>
+ <source>71/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#802626</frame-color>
+ <fill-color>#802626</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa4 - 72/91</name>
+ <source>72/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa5 - 68/92</name>
+ <source>68/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa5 - 69/92</name>
+ <source>69/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa5 - 70/92</name>
+ <source>70/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa5 - 71/92</name>
+ <source>71/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#333399</frame-color>
+ <fill-color>#333399</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa5 - 72/92</name>
+ <source>72/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fa8072</frame-color>
+ <fill-color>#fa8072</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C7</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met1.psa6 - 68/93</name>
+ <source>68/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fa8072</frame-color>
+ <fill-color>#fa8072</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C38</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met2.psa6 - 69/93</name>
+ <source>69/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fa8072</frame-color>
+ <fill-color>#fa8072</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C50</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met3.psa6 - 70/93</name>
+ <source>70/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fa8072</frame-color>
+ <fill-color>#fa8072</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C15</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met4.psa6 - 71/93</name>
+ <source>71/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#fa8072</frame-color>
+ <fill-color>#fa8072</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C43</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>met5.psa6 - 72/93</name>
+ <source>72/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ff0000</frame-color>
+ <fill-color>#ff0000</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa1 - 74/88</name>
+ <source>74/88@1</source>
+ </properties>
+ <properties>
+ <frame-color>#0000ff</frame-color>
+ <fill-color>#0000ff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa2 - 74/89</name>
+ <source>74/89@1</source>
+ </properties>
+ <properties>
+ <frame-color>#00cc66</frame-color>
+ <fill-color>#00cc66</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa3 - 74/90</name>
+ <source>74/90@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffffff</frame-color>
+ <fill-color>#ffffff</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa4 - 74/91</name>
+ <source>74/91@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffff00</frame-color>
+ <fill-color>#ffff00</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa5 - 74/92</name>
+ <source>74/92@1</source>
+ </properties>
+ <properties>
+ <frame-color>#bf4026</frame-color>
+ <fill-color>#bf4026</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C10</dither-pattern>
+ <line-style>C0</line-style>
+ <valid>true</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>rdl.psa6 - 74/93</name>
+ <source>74/93@1</source>
+ </properties>
+ <properties>
+ <frame-color>#ffe6bf</frame-color>
+ <fill-color>#ffe6bf</fill-color>
+ <frame-brightness>0</frame-brightness>
+ <fill-brightness>0</fill-brightness>
+ <dither-pattern>C21</dither-pattern>
+ <line-style>C1</line-style>
+ <valid>false</valid>
+ <visible>true</visible>
+ <transparent>false</transparent>
+ <width>1</width>
+ <marked>false</marked>
+ <xfill>false</xfill>
+ <animation>0</animation>
+ <name>blanking.drawing - 124/40</name>
+ <source>124/40@1</source>
+ </properties>
+ <name/>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>1</order>
+ <name>blank</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ <line>****************</line>
+ </pattern>
+ <order>2</order>
+ <name>solid</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ </pattern>
+ <order>3</order>
+ <name>dots</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>****************</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>****************</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>****************</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>****************</line>
+ </pattern>
+ <order>4</order>
+ <name>hLine</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ <line>..*...*...*...*.</line>
+ </pattern>
+ <order>5</order>
+ <name>vLine</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ </pattern>
+ <order>6</order>
+ <name>cross</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****************</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****************</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****************</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****************</line>
+ </pattern>
+ <order>7</order>
+ <name>grid</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ </pattern>
+ <order>8</order>
+ <name>slash</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*...*...*...*...</line>
+ <line>.*...*...*...*..</line>
+ <line>..*...*...*...*.</line>
+ <line>...*...*...*...*</line>
+ <line>*...*...*...*...</line>
+ <line>.*...*...*...*..</line>
+ <line>..*...*...*...*.</line>
+ <line>...*...*...*...*</line>
+ <line>*...*...*...*...</line>
+ <line>.*...*...*...*..</line>
+ <line>..*...*...*...*.</line>
+ <line>...*...*...*...*</line>
+ <line>*...*...*...*...</line>
+ <line>.*...*...*...*..</line>
+ <line>..*...*...*...*.</line>
+ <line>...*...*...*...*</line>
+ </pattern>
+ <order>9</order>
+ <name>backSlash</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>**......**......</line>
+ <line>..*.......*.....</line>
+ <line>...**......**...</line>
+ <line>.....*.......*..</line>
+ <line>......**......**</line>
+ <line>*.......*.......</line>
+ <line>.**......**.....</line>
+ <line>...*.......*....</line>
+ <line>....**......**..</line>
+ <line>......*.......*.</line>
+ <line>*......**......*</line>
+ <line>.*.......*......</line>
+ <line>..**......**....</line>
+ <line>....*.......*...</line>
+ <line>.....**......**.</line>
+ <line>.......*.......*</line>
+ </pattern>
+ <order>10</order>
+ <name>hZigZag</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*....*....*.....</line>
+ <line>*.....*....*....</line>
+ <line>.*....*.....*...</line>
+ <line>..*....*....*...</line>
+ <line>..*.....*....*..</line>
+ <line>...*....*.....*.</line>
+ <line>....*....*....*.</line>
+ <line>....*.....*....*</line>
+ <line>*....*....*.....</line>
+ <line>*.....*....*....</line>
+ <line>.*....*.....*...</line>
+ <line>..*....*....*...</line>
+ <line>..*.....*....*..</line>
+ <line>...*....*.....*.</line>
+ <line>....*....*....*.</line>
+ <line>....*.....*....*</line>
+ </pattern>
+ <order>11</order>
+ <name>vZigZag</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>...*****...*****</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****...*****...*</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>...*****...*****</line>
+ <line>...*...*...*...*</line>
+ <line>...*...*...*...*</line>
+ <line>****...*****...*</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>12</order>
+ <name>hCurb</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>..****....****..</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..****....****..</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>..****....****..</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..****....****..</line>
+ </pattern>
+ <order>13</order>
+ <name>vCurb</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>****************</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>****************</line>
+ <line>......*.......*.</line>
+ <line>......*.......*.</line>
+ <line>......*.......*.</line>
+ <line>****************</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>****************</line>
+ <line>......*.......*.</line>
+ <line>......*.......*.</line>
+ <line>......*.......*.</line>
+ </pattern>
+ <order>14</order>
+ <name>brick</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>*****...*****...</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>..*.......*.....</line>
+ <line>................</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>...*****...*****</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ <line>.....*.......*..</line>
+ </pattern>
+ <order>15</order>
+ <name>dagger</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>..*.............</line>
+ <line>..*.............</line>
+ <line>..*.............</line>
+ <line>*****...........</line>
+ <line>..*.............</line>
+ <line>..*.............</line>
+ <line>..*.............</line>
+ <line>................</line>
+ <line>.............*..</line>
+ <line>.............*..</line>
+ <line>.............*..</line>
+ <line>...........*****</line>
+ <line>.............*..</line>
+ <line>.............*..</line>
+ <line>.............*..</line>
+ </pattern>
+ <order>16</order>
+ <name>sparseDagger</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>..........*.....</line>
+ <line>..........*.....</line>
+ <line>..........*.....</line>
+ <line>........*****...</line>
+ <line>..........*.....</line>
+ <line>..........*.....</line>
+ <line>..........*.....</line>
+ <line>................</line>
+ <line>.....*..........</line>
+ <line>.....*..........</line>
+ <line>.....*..........</line>
+ <line>...*****........</line>
+ <line>.....*..........</line>
+ <line>.....*..........</line>
+ <line>.....*..........</line>
+ </pattern>
+ <order>17</order>
+ <name>sparseDagger2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>....*...........</line>
+ <line>...*.*..........</line>
+ <line>..*...*.........</line>
+ <line>.*.....*........</line>
+ <line>*********.......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>...........*....</line>
+ <line>..........*.*...</line>
+ <line>.........*...*..</line>
+ <line>........*.....*.</line>
+ <line>.......*********</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>18</order>
+ <name>triangle</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*...*...*...*...</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ </pattern>
+ <order>19</order>
+ <name>x</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>.*.....*.....*..</line>
+ <line>..*...**....*...</line>
+ <line>...*.*.*...*....</line>
+ <line>....*..*..*.....</line>
+ <line>.....*.*.*......</line>
+ <line>......***.......</line>
+ <line>.......*........</line>
+ <line>......***.......</line>
+ <line>.....*.*.*......</line>
+ <line>....*..*..*.....</line>
+ <line>...*...*...*....</line>
+ <line>..*....*....*...</line>
+ <line>.*..*******..*..</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>20</order>
+ <name>Xone</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>.*....**.....*..</line>
+ <line>..*..*..*...*...</line>
+ <line>...**....*.*....</line>
+ <line>....*....**.....</line>
+ <line>.....*...*......</line>
+ <line>......*.*.......</line>
+ <line>.......*........</line>
+ <line>......*.*.......</line>
+ <line>.....*...*......</line>
+ <line>....*.....*.....</line>
+ <line>...**......*....</line>
+ <line>..*.*.......*...</line>
+ <line>.*..******...*..</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>21</order>
+ <name>Xtwo</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>......*.......*.</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>..*.......*.....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>......*.......*.</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>..*.......*.....</line>
+ <line>................</line>
+ </pattern>
+ <order>22</order>
+ <name>spareDots</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>......*.......*.</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>..*.......*.....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>23</order>
+ <name>spareDots21</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>......*.......*.</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>..*.......*.....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>24</order>
+ <name>spareDots22</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ </pattern>
+ <order>25</order>
+ <name>checker</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>....****....****</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ <line>****....****....</line>
+ </pattern>
+ <order>26</order>
+ <name>checker2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.......*........</line>
+ <line>......**........</line>
+ <line>.......*........</line>
+ <line>.......*........</line>
+ <line>.......*........</line>
+ <line>.......*........</line>
+ <line>......***.......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>27</order>
+ <name>one</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.......**.......</line>
+ <line>......*..*......</line>
+ <line>.........*......</line>
+ <line>........*.......</line>
+ <line>.......*........</line>
+ <line>......*.........</line>
+ <line>......****......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>28</order>
+ <name>two</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>......***.......</line>
+ <line>.....*...*......</line>
+ <line>.........*......</line>
+ <line>.......**.......</line>
+ <line>.........*......</line>
+ <line>.....*...*......</line>
+ <line>......***.......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>29</order>
+ <name>three</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.............*..</line>
+ <line>............**..</line>
+ <line>...........*.*..</line>
+ <line>..........*..*..</line>
+ <line>.........******.</line>
+ <line>.............*..</line>
+ <line>.............*..</line>
+ <line>................</line>
+ </pattern>
+ <order>30</order>
+ <name>four</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>......***.......</line>
+ <line>.....*..........</line>
+ <line>.....*..........</line>
+ <line>.....***........</line>
+ <line>........*.......</line>
+ <line>........*.......</line>
+ <line>.....***........</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>31</order>
+ <name>five</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.......***......</line>
+ <line>......*.........</line>
+ <line>......*.........</line>
+ <line>......****......</line>
+ <line>......*...*.....</line>
+ <line>......*...*.....</line>
+ <line>.......***......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>32</order>
+ <name>six</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.....******.....</line>
+ <line>..........*.....</line>
+ <line>.........*......</line>
+ <line>.........*......</line>
+ <line>........*.......</line>
+ <line>........*.......</line>
+ <line>.......*........</line>
+ <line>......*.........</line>
+ <line>.....*..........</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>33</order>
+ <name>seven</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>......***.......</line>
+ <line>.....*...*......</line>
+ <line>.....*...*......</line>
+ <line>......***.......</line>
+ <line>.....*...*......</line>
+ <line>.....*...*......</line>
+ <line>......***.......</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>34</order>
+ <name>eight</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*..............*</line>
+ <line>.*............*.</line>
+ <line>..*..........*..</line>
+ <line>...*........*...</line>
+ <line>....*......*....</line>
+ <line>.....*....*.....</line>
+ <line>......*..*......</line>
+ <line>.......**.......</line>
+ <line>.......**.......</line>
+ <line>......*..*......</line>
+ <line>.....*....*.....</line>
+ <line>....*......*....</line>
+ <line>...*........*...</line>
+ <line>..*..........*..</line>
+ <line>.*............*.</line>
+ <line>*..............*</line>
+ </pattern>
+ <order>35</order>
+ <name>box45</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>.*.*.*.*.*.*.*.*</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ </pattern>
+ <order>36</order>
+ <name>gray50</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ <line>*...*...*...*...</line>
+ <line>................</line>
+ <line>..*...*...*...*.</line>
+ <line>................</line>
+ </pattern>
+ <order>37</order>
+ <name>gray25</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.*.*.*...*.*.*..</line>
+ <line>................</line>
+ <line>...*...*...*...*</line>
+ <line>................</line>
+ <line>.*...*.*.*...*.*</line>
+ <line>................</line>
+ <line>...*...*...*...*</line>
+ <line>................</line>
+ <line>.*.*.*...*.*.*..</line>
+ <line>................</line>
+ <line>...*...*...*...*</line>
+ <line>................</line>
+ <line>.*...*.*.*...*.*</line>
+ <line>................</line>
+ <line>...*...*...*...*</line>
+ <line>................</line>
+ </pattern>
+ <order>38</order>
+ <name>snow</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>..*.......*.....</line>
+ <line>...*.......*....</line>
+ <line>....*.......*...</line>
+ <line>.....*.......*..</line>
+ <line>......*.......*.</line>
+ <line>.......*.......*</line>
+ <line>*.......*.......</line>
+ <line>.*.......*......</line>
+ <line>..*.......*.....</line>
+ <line>...*.......*....</line>
+ <line>....*.......*...</line>
+ <line>.....*.......*..</line>
+ <line>......*.......*.</line>
+ <line>.......*.......*</line>
+ <line>*.......*.......</line>
+ <line>.*.......*......</line>
+ </pattern>
+ <order>39</order>
+ <name>backSlash2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*.....*.*.....*.</line>
+ <line>.*...*...*...*..</line>
+ <line>..*.*.....*.*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*.*.....*.*...</line>
+ <line>.*...*...*...*..</line>
+ <line>*.....*.*.....*.</line>
+ <line>...*...*...*...*</line>
+ <line>*.....*.*.....*.</line>
+ <line>.*...*...*...*..</line>
+ <line>..*.*.....*.*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*.*.....*.*...</line>
+ <line>.*...*...*...*..</line>
+ <line>*.....*.*.....*.</line>
+ <line>...*...*...*...*</line>
+ </pattern>
+ <order>40</order>
+ <name>lattice</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>**..**..**..**..</line>
+ <line>**..**..**..**..</line>
+ <line>..**..**..**..**</line>
+ <line>..**..**..**..**</line>
+ <line>**..**..**..**..</line>
+ <line>**..**..**..**..</line>
+ <line>..**..**..**..**</line>
+ <line>..**..**..**..**</line>
+ <line>**..**..**..**..</line>
+ <line>**..**..**..**..</line>
+ <line>..**..**..**..**</line>
+ <line>..**..**..**..**</line>
+ <line>**..**..**..**..</line>
+ <line>**..**..**..**..</line>
+ <line>..**..**..**..**</line>
+ <line>..**..**..**..**</line>
+ </pattern>
+ <order>41</order>
+ <name>smallChecker</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>....*...........</line>
+ <line>...*.*..........</line>
+ <line>..*...*.........</line>
+ <line>.*.....*........</line>
+ <line>*.......*.......</line>
+ <line>.*.......*......</line>
+ <line>..*.......*.....</line>
+ <line>...*.......*....</line>
+ <line>....*.......*...</line>
+ <line>.....*.......*..</line>
+ <line>......*.......*.</line>
+ <line>.......*.......*</line>
+ <line>........*.....*.</line>
+ <line>.........*...*..</line>
+ <line>..........*.*...</line>
+ <line>...........*....</line>
+ </pattern>
+ <order>42</order>
+ <name>slantBox</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ <line>.*...*...*...*..</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>..*...*...*...*.</line>
+ </pattern>
+ <order>43</order>
+ <name>slash2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>...*.......*....</line>
+ <line>..*.......*.....</line>
+ <line>.*.......*......</line>
+ <line>*.......*.......</line>
+ <line>.......*.......*</line>
+ <line>......*.......*.</line>
+ <line>.....*.......*..</line>
+ <line>....*.......*...</line>
+ <line>...*.......*....</line>
+ <line>..*.......*.....</line>
+ <line>.*.......*......</line>
+ <line>*.......*.......</line>
+ <line>.......*.......*</line>
+ <line>......*.......*.</line>
+ <line>.....*.......*..</line>
+ <line>....*.......*...</line>
+ </pattern>
+ <order>44</order>
+ <name>bigSlash</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>****....****....</line>
+ <line>*..*....*..*....</line>
+ <line>*..*....*..*....</line>
+ <line>****....****....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>****....****....</line>
+ <line>*..*....*..*....</line>
+ <line>*..*....*..*....</line>
+ <line>****....****....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>45</order>
+ <name>boxes</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>..**......**....</line>
+ <line>.*..*....*..*...</line>
+ <line>*....*..*....*..</line>
+ <line>*....*..*....*..</line>
+ <line>.*..*....*..*...</line>
+ <line>..**......**....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>..**......**....</line>
+ <line>.*..*....*..*...</line>
+ <line>*....*..*....*..</line>
+ <line>*....*..*....*..</line>
+ <line>.*..*....*..*...</line>
+ <line>..**......**....</line>
+ <line>................</line>
+ <line>................</line>
+ </pattern>
+ <order>46</order>
+ <name>circles</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.**..**..**..**.</line>
+ <line>...*...*...*...*</line>
+ <line>*...*...*...*...</line>
+ <line>.**..**..**..**.</line>
+ <line>.**..**..**..**.</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>.**..**..**..**.</line>
+ <line>.**..**..**..**.</line>
+ <line>...*...*...*...*</line>
+ <line>*...*...*...*...</line>
+ <line>.**..**..**..**.</line>
+ <line>.**..**..**..**.</line>
+ <line>*...*...*...*...</line>
+ <line>...*...*...*...*</line>
+ <line>.**..**..**..**.</line>
+ </pattern>
+ <order>47</order>
+ <name>zigzag</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>................</line>
+ <line>...*....*....*..</line>
+ <line>................</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>................</line>
+ <line>...*....*....*..</line>
+ <line>................</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>................</line>
+ <line>...*....*....*..</line>
+ <line>................</line>
+ <line>*.*.*.*.*.*.*.*.</line>
+ <line>................</line>
+ <line>...*....*....*..</line>
+ </pattern>
+ <order>48</order>
+ <name>lightMesh</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>...............*</line>
+ <line>..............*.</line>
+ <line>.............*..</line>
+ <line>............*...</line>
+ <line>...........*....</line>
+ <line>..........*.....</line>
+ <line>.........*......</line>
+ <line>........*.......</line>
+ <line>.......*........</line>
+ <line>......*.........</line>
+ <line>.....*..........</line>
+ <line>....*...........</line>
+ <line>...*............</line>
+ <line>..*.............</line>
+ <line>.*..............</line>
+ <line>*...............</line>
+ </pattern>
+ <order>49</order>
+ <name>hugeSlash</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*...............</line>
+ <line>.*..............</line>
+ <line>..*.............</line>
+ <line>...*............</line>
+ <line>....*...........</line>
+ <line>.....*..........</line>
+ <line>......*.........</line>
+ <line>.......*........</line>
+ <line>........*.......</line>
+ <line>.........*......</line>
+ <line>..........*.....</line>
+ <line>...........*....</line>
+ <line>............*...</line>
+ <line>.............*..</line>
+ <line>..............*.</line>
+ <line>...............*</line>
+ </pattern>
+ <order>50</order>
+ <name>hugeSlash2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>*.........*.....</line>
+ <line>.....*..........</line>
+ <line>..*.........*...</line>
+ <line>.......*........</line>
+ <line>....*.........*.</line>
+ <line>.*.......*......</line>
+ <line>......*.........</line>
+ <line>...*.......*....</line>
+ <line>........*.......</line>
+ <line>.....*.......*..</line>
+ <line>*.........*.....</line>
+ <line>.......*........</line>
+ <line>..*.........*...</line>
+ <line>.........*......</line>
+ <line>....*.........*.</line>
+ <line>...........*....</line>
+ </pattern>
+ <order>51</order>
+ <name>curve</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>....*....*....*.</line>
+ <line>..*.............</line>
+ <line>*.......*.......</line>
+ <line>.............*..</line>
+ <line>.......*........</line>
+ <line>............*...</line>
+ <line>.....*..........</line>
+ <line>...*.......*....</line>
+ <line>*...............</line>
+ <line>................</line>
+ <line>.........*......</line>
+ <line>................</line>
+ <line>......*........*</line>
+ <line>...*............</line>
+ <line>*............*..</line>
+ <line>..........*.....</line>
+ </pattern>
+ <order>52</order>
+ <name>curve2</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>...........*....</line>
+ <line>..........*.*...</line>
+ <line>.........*...*..</line>
+ <line>........*.....*.</line>
+ <line>.........*...*..</line>
+ <line>..........*.*...</line>
+ <line>...........*....</line>
+ <line>................</line>
+ <line>................</line>
+ <line>...*............</line>
+ <line>..*.*...........</line>
+ <line>.*...*..........</line>
+ <line>*.....*.........</line>
+ <line>.*...*..........</line>
+ <line>..*.*...........</line>
+ <line>...*............</line>
+ </pattern>
+ <order>53</order>
+ <name>diams</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>...*............</line>
+ <line>..*.*...........</line>
+ <line>.*...*..........</line>
+ <line>*.....*.........</line>
+ <line>.*...*..........</line>
+ <line>..*.*...........</line>
+ <line>...*............</line>
+ </pattern>
+ <order>54</order>
+ <name>sparsediam</name>
+ </custom-dither-pattern>
+ <custom-dither-pattern>
+ <pattern>
+ <line>.......*.......*</line>
+ <line>......*.........</line>
+ <line>.....*..........</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.*..............</line>
+ <line>*...............</line>
+ <line>.......*.......*</line>
+ <line>..............*.</line>
+ <line>.............*..</line>
+ <line>................</line>
+ <line>................</line>
+ <line>................</line>
+ <line>.........*......</line>
+ <line>........*.......</line>
+ </pattern>
+ <order>55</order>
+ <name>rain</name>
+ </custom-dither-pattern>
+ <custom-line-style>
+ <pattern>***</pattern>
+ <order>1</order>
+ <name>solid</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>****..</pattern>
+ <order>2</order>
+ <name>dashed</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>*..</pattern>
+ <order>3</order>
+ <name>dots</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>***..*..</pattern>
+ <order>4</order>
+ <name>dashDot</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>**..</pattern>
+ <order>5</order>
+ <name>shortDash</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>****..**..</pattern>
+ <order>6</order>
+ <name>doubleDash</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>*...</pattern>
+ <order>7</order>
+ <name>hidden</name>
+ </custom-line-style>
+ <custom-line-style>
+ <pattern>***</pattern>
+ <order>8</order>
+ <name>thickLine</name>
+ </custom-line-style>
+</layer-properties>
diff --git a/sky130/sky130.lyt b/sky130/sky130.lyt
new file mode 100644
index 0000000..139f6cc
--- /dev/null
+++ b/sky130/sky130.lyt
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<technology>
+ <name>EFS8A</name>
+ <description>EFS8A 5-metals</description>
+ <layer-properties_file>EFS8A.lyp</layer-properties_file>
+ <add-other-layers>true</add-other-layers>
+ <layer-map>
+'66/15 : PY_SHORT ';
+'72/15 : M5_SHORT ';
+'81/14 : LDID ';
+'122/16 :PWELL_PIN ';
+'64/5 : NWELLLABEL ';
+'64/16 : NWELLPT ';
+'64/59 : PWELLLABEL ';
+'64/20 : NWELL ';
+'64/18 : DNWELL ';
+'65/20 : DIFF ';
+'65/44 : TAP ';
+'125/44 : LVTN ';
+'78/44 : HVTP ';
+'75/20 : HVI ';
+'80/20 : TUNM ';
+'66/20 : POLY ';
+'95/20 : NPC ';
+'94/20 : PSDM ';
+'93/44 : NSDM ';
+'66/44 : LICON1 ';
+'67/20 : LI1 ';
+'67/16 : LI1T ';
+'67/5 : LI1P ';
+'67/44 : MCON ';
+'68/20 : MET1 ';
+'68/16 : MET1T ';
+'68/5 : MET1P ';
+'68/44 : VIA1 ';
+'69/20 : MET2 ';
+'69/16 : MET2T ';
+'69/5 : MET2P ';
+'69/44 : VIA2 ';
+'70/20 : MET3 ';
+'70/16 : MET3T ';
+'70/5 : MET3P ';
+'70/44 : VIA3 ';
+'71/20 : MET4 ';
+'71/16 : MET4T ';
+'71/5 : MET4P ';
+'71/44 : VIA4 ';
+'72/20 : MET5 ';
+'72/16 : MET5T ';
+'72/5 : MET5P ';
+'76/20 : PAD ';
+'76/16 : PADT ';
+'76/5 : PADP ';
+'81/4 : BOUND ';
+'83/44 : TEXT ';
+'18/20 : HVTR ';
+'92/44 : NCM ';
+'86/20 : RPM ';
+'61/20 : NSM ';
+'74/20 : RDL ';
+'74/21 : VHVI ';
+'11/44 : LDNTM ';
+'125/20 : HVNTM ';
+'85/44 : PMM ';
+'82/44 : PNP ';
+'82/64 : CAP ';
+'82/24 : IND ';
+'64/13 : PWRES ';
+'66/13 : POLYRES';
+'65/13 : DIFFRES';
+'81/23 : DIODE ';
+</layer-map>
+ <create-other-layers>true</create-other-layers>
+ <lef-def-import>
+ <read-all-layers>true</read-all-layers>
+ <layer-map/>
+ <produce-net-names>true</produce-net-names>
+ <net-property-name>#1</net-property-name>
+ <produce-cell-outlines>true</produce-cell-outlines>
+ <cell-outline-layer>OUTLINE</cell-outline-layer>
+ <produce-placement-blockages>true</produce-placement-blockages>
+ <placement-blockage-layer>PLACEMENT_BLK</placement-blockage-layer>
+ <produce-via-geometry>true</produce-via-geometry>
+ <via-geometry-suffix/>
+ <via-geometry-datatype>0</via-geometry-datatype>
+ <produce-pins>true</produce-pins>
+ <pins-suffix>.PIN</pins-suffix>
+ <pins-datatype>2</pins-datatype>
+ <produce-obstructions>true</produce-obstructions>
+ <obstructions-suffix>.OBS</obstructions-suffix>
+ <obstructions-datatype>3</obstructions-datatype>
+ <produce-blockages>true</produce-blockages>
+ <blockages-suffix>.BLK</blockages-suffix>
+ <blockages-datatype>4</blockages-datatype>
+ <produce-labels>true</produce-labels>
+ <labels-suffix>.LABEL</labels-suffix>
+ <labels-datatype>1</labels-datatype>
+ <produce-routing>true</produce-routing>
+ <routing-suffix/>
+ <routing-datatype>0</routing-datatype>
+ </lef-def-import>
+ <connectivity>
+ <connection>LI1,LICON1,SRCDRN</connection>
+ <connection>LI1,LICON1,POLY</connection>
+ <connection>MET1,MCON,LI1</connection>
+ <connection>MET1,VIA1,MET2</connection>
+ <connection>MET2,VIA2,MET3</connection>
+ <connection>MET3,VIA3,MET4</connection>
+ <connection>MET4,VIA4,MET5</connection>
+ <connection>LI1,LICON1,NWP</connection>
+ <symbols>SRCDRN='DIFF-POLY'</symbols>
+ <symbols>PTAP='TAP'</symbols>
+ <symbols>NWP='TAP+NWELL'</symbols>
+ <symbols>DIFF='65/20'</symbols>
+ <symbols>POLY='66/20'</symbols>
+ <symbols>LICON1='66/44'</symbols>
+ <symbols>LI1='67/20'</symbols>
+ <symbols>MCON='67/44'</symbols>
+ <symbols>MET1='68/20'</symbols>
+ <symbols>VIA1='68/44'</symbols>
+ <symbols>MET2='69/20'</symbols>
+ <symbols>VIA2='69/44'</symbols>
+ <symbols>MET3='70/20'</symbols>
+ <symbols>VIA3='70/44'</symbols>
+ <symbols>MET4='71/20'</symbols>
+ <symbols>VIA4='71/44'</symbols>
+ <symbols>MET5='72/20'</symbols>
+ </connectivity>
+</technology>
diff --git a/sky130/sky130.magicrc b/sky130/sky130.magicrc
new file mode 100644
index 0000000..feaf6b5
--- /dev/null
+++ b/sky130/sky130.magicrc
@@ -0,0 +1,114 @@
+###
+### Source file sky130.magicrc
+### Process this file with the m4 processor
+###
+puts stdout "Sourcing design .magicrc for technology TECHNAME ..."
+
+# Put grid on 0.005 pitch. This is important, as some commands don't
+# rescale the grid automatically (such as lef read?).
+
+set scalefac [tech lambda]
+if {[lindex $scalefac 1] < 2} {
+ scalegrid 1 2
+}
+
+# drc off
+drc euclidean on
+
+# Allow override of PDK path from environment variable PDKPATH
+if {[catch {set PDKPATH $env(PDKPATH)}]} {
+ set PDKPATH "STAGING_PATH/TECHNAME"
+}
+
+# loading technology
+#ifdef FULLTECH
+tech load $PDKPATH/MAGIC_CURRENT/TECHNAME-F.tech
+#else
+tech load $PDKPATH/MAGIC_CURRENT/TECHNAME.tech
+#endif
+
+# load device generator
+source $PDKPATH/MAGIC_CURRENT/TECHNAME.tcl
+
+# load bind keys (optional)
+# source $PDKPATH/MAGIC_CURRENT/TECHNAME-BindKeys
+
+# set units to lambda grid
+snap lambda
+
+# set sky130 standard power, ground, and substrate names
+set VDD VPWR
+set GND VGND
+set SUB VSUBS
+
+# Allow override of type of magic library views used, "mag" or "maglef",
+# from environment variable MAGTYPE
+
+if {[catch {set MAGTYPE $env(MAGTYPE)}]} {
+ set MAGTYPE maglef
+}
+
+# add path to reference cells
+if {[file isdir ${PDKPATH}/libs.ref/${MAGTYPE}]} {
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_pr_base
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_pr_rf
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_pr_rf2
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_io
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_hd
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_hdll
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_hs
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_hvl
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_lp
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_ls
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_fd_sc_ms
+ addpath ${PDKPATH}/libs.ref/${MAGTYPE}/sky130_osu130
+} else {
+ addpath ${PDKPATH}/libs.ref/sky130_fd_pr_base/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_pr_rf/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_pr_rf2/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_io/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_hd/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_hdll/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_hs/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_hvl/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_lp/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_ls/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_fd_sc_ms/${MAGTYPE}
+ addpath ${PDKPATH}/libs.ref/sky130_osu130/${MAGTYPE}
+}
+
+# add path to GDS cells
+#ifdef FULLTECH
+if {[file isdir ${PDKPATH}/libs.ref/gds}]} {
+ path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_base
+ path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_rf
+ path cell ${PDKPATH}/libs.ref/gds/sky130_fd_pr_rf2
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_io
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_hd
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_hdll
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_hs
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_hvl
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_lp
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_ls
+ path cell +${PDKPATH}/libs.ref/gds/sky130_fd_sc_ms
+ path cell +${PDKPATH}/libs.ref/gds/sky130_osu130
+} else {
+ path cell ${PDKPATH}/libs.ref/sky130_fd_pr_base/gds
+ path cell ${PDKPATH}/libs.ref/sky130_fd_pr_rf/gds
+ path cell ${PDKPATH}/libs.ref/sky130_fd_pr_rf2/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_io/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_hd/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_hdll/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_hs/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_hvl/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_lp/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_ls/gds
+ path cell +${PDKPATH}/libs.ref/sky130_fd_sc_ms/gds
+ path cell +${PDKPATH}/libs.ref/sky130_osu130/gds
+}
+#endif (FULLTECH)
+
+# add path to IP from catalog. This procedure defined in the PDK script.
+catch {magic::query_mylib_ip}
+# add path to local IP from user design space. Defined in the PDK script.
+catch {magic::query_my_projects}
diff --git a/sky130/sky130.par b/sky130/sky130.par
new file mode 100644
index 0000000..afd9190
--- /dev/null
+++ b/sky130/sky130.par
@@ -0,0 +1,108 @@
+# TECHNAME.par --- Parameter file for GrayWolf
+# NOTE: all distance units are in centimicrons unless otherwise stated
+# WARNING: this is NOT tcl syntax! No Comments on end of actual data line.
+# The vast majority of quantities here are not used (read instead from techLEF, etc.)
+
+RULES
+ # values are resistance in ohms/sq and capacitance in fF/um^2
+ # TODO: properly pick directions
+ layer metal1 0.105 0.0001 horizontal
+ layer metal2 0.105 0.0001 vertical
+ layer metal3 0.105 0.0001 horizontal
+#ifdef METAL5
+ layer metal4 0.105 0.0001 vertical
+ layer metal5 0.105 0.0001 horizontal
+#endif
+
+ via via12 metal1 metal2
+ via via23 metal2 metal3
+#ifdef METAL5
+ via via34 metal3 metal4
+ via via45 metal4 metal5
+#endif
+
+ # 0.5 um
+ width metal1 50
+ width metal2 60
+ # 0.6 um
+ width metal3 60
+#ifdef METAL5
+ width metal4 60
+ width metal5 60
+#endif
+
+ # TODO verify these two numbers
+ width via12 50
+ width via23 50
+#ifdef METAL5
+ width via34 50
+ width via45 50
+#endif
+
+ # Set spacing = track pitch - width, so that GrayWolf places pins
+ # on the right pitch.
+ # Pitches are (in um):
+ # metal1 = 200, metal2 = 160, metal3 = 200, metal4 = 320
+## pitch m1: 1.3um m2: 1.4um m3: 1.3um
+## width m1: 0.5um m2: 0.6um m3: 0.6um
+## space 0.8 0.8 0.7 (pitch calc)
+## fab-space 0.45 0.5 0.6
+
+ spacing metal1 metal1 80
+ spacing metal2 metal2 80
+ spacing metal3 metal3 80
+#ifdef METAL5
+ spacing metal4 metal4 80
+ spacing metal5 metal5 80
+#endif
+
+ # (WAS:) Stacked vias allowed
+ # spacing via12 via23 0
+
+ # To disable Stacked?: give non-zero spacing (centimicrons = 10 nanometer = 1/100 of micron)
+ # TODO need real value here:
+ spacing via12 via23 0
+#ifdef METAL5
+ spacing via23 via34 0
+ spacing via34 via45 0
+#endif
+
+ # .2um .15um
+ overhang via12 metal1 20
+ overhang via12 metal2 15
+
+ overhang via23 metal2 20
+ overhang via23 metal3 15
+
+#ifdef METAL5
+ overhang via34 metal3 14
+ overhang via34 metal4 16
+ overhang via45 metal4 14
+ overhang via45 metal5 16
+#endif
+ENDRULES
+
+*vertical_wire_weight : 1.0
+*vertical_path_weight : 1.0
+*padspacing : variable
+*rowSep : 0.0 0
+# min pitch of m1,m2,m3 (FIXME):
+*track.pitch : 130
+*graphics.wait : off
+*last_chance.wait : off
+*random.seed : 12345
+# TODO: proper track.pitch number above, plus feedThruWidth below
+
+TWMC*chip.aspect.ratio : 1.0
+
+# FIXME: Change width to width of minimum fill cell
+TWSC*feedThruWidth : 280 layer 1
+TWSC*do.global.route : on
+TWSC*ignore_feeds : true
+TWSC*call_row_evener : true
+TWSC*even_rows_maximally : true
+# TWSC*no.graphics : on
+
+GENR*row_to_tile_spacing: 1
+# GENR*numrows : 6
+GENR*flip_alternate_rows : 1
diff --git a/sky130/sky130.sh b/sky130/sky130.sh
new file mode 100644
index 0000000..9d8e6ac
--- /dev/null
+++ b/sky130/sky130.sh
@@ -0,0 +1,93 @@
+#!/bin/tcsh
+#---------------------------------------------------------------
+# Shell script setting up all variables used by the qflow scripts
+# for this project
+#---------------------------------------------------------------
+
+# The LEF file containing standard cell macros
+
+#ifdef EF_FORMAT
+set leffile=STAGING_PATH/TECHNAME/libs.ref/lef/LIBRARY/LIBRARY.lef
+#else (!EF_FORMAT)
+set leffile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/lef/LIBRARY.lef
+#endif (!EF_FORMAT)
+
+# The SPICE netlist containing subcell definitions for all the standard cells
+#ifdef EF_FORMAT
+set spicefile=STAGING_PATH/TECHNAME/libs.ref/spi/LIBRARY/LIBRARY.spi
+#else (!EF_FORMAT)
+set spicefile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/spice/LIBRARY.spi
+#endif (!EF_FORMAT)
+
+# The liberty format file containing standard cell timing and function information
+#ifdef EF_FORMAT
+set libertyfile=STAGING_PATH/TECHNAME/libs.ref/lib/LIBRARY/LIBRARY__ff_n40C_1v95.lib
+#else (!EF_FORMAT)
+set libertyfile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/lib/LIBRARY__ff_n40C_1v95.lib
+#endif (!EF_FORMAT)
+
+# If there is another LEF file containing technology information
+# that is separate from the file containing standard cell macros,
+# set this. Otherwise, leave it defined as an empty string.
+
+#ifdef METAL5
+#ifdef EF_FORMAT
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/techLEF/LIBRARY/LIBRARY_tech.lef
+#else (!EF_FORMAT)
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/techlef/LIBRARY_tech.lef
+#endif (!EF_FORMAT)
+#else
+# NOTE: There is no technology LEF file for the 3-metal stack!
+#endif
+
+# All cells below should be the lowest output drive strength value,
+# if the standard cell set has multiple cells with different drive
+# strengths. Comment out any cells that do not exist.
+
+set bufcell=LIBRARY__buf_1 ;# Minimum drive strength buffer cell
+set bufpin_in=A ;# Name of input port to buffer cell
+set bufpin_out=X ;# Name of output port to buffer cell
+set clkbufcell=LIBRARY__clkbuf_1 ;# Minimum drive strength buffer cell
+set clkbufpin_in=A ;# Name of input port to buffer cell
+set clkbufpin_out=X ;# Name of output port to buffer cell
+
+set fillcell=LIBRARY__fill_ ;# Spacer (filler) cell (prefix, if more than one)
+set decapcell=LIBRARY__decap_ ;# Decap (filler) cell (prefix, if more than one)
+set antennacell=LIBRARY__diode_ ;# Antenna (filler) cell (prefix, if more than one)
+set antennapin_in=vpb ;# Antenna cell input connection
+set bodytiecell=LIBRARY__tapvpwrvgnd_ ;# Body tie (filler) cell (prefix, if more than one)
+
+# yosys tries to eliminate use of these; depends on source .v
+set tiehi="LIBRARY__conb_1" ;# Cell to connect to power, if one exists
+set tiehipin_out="HI" ;# Output pin name of tiehi cell, if it exists
+set tielo="LIBRARY__conb_1" ;# Cell to connect to ground, if one exists
+set tielopin_out="LO" ;# Output pin name of tielo cell, if it exists
+
+set gndnet="vgnd,vnb" ;# Name used for ground pins and taps in standard cells
+set vddnet="vpwr,vpb" ;# Name used for power pins and taps in standard cells
+
+set separator="" ;# Separator between gate names and drive strengths
+set techfile=STAGING_PATH/TECHNAME/MAGIC_CURRENT/TECHNAME.tech ;# magic techfile
+set magicrc=STAGING_PATH/TECHNAME/MAGIC_CURRENT/TECHNAME.magicrc ;# magic startup script
+set magic_display="XR" ;# magic display, defeat display query and OGL preference
+set netgen_setup=STAGING_PATH/TECHNAME/libs.tech/netgen/TECHNAME_setup.tcl ;# netgen setup file for LVS
+#ifdef EF_FORMAT
+set gdsfile=STAGING_PATH/TECHNAME/libs.ref/gds/LIBRARY/LIBRARY.gds ;# GDS database of standard cells
+set verilogfile=STAGING_PATH/TECHNAME/libs.ref/verilog/LIBRARY/LIBRARY.v ;# Verilog models of standard cells
+#else (!EF_FORMAT)
+set gdsfile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/gds/LIBRARY.gds ;# GDS database of standard cells
+set verilogfile=STAGING_PATH/TECHNAME/libs.ref/LIBRARY/verilog/LIBRARY.v ;# Verilog models of standard cells
+#endif (!EF_FORMAT)
+
+# Set a conditional default in the project_vars.sh file for this process
+set postproc_options="-anchors"
+#ifdef METAL5
+# Normally one does not want to use the top metal for signal routing
+set route_layers = 5
+#else
+set route_layers = 3
+#endif
+set fill_ratios="0,70,10,20"
+set fanout_options="-l 200 -c 20"
+set addspacers_options="-stripe 2.5 50.0 PG"
+set xspice_options="-io_time=500p -time=50p -idelay=5p -odelay=50p -cload=250f"
diff --git a/sky130/sky130.tcl b/sky130/sky130.tcl
new file mode 100644
index 0000000..684aee5
--- /dev/null
+++ b/sky130/sky130.tcl
@@ -0,0 +1,5596 @@
+###
+### Source file sky130.tcl
+### Process this file with the preprocessor script
+###
+#-----------------------------------------------------
+# Magic/TCL design kit for SKYWATER TECHNAME
+#-----------------------------------------------------
+# Tim Edwards
+# Revision 0 PRE-ALPHA 3/21/2019
+#-----------------------------------------------------
+
+set TECHPATH STAGING_PATH
+if [catch {set PDKPATH}] {set PDKPATH ${TECHPATH}/TECHNAME}
+set PDKNAME TECHNAME
+# "sky130" is the namespace used for all devices
+set PDKNAMESPACE sky130
+puts stdout "Loading TECHNAME Device Generator Menu ..."
+
+# Initialize toolkit menus to the wrapper window
+
+global Opts
+namespace eval sky130 {}
+
+# Set the window callback
+if [catch {set Opts(callback)}] {set Opts(callback) ""}
+set Opts(callback) [subst {sky130::addtechmenu \$framename; $Opts(callback)}]
+
+# if {![info exists Opts(cmdentry)]} {set Opts(cmdentry) 1}
+
+# Set options specific to this PDK
+set Opts(hidelocked) 1
+set Opts(hidespecial) 1
+
+# Create new "tool" proc that doesn't have the netlist tool.
+proc magic::nexttool {} {
+ global Opts
+
+ # Don't attempt to switch tools while a selection drag is active
+ if {$Opts(motion) == {}} {
+ switch $Opts(tool) {
+ box { magic::tool wiring }
+ wiring { magic::tool pick }
+ default { magic::tool box }
+ }
+ }
+}
+
+# This shoule be part of sitedef. . .
+macro space magic::nexttool
+
+# Wrap the closewrapper procedure so that closing the last
+# window is equivalent to quitting.
+if {[info commands closewrapper] == "closewrapper"} {
+ rename closewrapper closewrapperonly
+ proc closewrapper { framename } {
+ if {[llength [windownames all]] <= 1} {
+ magic::quit
+ } else {
+ closewrapperonly $framename
+ }
+ }
+}
+
+# Remove maze router layers from the toolbar by locking them
+tech lock fence,magnet,rotate
+
+namespace eval sky130 {
+ namespace path {::tcl::mathop ::tcl::mathfunc}
+
+ set ruleset [dict create]
+
+ # Process DRC rules (magic style)
+
+ dict set ruleset poly_surround 0.08 ;# Poly surrounds contact
+ dict set ruleset diff_surround 0.06 ;# Diffusion surrounds contact
+ dict set ruleset gate_to_diffcont 0.145 ;# Gate to diffusion contact center
+ dict set ruleset gate_to_polycont 0.275 ;# Gate to poly contact center
+ dict set ruleset gate_extension 0.13 ;# Poly extension beyond gate
+ dict set ruleset diff_extension 0.29 ;# Diffusion extension beyond gate
+ dict set ruleset contact_size 0.17 ;# Minimum contact size
+ dict set ruleset via_size 0.17 ;# Minimum via size
+ dict set ruleset metal_surround 0.08 ;# Local interconnect overlaps contact
+ dict set ruleset sub_surround 0.18 ;# Sub/well surrounds diffusion
+ dict set ruleset diff_spacing 0.28 ;# Diffusion spacing rule
+ dict set ruleset poly_spacing 0.21 ;# Poly spacing rule
+ dict set ruleset diff_poly_space 0.075 ;# Diffusion to poly spacing rule
+ dict set ruleset diff_gate_space 0.20 ;# Diffusion to gate poly spacing rule
+ dict set ruleset metal_spacing 0.23 ;# Local interconnect spacing rule
+ dict set ruleset mmetal_spacing 0.14 ;# Metal spacing rule (above local interconnect)
+ dict set ruleset res_to_cont 0.20 ;# resistor to contact center
+ dict set ruleset res_diff_space 0.20 ;# resistor to guard ring
+}
+
+#-----------------------------------------------------
+# magic::addtechmenu
+#-----------------------------------------------------
+
+proc sky130::addtechmenu {framename} {
+ global Winopts Opts
+
+ # Check for difference between magic 8.1.125 and earlier, and 8.1.126 and later
+ if {[catch {${framename}.titlebar cget -height}]} {
+ set layoutframe ${framename}.pane.top
+ } else {
+ set layoutframe ${framename}
+ }
+
+ # List of devices is long. Divide into two sections for active and passive deivces
+ magic::add_toolkit_menu $layoutframe "Devices 1" pdk1
+
+ magic::add_toolkit_command $layoutframe "nmos (MOSFET)" \
+ "magic::gencell sky130::nshort" pdk1
+ magic::add_toolkit_command $layoutframe "pmos (MOSFET)" \
+ "magic::gencell sky130::pshort" pdk1
+
+ magic::add_toolkit_separator $layoutframe pdk1
+ magic::add_toolkit_command $layoutframe "n-diode" \
+ "magic::gencell sky130::ndiode" pdk1
+ magic::add_toolkit_command $layoutframe "p-diode" \
+ "magic::gencell sky130::pdiode" pdk1
+
+ magic::add_toolkit_separator $layoutframe pdk1
+ magic::add_toolkit_command $layoutframe "MOS varactor" \
+ "magic::gencell sky130::xcnwvc" pdk1
+ magic::add_toolkit_separator $layoutframe pdk1
+
+ magic::add_toolkit_command $layoutframe "NPN 1x1" \
+ "magic::gencell sky130::sky130_fd_pr_rf_npn_1x1" pdk1
+ magic::add_toolkit_command $layoutframe "NPN 1x2" \
+ "magic::gencell sky130::sky130_fd_pr_rf_npn_1x2" pdk1
+ magic::add_toolkit_command $layoutframe "PNP 5x" \
+ "magic::gencell sky130::sky130_fd_pr_rf_pnp5x" pdk1
+
+ magic::add_toolkit_separator $layoutframe pdk1
+
+ magic::add_toolkit_command $layoutframe "balun" \
+ "magic::gencell sky130::balun" pdk1
+ magic::add_toolkit_command $layoutframe "inductor 011" \
+ "magic::gencell sky130::xind4_011" pdk1
+ magic::add_toolkit_command $layoutframe "inductor 02" \
+ "magic::gencell sky130::xind4_02" pdk1
+
+ magic::add_toolkit_separator $layoutframe pdk1
+
+ magic::add_toolkit_command $layoutframe "substrate contact (1.8V)" \
+ "sky130::subconn_draw" pdk1
+ magic::add_toolkit_command $layoutframe "substrate contact (5.0V)" \
+ "sky130::mvsubconn_draw" pdk1
+ magic::add_toolkit_command $layoutframe "deep n-well region" \
+ "sky130::deep_nwell_draw" pdk1
+ magic::add_toolkit_command $layoutframe "mcon" \
+ "sky130::mcon_draw" pdk1
+ magic::add_toolkit_command $layoutframe "via1" \
+ "sky130::via1_draw" pdk1
+ magic::add_toolkit_command $layoutframe "via2" \
+ "sky130::via2_draw" pdk1
+#ifdef METAL5
+ magic::add_toolkit_command $layoutframe "via3" \
+ "sky130::via3_draw" pdk1
+ magic::add_toolkit_command $layoutframe "via4" \
+ "sky130::via4_draw" pdk1
+#endif (METAL5)
+
+
+ magic::add_toolkit_menu $layoutframe "Devices 2" pdk2
+
+ magic::add_toolkit_command $layoutframe "mrdn (1.8V) - 120 Ohm/sq" \
+ "magic::gencell sky130::mrdn" pdk2
+ magic::add_toolkit_command $layoutframe "mrdp (1.8V) - 197 Ohm/sq" \
+ "magic::gencell sky130::mrdp" pdk2
+ magic::add_toolkit_command $layoutframe "mrdn_hv (5.0V) - 114 Ohm/sq" \
+ "magic::gencell sky130::mrdn_hv" pdk2
+ magic::add_toolkit_command $layoutframe "mrdp_hv (5.0V) - 191 Ohm/sq" \
+ "magic::gencell sky130::mrdp_hv" pdk2
+
+ magic::add_toolkit_command $layoutframe "mrp1 - 48.2 Ohm/sq" \
+ "magic::gencell sky130::mrp1" pdk2
+ magic::add_toolkit_command $layoutframe "xhrpoly - 319.8 Ohm/sq" \
+ "magic::gencell sky130::xhrpoly" pdk2
+ magic::add_toolkit_command $layoutframe "uhrpoly - 2000 Ohm/sq" \
+ "magic::gencell sky130::uhrpoly" pdk2
+ magic::add_toolkit_command $layoutframe "xpwres - 3050 Ohm/sq" \
+ "magic::gencell sky130::xpwres" pdk2
+ magic::add_toolkit_separator $layoutframe pdk2
+
+ magic::add_toolkit_command $layoutframe "mrl1 - 12.2 Ohm/sq" \
+ "magic::gencell sky130::mrl1" pdk2
+ magic::add_toolkit_command $layoutframe "mrm1 - 125 mOhm/sq" \
+ "magic::gencell sky130::mrm1" pdk2
+ magic::add_toolkit_command $layoutframe "mrm2 - 125 mOhm/sq" \
+ "magic::gencell sky130::mrm2" pdk2
+ magic::add_toolkit_command $layoutframe "mrm3 - 47 mOhm/sq" \
+ "magic::gencell sky130::mrm3" pdk2
+#ifdef METAL5
+ magic::add_toolkit_command $layoutframe "mrm4 - 47 mOhm/sq" \
+ "magic::gencell sky130::mrm4" pdk2
+ magic::add_toolkit_command $layoutframe "mrm5 - 29 mOhm/sq" \
+ "magic::gencell sky130::mrm5" pdk2
+#endif (METAL5)
+
+#ifdef MIM
+ magic::add_toolkit_command $layoutframe "xcmimc1 - 1fF/um^2 MiM cap" \
+ "magic::gencell sky130::xcmimc1" pdk2
+ magic::add_toolkit_command $layoutframe "xcmimc2 - 1fF/um^2 MiM cap" \
+ "magic::gencell sky130::xcmimc2" pdk2
+#endif (MIM)
+ magic::add_toolkit_separator $layoutframe pdk2
+
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m5 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m3/m5 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m4 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 p/m4 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield" pdk2
+ # magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 p/m5 shield" \
+ # "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 li/m3/m5 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 6.8x6.1 li/m4 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 6.8x6.1 p/m4 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 li/m3/m5 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 4.2x2 nhvnat" \
+ "magic::gencell sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield" pdk2
+ # magic::add_toolkit_command $layoutframe "vpp 1.8x1.8 li shield" \
+ # "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield" pdk2
+ # magic::add_toolkit_command $layoutframe "vpp 1.8x1.8 m3 shield" \
+ # "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 li/m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 li/m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 m3 shield" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield" pdk2
+ magic::add_toolkit_command $layoutframe "vpp2" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp2" pdk2
+ magic::add_toolkit_command $layoutframe "vpp2 nwell" \
+ "magic::gencell sky130::sky130_fd_pr_rf_xcmvpp2_nwell" pdk2
+
+ ${layoutframe}.titlebar.mbuttons.drc.toolmenu add command -label "DRC Routing" -command {drc style drc(routing)}
+
+ # Add command entry window by default if enabled
+ if {[info exists Opts(cmdentry)]} {
+ set Winopts(${framename},cmdentry) $Opts(cmdentry)
+ } else {
+ set Winopts(${framename},cmdentry) 0
+ }
+ if {$Winopts(${framename},cmdentry) == 1} {
+ addcommandentry $framename
+ }
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mcon_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.17} {
+ puts stderr "Mcon width must be at least 0.17um"
+ return
+ }
+ if {$h < 0.17} {
+ puts stderr "Mcon height must be at least 0.17um"
+ return
+ }
+ paint lic
+ box grow n 0.05um
+ box grow s 0.05um
+ paint m1
+ box grow n -0.05um
+ box grow s -0.05um
+ box grow e 0.05um
+ box grow w 0.05um
+ paint li
+ box grow e -0.05um
+ box grow w -0.05um
+}
+
+proc sky130::via1_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.26} {
+ puts stderr "Via1 width must be at least 0.26um"
+ return
+ }
+ if {$h < 0.26} {
+ puts stderr "Via1 height must be at least 0.26um"
+ return
+ }
+ paint via1
+ box grow n 0.05um
+ box grow s 0.05um
+ paint m2
+ box grow n -0.05um
+ box grow s -0.05um
+ box grow e 0.05um
+ box grow w 0.05um
+ paint m1
+ box grow e -0.05um
+ box grow w -0.05um
+}
+
+proc sky130::via2_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.28} {
+ puts stderr "Via2 width must be at least 0.28um"
+ return
+ }
+ if {$h < 0.28} {
+ puts stderr "Via2 height must be at least 0.28um"
+ return
+ }
+ paint via2
+ box grow n 0.05um
+ box grow s 0.05um
+ paint m2
+ box grow n -0.05um
+ box grow s -0.05um
+ box grow e 0.05um
+ box grow w 0.05um
+ paint m3
+ box grow e -0.05um
+ box grow w -0.05um
+}
+
+#ifdef METAL5
+proc sky130::via3_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.32} {
+ puts stderr "Via3 width must be at least 0.32um"
+ return
+ }
+ if {$h < 0.32} {
+ puts stderr "Via3 height must be at least 0.32um"
+ return
+ }
+ paint via3
+ box grow n 0.05um
+ box grow s 0.05um
+ paint m4
+ box grow n -0.05um
+ box grow s -0.05um
+ box grow e 0.05um
+ box grow w 0.05um
+ paint m3
+ box grow e -0.05um
+ box grow w -0.05um
+}
+
+proc sky130::via4_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 1.18} {
+ puts stderr "Via3 width must be at least 1.18um"
+ return
+ }
+ if {$h < 1.18} {
+ puts stderr "Via3 height must be at least 1.18um"
+ return
+ }
+ paint via4
+ box grow n 0.05um
+ box grow s 0.05um
+ paint m5
+ box grow n -0.05um
+ box grow s -0.05um
+ box grow e 0.05um
+ box grow w 0.05um
+ paint m4
+ box grow e -0.05um
+ box grow w -0.05um
+}
+#endif (METAL5)
+
+proc sky130::subconn_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.17} {
+ puts stderr "Substrate tap width must be at least 0.17um"
+ return
+ }
+ if {$h < 0.17} {
+ puts stderr "Substrate tap height must be at least 0.17um"
+ return
+ }
+ paint nsc
+ box grow c 0.1um
+ paint nsd
+ box grow c -0.1um
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mvsubconn_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 0.17} {
+ puts stderr "Substrate tap width must be at least 0.17um"
+ return
+ }
+ if {$h < 0.17} {
+ puts stderr "Substrate tap height must be at least 0.17um"
+ return
+ }
+ paint mvnsc
+ box grow c 0.1um
+ paint mvnsd
+ box grow c -0.1um
+}
+
+#----------------------------------------------------------------
+
+proc sky130::deep_nwell_draw {} {
+ set w [magic::i2u [box width]]
+ set h [magic::i2u [box height]]
+ if {$w < 3.0} {
+ puts stderr "Deep-nwell region width must be at least 3.0um"
+ return
+ }
+ if {$h < 3.0} {
+ puts stderr "Deep-nwell region height must be at least 3.0um"
+ return
+ }
+ suspendall
+ tech unlock *
+ paint dnwell
+ pushbox
+ pushbox
+ box grow c 0.4um
+ paint nwell
+ box grow c -1.43um
+ erase nwell
+ popbox
+ box grow c 0.03um
+
+ pushbox
+ box width 0
+ box grow c 0.085um
+ paint li
+ pushbox
+ box grow n -0.3um
+ box grow s -0.3um
+ paint nsc
+ popbox
+ box grow c 0.1um
+ paint nsd
+ popbox
+
+ pushbox
+ box height 0
+ box grow c 0.085um
+ paint li
+ pushbox
+ box grow e -0.3um
+ box grow w -0.3um
+ paint nsc
+ popbox
+ box grow c 0.1um
+ paint nsd
+ popbox
+
+ pushbox
+ box move n [box height]i
+ box height 0
+ box grow c 0.085um
+ paint li
+ pushbox
+ box grow e -0.3um
+ box grow w -0.3um
+ paint nsc
+ popbox
+ box grow c 0.1um
+ paint nsd
+ popbox
+
+ pushbox
+ box move e [box width]i
+ box width 0
+ box grow c 0.085um
+ paint li
+ pushbox
+ box grow n -0.3um
+ box grow s -0.3um
+ paint nsc
+ box grow c 0.1um
+ paint nsd
+ popbox
+
+ popbox
+ tech revert
+ resumeall
+}
+
+#----------------------------------------------------------------
+
+proc sky130::res_recalc {field parameters} {
+ set snake 0
+ set sterm 0.0
+ set caplen 0
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+ set val [magic::spice2float $val]
+ set l [magic::spice2float $l]
+ set w [magic::spice2float $w]
+
+ if {$snake == 0} {
+ # Straight resistor calculation
+ switch $field {
+ val { set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
+ set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
+ }
+ w { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
+ set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
+ }
+ l { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
+ set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
+ }
+ }
+ } else {
+ set term [expr $term + $sterm]
+ # Snake resistor calculation
+ switch $field {
+ val { set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
+ - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
+ / ($rho * $nx)]
+
+ set w [expr ((2 * $term + $l * $rho * $nx \
+ + $caplen * $rho * ($nx - 1)) \
+ / ($val - $rho * ($nx - 1))) + $dw]
+ }
+ w { set val [expr $rho * ($nx - 1) + ((2 * $term) \
+ + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
+ / ($w - $dw)]
+
+ set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
+ - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
+ / ($rho * $nx)]
+ }
+ l { set val [expr $rho * ($nx - 1) + ((2 * $term) \
+ + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
+ / ($w - $dw)]
+
+ set w [expr ((2 * $term + $l * $rho * $nx \
+ + $caplen * $rho * ($nx - 1)) \
+ / ($val - $rho * ($nx - 1))) + $dw]
+ }
+ }
+ }
+
+ set val [magic::3digitpastdecimal $val]
+ set w [magic::3digitpastdecimal $w]
+ set l [magic::3digitpastdecimal $l]
+
+ dict set parameters val $val
+ dict set parameters w $w
+ dict set parameters l $l
+
+ return $parameters
+}
+
+#----------------------------------------------------------------
+# Drawn diode routines
+#----------------------------------------------------------------
+
+proc sky130::diode_recalc {field parameters} {
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+ switch $field {
+ area { puts stdout "area changed" }
+ peri { puts stdout "perimeter changed" }
+ w { puts stdout "width changed" }
+ l { puts stdout "length changed" }
+ }
+ dict set parameters area $area
+ dict set parameters peri $peri
+ dict set parameters w $w
+ dict set parameters l $l
+}
+
+#----------------------------------------------------------------
+# diode: Conversion from SPICE netlist parameters to toolkit
+#----------------------------------------------------------------
+
+proc sky130::diode_convert {parameters} {
+ set pdkparams [dict create]
+ dict for {key value} $parameters {
+ switch -nocase $key {
+ l -
+ w -
+ peri {
+ # Length, width, and perimeter are converted to units of microns
+ set value [magic::spice2float $value]
+ # set value [expr $value * 1e6]
+ set value [magic::3digitpastdecimal $value]
+ dict set pdkparams [string tolower $key] $value
+ }
+ area {
+ # area also converted to units of microns
+ set value [magic::spice2float $value]
+ # set value [expr $value * 1e12]
+ set value [magic::3digitpastdecimal $value]
+ dict set pdkparams [string tolower $key] $value
+ }
+ m {
+ # Convert m to ny
+ dict set pdkparams ny $value
+ }
+ }
+ }
+ return $pdkparams
+}
+
+#----------------------------------------------------------------
+# diode: Interactively specifies the fixed layout parameters
+#----------------------------------------------------------------
+
+proc sky130::diode_dialog {device parameters} {
+ # Editable fields: w, l, area, perim, nx, ny
+
+ magic::add_entry area "Area (um^2)" $parameters
+ magic::add_entry peri "Perimeter (um)" $parameters
+ sky130::compute_aptot $parameters
+ magic::add_message atot "Total area (um^2)" $parameters
+ magic::add_message ptot "Total perimeter (um)" $parameters
+ magic::add_entry l "Length (um)" $parameters
+ magic::add_entry w "Width (um)" $parameters
+ magic::add_entry nx "X Repeat" $parameters
+ magic::add_entry ny "Y Repeat" $parameters
+
+ if {[dict exists $parameters compatible]} {
+ set sellist [dict get $parameters compatible]
+ magic::add_selectlist gencell "Device type" $sellist $parameters $device
+ }
+
+ if {[dict exists $parameters doverlap]} {
+ magic::add_checkbox doverlap "Overlap at end contact" $parameters
+ }
+ if {[dict exists $parameters elc]} {
+ magic::add_checkbox elc "Add left end contact" $parameters
+ }
+ if {[dict exists $parameters erc]} {
+ magic::add_checkbox erc "Add right end contact" $parameters
+ }
+ if {[dict exists $parameters etc]} {
+ magic::add_checkbox etc "Add top end contact" $parameters
+ }
+ if {[dict exists $parameters ebc]} {
+ magic::add_checkbox ebc "Add bottom end contact" $parameters
+ }
+
+ if {[dict exists $parameters guard]} {
+ magic::add_checkbox full_metal "Full metal guard ring" $parameters
+ }
+ if {[dict exists $parameters glc]} {
+ magic::add_checkbox glc "Add left guard ring contact" $parameters
+ }
+ if {[dict exists $parameters grc]} {
+ magic::add_checkbox grc "Add right guard ring contact" $parameters
+ }
+ if {[dict exists $parameters gtc]} {
+ magic::add_checkbox gtc "Add top guard ring contact" $parameters
+ }
+ if {[dict exists $parameters gbc]} {
+ magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
+ }
+
+ magic::add_dependency sky130::diode_recalc $device sky130 l w area peri
+
+ # magic::add_checkbox dummy "Add dummy" $parameters
+}
+
+#----------------------------------------------------------------
+# Diode total area and perimeter computation
+#----------------------------------------------------------------
+
+proc sky130::compute_aptot {parameters} {
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+ set area [magic::spice2float $area]
+ set area [magic::3digitpastdecimal $area]
+ set peri [magic::spice2float $peri]
+ set peri [magic::3digitpastdecimal $peri]
+
+ # Compute total area
+ catch {set magic::atot_val [expr ($area * $nx * $ny)]}
+ # Compute total perimeter
+ catch {set magic::ptot_val [expr ($peri * $nx * $ny)]}
+}
+
+#----------------------------------------------------------------
+# diode: Check device parameters for out-of-bounds values
+#----------------------------------------------------------------
+
+proc sky130::diode_check {parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set l [magic::spice2float $l]
+ set l [magic::3digitpastdecimal $l]
+ set w [magic::spice2float $w]
+ set w [magic::3digitpastdecimal $w]
+
+ set area [magic::spice2float $area]
+ set area [magic::3digitpastdecimal $area]
+ set peri [magic::spice2float $peri]
+ set peri [magic::3digitpastdecimal $peri]
+
+ if {$l == 0} {
+ # Calculate L from W and area
+ set l [expr ($area / $w)]
+ dict set parameters l [magic::float2spice $l]
+ } elseif {$w == 0} {
+ # Calculate W from L and area
+ set w [expr ($area / $l)]
+ dict set parameters w [magic::float2spice $w]
+ }
+ if {$w < $wmin} {
+ puts stderr "Diode width must be >= $wmin"
+ dict set parameters w $wmin
+ }
+ if {$l < $lmin} {
+ puts stderr "Diode length must be >= $lmin"
+ dict set parameters l $lmin
+ }
+ # Calculate area and perimeter from L and W
+ set area [expr ($l * $w)]
+ dict set parameters area [magic::float2spice $area]
+ set peri [expr (2 * ($l + $w))]
+ dict set parameters peri [magic::float2spice $peri]
+ sky130::compute_aptot $parameters
+
+ return $parameters
+}
+
+#------------------------------------------------------------------
+# NOTE: ndiode_lvt, ndiode_native, pdiode_lvt, and pdiode_hvt are
+# all considered parasitic diodes. They may be generated by
+# invoking the build procedure on the command line. To enable them
+# in the PDK, add them to the appropriate compatible {} list.
+#------------------------------------------------------------------
+
+proc sky130::ndiode_defaults {} {
+ return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
+ compatible {ndiode ndiode_h} full_metal 1}
+}
+
+proc sky130::ndiode_lvt_defaults {} {
+ return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
+ full_metal 1}
+}
+
+proc sky130::pdiode_defaults {} {
+ return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 \
+ glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
+ compatible {pdiode pdiode_h} full_metal 1}
+}
+
+proc sky130::pdiode_lvt_defaults {} {
+ return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 \
+ glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
+ full_metal 1}
+}
+
+proc sky130::pdiode_hvt_defaults {} {
+ return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 \
+ glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
+ full_metal 1}
+}
+
+proc sky130::ndiode_h_defaults {} {
+ return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
+ compatible {ndiode ndiode_h} full_metal 1}
+}
+
+proc sky130::ndiode_native_defaults {} {
+ return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
+ full_metal 1}
+}
+
+proc sky130::pdiode_h_defaults {} {
+ return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
+ nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
+ elc 1 erc 1 etc 1 ebc 1 \
+ glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
+ compatible {pdiode pdiode_h} full_metal 1}
+}
+
+#----------------------------------------------------------------
+
+proc sky130::ndiode_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::ndiode_lvt_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::pdiode_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::pdiode_lvt_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::pdiode_hvt_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::ndiode_h_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::ndiode_native_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+proc sky130::pdiode_h_convert {parameters} {
+ return [sky130::diode_convert $parameters]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::ndiode_dialog {parameters} {
+ sky130::diode_dialog ndiode $parameters
+}
+
+proc sky130::ndiode_lvt_dialog {parameters} {
+ sky130::diode_dialog ndiode_lvt $parameters
+}
+
+proc sky130::pdiode_dialog {parameters} {
+ sky130::diode_dialog pdiode $parameters
+}
+
+proc sky130::pdiode_lvt_dialog {parameters} {
+ sky130::diode_dialog pdiode_lvt $parameters
+}
+
+proc sky130::pdiode_hvt_dialog {parameters} {
+ sky130::diode_dialog pdiode_hvt $parameters
+}
+
+proc sky130::ndiode_h_dialog {parameters} {
+ sky130::diode_dialog ndiode_h $parameters
+}
+
+proc sky130::ndiode_native_dialog {parameters} {
+ sky130::diode_dialog ndiode_native $parameters
+}
+
+proc sky130::pdiode_h_dialog {parameters} {
+ sky130::diode_dialog pdiode_h $parameters
+}
+
+#----------------------------------------------------------------
+
+proc sky130::ndiode_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::ndiode_lvt_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::pdiode_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::pdiode_lvt_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::pdiode_hvt_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::ndiode_h_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::ndiode_native_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+proc sky130::pdiode_h_check {parameters} {
+ sky130::diode_check $parameters
+}
+
+#----------------------------------------------------------------
+# Diode: Draw a single device
+#----------------------------------------------------------------
+
+proc sky130::diode_device {parameters} {
+ # Epsilon for avoiding round-off errors
+ set eps 0.0005
+
+ # Set local default values if they are not in parameters
+ set dev_surround 0
+ set dev_sub_type ""
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # If there is no end_sub_surround, set it to sub_surround
+ if {![dict exists $parameters end_sub_surround]} {
+ set end_sub_surround $sub_surround
+ }
+
+ # Draw the device
+ pushbox
+ box size 0 0
+
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+
+ # Calculate ring size (measured to contact center)
+ set gx [+ $w [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
+ set gy [+ $l [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
+
+ # Draw the ring first, because diode may occupy well/substrate plane
+ set guardparams $parameters
+ dict set guardparams plus_diff_type $end_type
+ dict set guardparams plus_contact_type $end_contact_type
+ dict set guardparams diff_surround $end_surround
+ dict set guardparams sub_type $end_sub_type
+ dict set guardparams sub_surround $sub_surround
+ dict set guardparams guard_sub_surround $end_sub_surround
+ dict set guardparams glc $elc
+ dict set guardparams grc $erc
+ dict set guardparams gtc $etc
+ dict set guardparams gbc $ebc
+ set cext [sky130::guard_ring $gx $gy $guardparams]
+
+ pushbox
+ box grow n ${hl}um
+ box grow s ${hl}um
+ box grow e ${hw}um
+ box grow w ${hw}um
+ paint ${dev_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+
+ if {$dev_sub_type != ""} {
+ box grow n ${sub_surround}um
+ box grow s ${sub_surround}um
+ box grow e ${sub_surround}um
+ box grow w ${sub_surround}um
+ paint ${dev_sub_type}
+ }
+ popbox
+
+ if {${w} < ${l}} {
+ set orient vert
+ } else {
+ set orient horz
+ }
+
+ # Reduce width by surround amount
+ set w [- $w [* ${dev_surround} 2.0]]
+ set l [- $l [* ${dev_surround} 2.0]]
+
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${w} ${l} \
+ ${dev_surround} ${metal_surround} ${contact_size} \
+ ${dev_type} ${dev_contact_type} li ${orient}]]
+
+ popbox
+ return $cext
+}
+
+#----------------------------------------------------------------
+# Diode: Draw the tiled device
+#----------------------------------------------------------------
+
+proc sky130::diode_draw {parameters} {
+ tech unlock *
+
+ # Set defaults if they are not in parameters
+ set doverlap 0 ;# overlap diodes at contacts
+ set guard 0 ;# draw a guard ring
+ set prohibit_overlap false ;# don't prohibit overlaps
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set w [magic::spice2float $w]
+ set l [magic::spice2float $l]
+
+ pushbox
+ box values 0 0 0 0
+
+ # Determine the base device dimensions by drawing one device
+ # while all layers are locked (nothing drawn). This allows the
+ # base drawing routine to do complicated geometry without having
+ # to duplicate it here with calculations.
+
+ tech lock *
+ set bbox [sky130::diode_device $parameters]
+ # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
+ tech unlock *
+
+ set fw [- [lindex $bbox 2] [lindex $bbox 0]]
+ set fh [- [lindex $bbox 3] [lindex $bbox 1]]
+ set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
+ set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
+
+ # If prohibit_overlap is true, then end overlapping is prohibited when
+ # nx or ny is > 1 to prevent DRC errors (typically from well spacing rule)
+ if {$prohibit_overlap == true} {
+ if {($nx > 1) || ($ny > 1)} {
+ set doverlap 0
+ }
+ }
+
+ # Determine tile width and height (depends on overlap)
+
+ if {$doverlap == 0} {
+ set dx [+ $fw $end_spacing]
+ set dy [+ $fh $end_spacing]
+ } else {
+ # overlap contact
+ set dx [- $fw [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
+ set dy [- $fh [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
+ }
+
+ # Determine core width and height
+ set corex [+ [* [- $nx 1] $dx] $fw]
+ set corey [+ [* [- $ny 1] $dy] $fh]
+ set corellx [/ [+ [- $corex $fw] $lw] 2.0]
+ set corelly [/ [+ [- $corey $fh] $lh] 2.0]
+
+ if {$guard != 0} {
+ # Calculate guard ring size (measured to contact center)
+ set gx [+ $corex [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
+ set gy [+ $corey [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
+
+ # Draw the guard ring first, because diode may occupy well/substrate plane
+ sky130::guard_ring $gx $gy $parameters
+ }
+
+ pushbox
+ box move w ${corellx}um
+ box move s ${corelly}um
+ if {($nx > 1) || ($ny > 1)} {
+ pushbox
+ set hfw [/ $fw 2.0]
+ set hfh [/ $fh 2.0]
+ box move w ${hfw}um
+ box move s ${hfh}um
+ box size ${corex}um ${corey}um
+ paint $end_sub_type
+ popbox
+ }
+ for {set xp 0} {$xp < $nx} {incr xp} {
+ pushbox
+ for {set yp 0} {$yp < $ny} {incr yp} {
+ sky130::diode_device $parameters
+ box move n ${dy}um
+ }
+ popbox
+ box move e ${dx}um
+ }
+ popbox
+ popbox
+
+ tech revert
+}
+
+#----------------------------------------------------------------
+
+proc sky130::ndiode_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type ndiode \
+ dev_contact_type ndic \
+ end_type psd \
+ end_contact_type psc \
+ end_sub_type psub \
+ dev_spacing ${diff_spacing} \
+ dev_surround ${diff_surround} \
+ end_spacing ${diff_spacing} \
+ end_surround 0 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+# NOTE: Use ppd instead of psd so that there is additional
+# diffusion around the contact, allowing more space for the
+# implant (likewise pdiode_lvt and pdiode_hvt).
+
+proc sky130::ndiode_lvt_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type ndiodelvt \
+ dev_contact_type ndilvtc \
+ end_type ppd \
+ end_contact_type psc \
+ end_sub_type psub \
+ dev_spacing ${diff_spacing} \
+ dev_surround ${diff_surround} \
+ end_spacing ${diff_spacing} \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::pdiode_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type pdiode \
+ guard 1 \
+ dev_contact_type pdic \
+ end_type nsd \
+ end_contact_type nsc \
+ end_sub_type nwell \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ dev_spacing ${diff_spacing} \
+ dev_surround ${diff_surround} \
+ end_spacing ${diff_spacing} \
+ end_surround 0 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::pdiode_lvt_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type pdiodelvt \
+ guard 1 \
+ dev_contact_type pdilvtc \
+ end_type nnd \
+ end_contact_type nsc \
+ end_sub_type nwell \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ dev_spacing ${diff_spacing} \
+ dev_surround ${diff_surround} \
+ end_spacing ${diff_spacing} \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::pdiode_hvt_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type pdiodehvt \
+ guard 1 \
+ dev_contact_type pdihvtc \
+ end_type nnd \
+ end_contact_type nsc \
+ end_sub_type nwell \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ dev_spacing ${diff_spacing} \
+ dev_surround ${diff_surround} \
+ end_spacing ${diff_spacing} \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::ndiode_h_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type mvndiode \
+ dev_contact_type mvndic \
+ end_type mvpsd \
+ end_contact_type mvpsc \
+ end_sub_type psub \
+ diff_spacing 0.37 \
+ dev_spacing 0.39 \
+ dev_surround ${diff_surround} \
+ end_spacing 0.36 \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+
+proc sky130::ndiode_native_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ dev_type nndiode \
+ dev_contact_type nndic \
+ end_type mvpsd \
+ end_contact_type mvpsc \
+ end_sub_type psub \
+ dev_spacing 0.37 \
+ dev_surround ${diff_surround} \
+ end_spacing 0.30 \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+
+#----------------------------------------------------------------
+
+proc sky130::pdiode_h_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 1 \
+ dev_type mvpdiode \
+ dev_contact_type mvpdic \
+ end_type mvnsd \
+ end_contact_type mvnsc \
+ end_sub_type nwell \
+ plus_diff_type mvpsd \
+ plus_contact_type mvpsc \
+ sub_type psub \
+ diff_spacing 0.58 \
+ dev_spacing 0.37 \
+ dev_surround ${diff_surround} \
+ end_spacing 0.30 \
+ end_sub_surround 0.33 \
+ end_surround ${diff_surround} \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::diode_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+# Drawn capactitor routines
+# NOTE: Work in progress. These values need to be corrected.
+#----------------------------------------------------------------
+
+#ifdef MIM
+proc sky130::xcmimc1_defaults {} {
+ return {w 2.00 l 2.00 val 4.0 carea 1.00 cperi 0.17 \
+ nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
+ lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1}
+}
+proc sky130::xcmimc2_defaults {} {
+ return {w 2.00 l 2.00 val 4.0 carea 1.00 cperi 0.17 \
+ nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
+ lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1}
+}
+#endif (MIM)
+
+
+#----------------------------------------------------------------
+# Recalculate capacitor values from GUI entries.
+# Recomputes W/L and Value as long as 2 of them are present
+# (To be completed)
+#----------------------------------------------------------------
+
+proc sky130::cap_recalc {field parameters} {
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+ switch $field {
+ val { puts stdout "value changed" }
+ w { puts stdout "width changed" }
+ l { puts stdout "length changed" }
+ }
+ dict set parameters val $val
+ dict set parameters w $w
+ dict set parameters l $l
+}
+
+#----------------------------------------------------------------
+# Capacitor defaults:
+#----------------------------------------------------------------
+# w Width of drawn cap
+# l Length of drawn cap
+# nx Number of devices in X
+# ny Number of devices in Y
+# val Default cap value
+# carea Area
+# cperi Perimeter
+# dummy Add dummy cap
+# square Make square capacitor
+#
+# (not user-editable)
+#
+# wmin Minimum allowed width
+# lmin Minimum allowed length
+# dc Area to remove to calculated area
+#----------------------------------------------------------------
+
+#----------------------------------------------------------------
+# capacitor: Conversion from SPICE netlist parameters to toolkit
+#----------------------------------------------------------------
+
+proc sky130::cap_convert {parameters} {
+ set pdkparams [dict create]
+ dict for {key value} $parameters {
+ switch -nocase $key {
+ l -
+ w {
+ # Length and width are converted to units of microns
+ set value [magic::spice2float $value]
+ # set value [expr $value * 1e6]
+ set value [magic::3digitpastdecimal $value]
+ dict set pdkparams [string tolower $key] $value
+ }
+ m {
+ # Convert m to ny
+ dict set pdkparams ny $value
+ }
+ }
+ }
+ return $pdkparams
+}
+
+#ifdef MIM
+proc sky130::xcmimc1_convert {parameters} {
+ return [cap_convert $parameters]
+}
+proc sky130::xcmimc2_convert {parameters} {
+ return [cap_convert $parameters]
+}
+#endif (MIM)
+
+#----------------------------------------------------------------
+# capacitor: Interactively specifies the fixed layout parameters
+#----------------------------------------------------------------
+
+proc sky130::cap_dialog {device parameters} {
+ # Editable fields: w, l, nx, ny, val
+ # Checked fields: square, dummy
+
+ magic::add_entry val "Value (fF)" $parameters
+ sky130::compute_ctot $parameters
+ magic::add_message ctot "Total capacitance (pF)" $parameters
+ magic::add_entry l "Length (um)" $parameters
+ magic::add_entry w "Width (um)" $parameters
+ magic::add_entry nx "X Repeat" $parameters
+ magic::add_entry ny "Y Repeat" $parameters
+
+ if {[dict exists $parameters square]} {
+ magic::add_checkbox square "Square capacitor" $parameters
+ }
+ if {[dict exists $parameters bconnect]} {
+ magic::add_checkbox bconnect "Connect bottom plates in array" $parameters
+ }
+ if {[dict exists $parameters tconnect]} {
+ magic::add_checkbox tconnect "Connect top plates in array" $parameters
+ }
+ if {[dict exists $parameters guard]} {
+ magic::add_checkbox guard "Add guard ring" $parameters
+ }
+
+ magic::add_dependency sky130::cap_recalc $device sky130 l w val
+
+ # magic::add_checkbox dummy "Add dummy" $parameters
+}
+
+#ifdef MIM
+proc sky130::xcmimc1_dialog {parameters} {
+ sky130::cap_dialog xcmimc1 $parameters
+}
+proc sky130::xcmimc2_dialog {parameters} {
+ sky130::cap_dialog xcmimc2 $parameters
+}
+#endif (MIM)
+
+#----------------------------------------------------------------
+# Capacitor total capacitance computation
+#----------------------------------------------------------------
+
+proc sky130::compute_ctot {parameters} {
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+ set val [magic::spice2float $val]
+ set val [magic::3digitpastdecimal $val]
+
+ # Compute total capacitance (and convert fF to pF)
+ catch {set magic::ctot_val [expr (0.001 * $val * $nx * $ny)]}
+}
+
+#----------------------------------------------------------------
+# Capacitor: Draw a single device
+#----------------------------------------------------------------
+
+proc sky130::cap_device {parameters} {
+ # Epsilon for avoiding round-off errors
+ set eps 0.0005
+
+ # Set local default values if they are not in parameters
+ set cap_surround 0
+ set bot_surround 0
+ set top_surround 0
+ set bconnect 0 ;# bottom plates are connected in array
+ set cap_spacing 0 ;# cap spacing in array
+ set top_metal_space 0 ;# top metal spacing (if larger than cap spacing)
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ if {![dict exists $parameters top_metal_space]} {
+ set top_metal_space $metal_spacing
+ }
+
+ # Draw the device
+ pushbox
+ box size 0 0
+
+ pushbox
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+ box grow e ${hw}um
+ box grow w ${hw}um
+ box grow n ${hl}um
+ box grow s ${hl}um
+ paint ${cap_type}
+ pushbox
+ box grow n -${cap_surround}um
+ box grow s -${cap_surround}um
+ box grow e -${cap_surround}um
+ box grow w -${cap_surround}um
+ paint ${cap_contact_type}
+ pushbox
+ box grow n ${top_surround}um
+ box grow s ${top_surround}um
+ box grow e ${top_surround}um
+ box grow w ${top_surround}um
+ paint ${top_type}
+ set cext [sky130::getbox]
+ popbox
+ popbox
+ pushbox
+ box grow n ${bot_surround}um
+ box grow s ${bot_surround}um
+ box grow e ${bot_surround}um
+ box grow w ${bot_surround}um
+
+ paint ${bot_type}
+ # Create boundary using properties
+ property FIXED_BBOX [box values]
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+
+ # Extend bottom metal under contact to right
+ box grow e ${end_spacing}um
+ set chw [/ ${contact_size} 2.0]
+ box grow e ${chw}um
+ box grow e ${end_surround}um
+ paint ${bot_type}
+
+ popbox
+ popbox
+
+ # Draw contact to right. Reduce contact extent if devices are not
+ # wired together and the top metal spacing rule limits the distance
+ set lcont $l
+ if {($bconnect == 0) && ($ny > 1)} {
+ if {$cap_spacing < $top_metal_space} {
+ set cspace [- $top_metal_space $cap_spacing]
+ set lcont [- $l $cspace]
+ }
+ }
+
+ pushbox
+ box move e ${hw}um
+ box move e ${bot_surround}um
+ box move e ${end_spacing}um
+ set cl [- [+ ${lcont} [* ${bot_surround} 2.0]] [* ${end_surround} 2.0]]
+ set cl [- ${cl} ${metal_surround}] ;# see below
+ set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cl} \
+ ${end_surround} ${metal_surround} ${contact_size} \
+ ${bot_type} ${top_contact_type} ${top_type} full]]
+ popbox
+ popbox
+
+ return $cext
+
+ # cl shrinks top and bottom to accomodate larger bottom metal
+ # surround rule for contacts near a MiM cap. This should be its
+ # own variable, but metal_surround is sufficient.
+}
+
+#----------------------------------------------------------------
+# Metal plate sandwich capacitor: Draw a single device
+#----------------------------------------------------------------
+
+proc sky130::sandwich_cap_device {parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ pushbox
+ box size 0 0
+
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+
+ set cw [- [* $hw [/ 2.0 3]] [* $cont_surround 2.0]]
+ set cl [- [* $hl [/ 2.0 3]] [* $cont_surround 2.0]]
+
+ # plate capacitor defines layers p0, p1, etc.
+ for {set i 0} {$i < 20} {incr i} {
+ if {[catch {set layer [subst \$p${i}_type]}]} {break} ;# no more layers defined
+ pushbox
+ box grow e ${hw}um
+ box grow w ${hw}um
+ box grow n ${hl}um
+ box grow s ${hl}um
+ if {![catch {set shrink [subst \$p${i}_shrink]}]} {
+ box grow e -${shrink}um
+ box grow w -${shrink}um
+ box grow n -${shrink}um
+ box grow s -${shrink}um
+ set cutout_spacing [+ [* ${shrink} 2.0] [/ $via_size 2.0] $cont_surround]
+ } else {
+ set cutout_spacing 0
+ }
+
+ paint ${layer}
+
+ if {$i == 1} {
+ # Note that cap_type geometry is coincident with p1_type.
+ # Typically, this will define a layer that outputs as both
+ # poly and a capacitor definition layer.
+ if {[dict exists $parameters cap_type]} {
+ paint $cap_type
+ }
+ }
+ popbox
+
+ # Even layers connect at corners, odd layers connect at sides.
+ # Even layers cut out the sides, odd layers cut out the corners.
+ # Layer zero has no side contacts or cutout.
+
+ if {[% $i 2] == 0} {
+ set cornercmd paint
+ set cornersize $cutout_spacing
+ set sidecmd erase
+ set nssidelong [+ $cutout_spacing [/ $hw 3.0]]
+ set ewsidelong [+ $cutout_spacing [/ $hl 3.0]]
+ set sideshort $cutout_spacing
+ } else {
+ set cornercmd erase
+ set cornersize $cutout_spacing
+ set sidecmd paint
+ set nssidelong [/ $hw 3.0]
+ set ewsidelong [/ $hl 3.0]
+ set sideshort $cutout_spacing
+ }
+
+ if {$i > 0} {
+ pushbox
+ box move e ${hw}um
+ box grow n ${ewsidelong}um
+ box grow s ${ewsidelong}um
+ box grow w ${sideshort}um
+ ${sidecmd} ${layer}
+ popbox
+ pushbox
+ box move n ${hl}um
+ box grow e ${nssidelong}um
+ box grow w ${nssidelong}um
+ box grow s ${sideshort}um
+ ${sidecmd} ${layer}
+ popbox
+ pushbox
+ box move w ${hw}um
+ box grow n ${ewsidelong}um
+ box grow s ${ewsidelong}um
+ box grow e ${sideshort}um
+ ${sidecmd} ${layer}
+ popbox
+ pushbox
+ box move s ${hl}um
+ box grow e ${nssidelong}um
+ box grow w ${nssidelong}um
+ box grow n ${sideshort}um
+ ${sidecmd} ${layer}
+ popbox
+
+ pushbox
+ box move n ${hl}um
+ box move e ${hw}um
+ box grow s ${cornersize}um
+ box grow w ${cornersize}um
+ ${cornercmd} ${layer}
+ popbox
+ pushbox
+ box move n ${hl}um
+ box move w ${hw}um
+ box grow s ${cornersize}um
+ box grow e ${cornersize}um
+ ${cornercmd} ${layer}
+ popbox
+ pushbox
+ box move s ${hl}um
+ box move e ${hw}um
+ box grow n ${cornersize}um
+ box grow w ${cornersize}um
+ ${cornercmd} ${layer}
+ popbox
+ pushbox
+ box move s ${hl}um
+ box move w ${hw}um
+ box grow n ${cornersize}um
+ box grow e ${cornersize}um
+ ${cornercmd} ${layer}
+ popbox
+ }
+ }
+
+ # Draw contacts after all layers have been drawn, so that erasing
+ # layers does not affect the contacts.
+
+ for {set i 0} {$i < 20} {incr i} {
+ if {![catch {set contact [subst \$p${i}_contact_type]}]} {
+ set layer [subst \$p${i}_type]
+ set j [+ $i 1]
+ set toplayer [subst \$p${j}_type]
+
+ # Draw corner contacts
+ pushbox
+ box move e ${hw}um
+ box move n ${hl}um
+ sky130::draw_contact 0 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move w ${hw}um
+ box move n ${hl}um
+ sky130::draw_contact 0 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move e ${hw}um
+ box move s ${hl}um
+ sky130::draw_contact 0 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move w ${hw}um
+ box move s ${hl}um
+ sky130::draw_contact 0 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+
+ # Draw side contacts (except on poly)
+ if {$i > 0} {
+ pushbox
+ box move w ${hw}um
+ sky130::draw_contact 0 ${cl} \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move e ${hw}um
+ sky130::draw_contact 0 ${cl} \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move n ${hl}um
+ sky130::draw_contact ${cw} 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ pushbox
+ box move s ${hl}um
+ sky130::draw_contact ${cw} 0 \
+ ${cont_surround} ${cont_surround} ${via_size} \
+ ${layer} ${contact} ${toplayer} full
+ popbox
+ }
+ } else {
+ break
+ }
+ }
+
+ popbox
+ # Bounding box is the same as the device length and width
+ set cext [list -$hw -$hl $hw $hl]
+ return $cext
+}
+
+#----------------------------------------------------------------
+# Capacitor: Draw the tiled device
+#----------------------------------------------------------------
+
+proc sky130::cap_draw {parameters} {
+ tech unlock *
+ set savesnap [snap]
+ snap internal
+
+ # Set defaults if they are not in parameters
+ set coverlap 0 ;# overlap capacitors at contacts
+ set guard 0 ;# draw a guard ring
+ set sandwich 0 ;# this is not a plate sandwich capacitor
+ set cap_spacing 0 ;# abutted caps if spacing is zero
+ set cap_diff_spacing 0
+ set wide_cap_spacing 0 ;# additional spacing for wide metal rule
+ set wide_cap_width 0
+ set end_spacing 0
+ set end_surround 0
+ set bot_surround 0
+ set top_metal_width 0
+ set bconnect 0 ;# connect bottom plates in array
+ set tconnect 0 ;# connect top plates in array
+ set top_type ""
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set w [magic::spice2float $w]
+ set l [magic::spice2float $l]
+
+ pushbox
+ box values 0 0 0 0
+
+ # Determine the base device dimensions by drawing one device
+ # while all layers are locked (nothing drawn). This allows the
+ # base drawing routine to do complicated geometry without having
+ # to duplicate it here with calculations.
+
+ tech lock *
+ if {$sandwich == 1} {
+ set bbox [sky130::sandwich_cap_device $parameters]
+ } else {
+ set bbox [sky130::cap_device $parameters]
+ }
+ # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
+ tech unlock *
+
+ set fw [- [lindex $bbox 2] [lindex $bbox 0]]
+ set fh [- [lindex $bbox 3] [lindex $bbox 1]]
+ set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
+ set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
+
+ set dwide 0
+ if {($fw >= $wide_cap_width) && ($fh >= $wide_cap_width)} {
+ set dwide $wide_cap_spacing
+ }
+
+ # Determine tile width and height (depends on overlap)
+ if {$coverlap == 0} {
+ set dy [+ $fh $cap_spacing $dwide]
+ } else {
+ # overlap at end contact
+ set dy [- $fh [+ $end_surround $end_surround $contact_size]]
+ }
+ # Contact is placed on right so spacing is determined by end_spacing.
+ set dx [+ $fw $end_spacing $dwide]
+
+ # Determine core width and height
+ set corex [+ [* [- $nx 1] $dx] $fw]
+ set corey [+ [* [- $ny 1] $dy] $fh]
+ set corellx [/ [+ [- $corex $fw] $lw] 2.0]
+ set corelly [/ [+ [- $corey $fh] $lh] 2.0]
+
+ if {$guard != 0} {
+ # Calculate guard ring size (measured to contact center)
+ set gx [+ $corex [* 2.0 [+ $cap_diff_spacing $diff_surround]] $contact_size]
+ set gy [+ $corey [* 2.0 [+ $end_spacing $diff_surround]] $contact_size]
+
+ # Draw the guard ring first.
+ sky130::guard_ring $gx $gy $parameters
+ }
+
+ set twidth [+ ${contact_size} ${end_surround} ${end_surround}]
+ if {${twidth} < ${top_metal_width}} {
+ set twidth ${top_metal_width}
+ }
+ set hmw [/ $twidth 2.0]
+ set hdy [/ $dy 2.0]
+ set cdx [+ [/ ${w} 2.0] ${bot_surround} ${end_spacing}]
+
+ pushbox
+ box move w ${corellx}um
+ box move s ${corelly}um
+ for {set xp 0} {$xp < $nx} {incr xp} {
+ pushbox
+ for {set yp 0} {$yp < $ny} {incr yp} {
+ if {$sandwich == 1} {
+ sky130::sandwich_cap_device $parameters
+ } else {
+ sky130::cap_device $parameters
+ }
+ if {$ny > 1} {
+ pushbox
+ box grow e ${hmw}um
+ box grow w ${hmw}um
+ box grow n ${hdy}um
+ box grow s ${hdy}um
+ if {($top_type != "") && ($tconnect == 1)} {
+ paint ${top_type}
+ }
+ if {($top_type != "") && ($bconnect == 1)} {
+ box move e ${cdx}um
+ paint ${top_type}
+ }
+ popbox
+ }
+ box move n ${dy}um
+ }
+ popbox
+ box move e ${dx}um
+ }
+ popbox
+ popbox
+
+ snap $savesnap
+ tech revert
+}
+
+#----------------------------------------------------------------
+
+#ifdef MIM
+proc sky130::xcmimc1_draw {parameters} {
+ set newdict [dict create \
+ top_type m4 \
+ top_contact_type via3 \
+ cap_type mimcap \
+ cap_contact_type mimcc \
+ bot_type m3 \
+ bot_surround 0.5 \
+ cap_spacing 0.5 \
+ cap_surround 0.2 \
+ top_surround 0.005 \
+ end_surround 0.1 \
+ end_spacing 0.60 \
+ contact_size 0.32 \
+ metal_surround 0.08 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::cap_draw $drawdict]
+}
+
+proc sky130::xcmimc2_draw {parameters} {
+ set newdict [dict create \
+ top_type m5 \
+ top_contact_type via4 \
+ cap_type mimcap2 \
+ cap_contact_type mim2cc \
+ bot_type m4 \
+ bot_surround 0.5 \
+ cap_spacing 0.5 \
+ cap_surround 0.2 \
+ top_surround 0.12 \
+ end_surround 0.1 \
+ end_spacing 2.10 \
+ contact_size 1.18 \
+ metal_surround 0.21 \
+ top_metal_width 1.6 \
+ top_metal_space 1.7 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::cap_draw $drawdict]
+}
+
+#endif (MIM)
+
+#----------------------------------------------------------------
+# capacitor: Check device parameters for out-of-bounds values
+#----------------------------------------------------------------
+
+proc sky130::cap_check {parameters} {
+ # In case wmax and/or lmax are undefined
+ set lmax 0
+ set wmax 0
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set l [magic::spice2float $l]
+ set l [magic::3digitpastdecimal $l]
+ set w [magic::spice2float $w]
+ set w [magic::3digitpastdecimal $w]
+
+ set val [magic::spice2float $val]
+ set carea [magic::spice2float $carea]
+ set cperi [magic::spice2float $cperi]
+ set dc [magic::spice2float $dc]
+
+ if {$square == 1} {
+ # Calculate L and W from value
+ set a $carea
+ set b [expr $cperi * 4]
+ set c [expr -4 * $dc - $val]
+ set l [expr ((-$b + sqrt($b * $b - (4 * $a * $c))) / (2 * $a))]
+ dict set parameters l [magic::float2spice $l]
+ set w $l
+ dict set parameters w [magic::float2spice $w]
+ } elseif {$l == 0} {
+ # Calculate L from W and value
+ set l [expr (($val + 4 * $dc - 2 * $w * $cperi) / ($w * $carea + 2 * $cperi))]
+ dict set parameters l [magic::float2spice $l]
+ } elseif {$w == 0} {
+ # Calculate W from L and value
+ set w [expr (($val + 4 * $dc - 2 * $l * $cperi) / ($l * $carea + 2 * $cperi))]
+ dict set parameters w [magic::float2spice $w]
+ }
+ if {$w < $wmin} {
+ puts stderr "Capacitor width must be >= $wmin"
+ dict set parameters w $wmin
+ set w $wmin
+ }
+ if {$l < $lmin} {
+ puts stderr "Capacitor length must be >= $lmin"
+ dict set parameters l $lmin
+ set l $lmin
+ }
+ if {($wmax > 0) && ($w > $wmax)} {
+ puts stderr "Capacitor width must be <= $wmax"
+ dict set parameters w $wmax
+ set w $wmax
+ }
+ if {($lmax > 0) && ($l > $lmax)} {
+ puts stderr "Capacitor length must be <= $lmax"
+ dict set parameters l $lmax
+ set l $lmax
+ }
+ # Calculate value from L and W
+ set cval [expr ($l * $w * $carea + 2 * ($l + $w) * $cperi - 4 * $dc)]
+ dict set parameters val [magic::float2spice $cval]
+ sky130::compute_ctot $parameters
+
+ return $parameters
+}
+
+#ifdef MIM
+proc sky130::xcmimc1_check {parameters} {
+ return [sky130::cap_check $parameters]
+}
+proc sky130::xcmimc2_check {parameters} {
+ return [sky130::cap_check $parameters]
+}
+#endif (MIM)
+
+#----------------------------------------------------------------
+# Drawn resistors
+#----------------------------------------------------------------
+
+#----------------------------------------------------------------
+# Resistor defaults:
+#----------------------------------------------------------------
+# User editable values:
+#
+# val Resistor value in ohms
+# w Width
+# l Length
+# t Number of turns
+# m Number devices in Y
+# nx Number devices in X
+# snake Use snake geometry (if not present, snake geometry not allowed)
+# dummy Flag to mark addition of dummy resistor
+#
+# Non-user editable values:
+#
+# wmin Minimum allowed width
+# lmin Minimum allowed length
+# rho Resistance in ohms per square
+# dw Delta width
+# term Resistance per terminal
+# sterm Additional resistance per terminal for snake geometry
+#----------------------------------------------------------------
+
+#----------------------------------------------------------------
+# xpwres: Specify all user-editable default values and those
+# needed by xpwres_check
+# NOTE: Work in progress. These values need to be corrected.
+#----------------------------------------------------------------
+
+proc sky130::xpwres_defaults {} {
+ return {w 2.650 l 26.50 m 1 nx 1 wmin 2.650 lmin 26.50 \
+ rho 975 val 4875 dummy 0 dw 0.25 term 1.0 \
+ endcov 100 full_metal 1}
+}
+
+#----------------------------------------------------------------
+# rpp1: Specify all user-editable default values and those
+# needed by rp1_check
+#----------------------------------------------------------------
+
+proc sky130::mrp1_defaults {} {
+ return {w 0.330 l 1.650 m 1 nx 1 wmin 0.330 lmin 1.650 \
+ rho 48.2 val 241 dummy 0 dw 0.0 term 0.0 \
+ sterm 0.0 caplen 0.4 snake 0 \
+ glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
+ full_metal 1}
+}
+
+# "term" is rho * 0.06, the distance between xpc edge and CONT.
+proc sky130::xhrpoly_defaults {} {
+ return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
+ rho 319.8 val 456.857 dummy 0 dw 0.0 term 19.188 \
+ sterm 0.0 caplen 0 glc 1 grc 1 gtc 1 gbc 1 \
+ full_metal 1}
+}
+
+# "term" is rho * 0.06, the distance between xpc edge and CONT.
+proc sky130::uhrpoly_defaults {} {
+ return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
+ rho 2000 val 2875.143 dummy 0 dw 0.0 term 120 \
+ sterm 0.0 caplen 0 \
+ glc 1 grc 1 gtc 1 gbc 1 full_metal 1}
+}
+
+#----------------------------------------------------------------
+# mrdn: Specify all user-editable default values and those
+# needed by rdn_check
+#----------------------------------------------------------------
+
+proc sky130::mrdn_defaults {} {
+ return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
+ rho 120 val 600.0 dummy 0 dw 0.05 term 0.0 \
+ sterm 0.0 caplen 0.4 snake 0 \
+ glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
+ full_metal 1}
+}
+
+proc sky130::mrdn_hv_defaults {} {
+ return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
+ rho 120 val 600.0 dummy 0 dw 0.02 term 0.0 \
+ sterm 0.0 caplen 0.4 snake 0 \
+ glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
+ full_metal 1}
+}
+
+#----------------------------------------------------------------
+# mrdp: Specify all user-editable default values and those
+# needed by rdp_check
+#----------------------------------------------------------------
+
+proc sky130::mrdp_defaults {} {
+ return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
+ rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
+ sterm 0.0 caplen 0.60 snake 0 \
+ glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
+ full_metal 1}
+}
+
+proc sky130::mrdp_hv_defaults {} {
+ return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
+ rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
+ sterm 0.0 caplen 0.60 snake 0 \
+ glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
+ full_metal 1}
+}
+
+#----------------------------------------------------------------
+# mrl1: Specify all user-editable default values and those needed
+# by mrl1_check
+#----------------------------------------------------------------
+
+proc sky130::mrl1_defaults {} {
+ return {w 0.170 l 0.170 m 1 nx 1 wmin 0.17 lmin 0.17 \
+ rho 12.8 val 12.8 dummy 0 dw 0.0 term 0.0 snake 0 \
+ roverlap 0}
+}
+
+#----------------------------------------------------------------
+# mrm1: Specify all user-editable default values and those needed
+# by mrm1_check
+#----------------------------------------------------------------
+
+proc sky130::mrm1_defaults {} {
+ return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
+ rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
+ roverlap 0}
+}
+
+#----------------------------------------------------------------
+# mrm2: Specify all user-editable default values and those needed
+# by mrm2_check
+#----------------------------------------------------------------
+
+proc sky130::mrm2_defaults {} {
+ return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
+ rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
+ roverlap 0}
+}
+
+#----------------------------------------------------------------
+# mrm3: Specify all user-editable default values and those needed
+# by mrm3_check
+#----------------------------------------------------------------
+
+proc sky130::mrm3_defaults {} {
+ return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
+ rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
+ roverlap 0}
+}
+
+#----------------------------------------------------------------
+# Additional entries for mrm4 and mrm5, depending on the
+# back-end metal stack.
+#----------------------------------------------------------------
+
+#ifdef METAL5
+proc sky130::mrm4_defaults {} {
+ return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
+ rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
+ roverlap 0}
+}
+proc sky130::mrm5_defaults {} {
+ return {w 1.600 l 1.600 m 1 nx 1 wmin 1.60 lmin 1.60 \
+ rho 0.029 val 0.029 dummy 0 dw 0.0 term 0.0 \
+ roverlap 0}
+}
+#endif (METAL5)
+
+#----------------------------------------------------------------
+# resistor: Conversion from SPICE netlist parameters to toolkit
+#----------------------------------------------------------------
+
+proc sky130::res_convert {parameters} {
+ set pdkparams [dict create]
+ dict for {key value} $parameters {
+ switch -nocase $key {
+ l -
+ w {
+ # Length and width are converted to units of microns
+ set value [magic::spice2float $value]
+ # set value [expr $value * 1e6]
+ set value [magic::3digitpastdecimal $value]
+ dict set pdkparams [string tolower $key] $value
+ }
+ }
+ }
+ return $pdkparams
+}
+
+#----------------------------------------------------------------
+
+proc sky130::xpwres_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrp1_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::xhrpoly_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::uhrpoly_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrdn_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrdp_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrdn_hv_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrdp_hv_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrl1_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrm1_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrm2_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+proc sky130::mrm3_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+
+#ifdef METAL5
+proc sky130::mrm4_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+proc sky130::mrm5_convert {parameters} {
+ return [sky130::res_convert $parameters]
+}
+#endif (METAL5)
+
+#----------------------------------------------------------------
+# resistor: Interactively specifies the fixed layout parameters
+#----------------------------------------------------------------
+
+proc sky130::res_dialog {device parameters} {
+ # Editable fields: w, l, t, nx, m, val
+ # Checked fields:
+
+ magic::add_entry val "Value (ohms)" $parameters
+ if {[dict exists $parameters snake]} {
+ sky130::compute_ltot $parameters
+ magic::add_message ltot "Total length (um)" $parameters
+ }
+ magic::add_entry l "Length (um)" $parameters
+ magic::add_entry w "Width (um)" $parameters
+ magic::add_entry nx "X Repeat" $parameters
+ magic::add_entry m "Y Repeat" $parameters
+ if {[dict exists $parameters endcov]} {
+ magic::add_entry endcov "End contact coverage (%)" $parameters
+ }
+
+ # magic::add_checkbox dummy "Add dummy" $parameters
+
+ if {[dict exists $parameters snake]} {
+ magic::add_checkbox snake "Use snake geometry" $parameters
+ }
+ if {[dict exists $parameters roverlap]} {
+ if {[dict exists $parameters endcov]} {
+ magic::add_checkbox roverlap "Overlap at end contact" $parameters
+ } else {
+ magic::add_checkbox roverlap "Overlap at ends" $parameters
+ }
+ }
+ magic::add_checkbox guard "Add guard ring" $parameters
+
+ if {[dict exists $parameters full_metal]} {
+ magic::add_checkbox full_metal "Full metal guard ring" $parameters
+ }
+ if {[dict exists $parameters glc]} {
+ magic::add_checkbox glc "Add left guard ring contact" $parameters
+ }
+ if {[dict exists $parameters grc]} {
+ magic::add_checkbox grc "Add right guard ring contact" $parameters
+ }
+ if {[dict exists $parameters gtc]} {
+ magic::add_checkbox gtc "Add top guard ring contact" $parameters
+ }
+ if {[dict exists $parameters gbc]} {
+ magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
+ }
+
+ if {[dict exists $parameters snake]} {
+ magic::add_dependency sky130::res_recalc $device sky130 l w val nx snake
+ } else {
+ magic::add_dependency sky130::res_recalc $device sky130 l w val nx
+ }
+}
+
+#----------------------------------------------------------------
+
+proc sky130::xpwres_dialog {parameters} {
+ sky130::res_dialog xpwres $parameters
+}
+
+proc sky130::mrp1_dialog {parameters} {
+ sky130::res_dialog mrp1 $parameters
+}
+
+proc sky130::xhrpoly_dialog {parameters} {
+ sky130::res_dialog xhrpoly $parameters
+}
+
+proc sky130::uhrpoly_dialog {parameters} {
+ sky130::res_dialog uhrpoly $parameters
+}
+
+proc sky130::mrdn_dialog {parameters} {
+ sky130::res_dialog mrdn $parameters
+}
+
+proc sky130::mrdp_dialog {parameters} {
+ sky130::res_dialog mrdp $parameters
+}
+
+proc sky130::mrdn_hv_dialog {parameters} {
+ sky130::res_dialog mrdn_hv $parameters
+}
+
+proc sky130::mrdp_hv_dialog {parameters} {
+ sky130::res_dialog mrdp_hv $parameters
+}
+
+proc sky130::mrl1_dialog {parameters} {
+ sky130::res_dialog mrl1 $parameters
+}
+
+proc sky130::mrm1_dialog {parameters} {
+ sky130::res_dialog mrm1 $parameters
+}
+
+proc sky130::mrm2_dialog {parameters} {
+ sky130::res_dialog mrm2 $parameters
+}
+
+proc sky130::mrm3_dialog {parameters} {
+ sky130::res_dialog mrm3 $parameters
+}
+
+#ifdef METAL5
+proc sky130::mrm4_dialog {parameters} {
+ sky130::res_dialog mrm4 $parameters
+}
+proc sky130::mrm5_dialog {parameters} {
+ sky130::res_dialog mrm5 $parameters
+}
+#endif (METAL5)
+
+#----------------------------------------------------------------
+# Resistor: Draw a single device in straight geometry
+#----------------------------------------------------------------
+
+proc sky130::res_device {parameters} {
+ # Epsilon for avoiding round-off errors
+ set eps 0.0005
+
+ # Set local default values if they are not in parameters
+ set endcov 0 ;# percent coverage of end contacts
+ set roverlap 0 ;# overlap resistors at end contacts
+ set well_res_overlap 0 ;# not a well resistor
+ set end_contact_type "" ;# no contacts for metal resistors
+ set end_overlap_cont 0 ;# additional end overlap on sides
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ if {![dict exists $parameters end_contact_size]} {
+ set end_contact_size $contact_size
+ }
+
+ # Draw the resistor and endcaps
+ pushbox
+ box size 0 0
+ pushbox
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+ box grow n ${hl}um
+ box grow s ${hl}um
+ box grow e ${hw}um
+ box grow w ${hw}um
+
+ pushbox
+ box grow n ${res_to_endcont}um
+ box grow s ${res_to_endcont}um
+ if {$well_res_overlap > 0} {
+ set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
+ box grow n ${well_extend}um
+ box grow s ${well_extend}um
+ paint ${well_res_type}
+ } else {
+ paint ${end_type}
+ }
+ set cext [sky130::getbox]
+ popbox
+
+ if {$well_res_overlap > 0} {
+ erase ${well_res_type}
+ } else {
+ erase ${end_type}
+ }
+ paint ${res_type}
+ popbox
+
+ # Reduce contact sizes by (end type) surround so that
+ # the contact area edges match the device type width.
+ # (Minimum dimensions will be enforced by the contact drawing routine)
+ set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
+
+ # Reduce end material size for well resistor types
+ if {$well_res_overlap > 0} {
+ set epl [- ${epl} [* ${well_res_overlap} 2]]
+ }
+
+ # Reduce by coverage percentage unless overlapping at contacts
+ if {(${roverlap} == 0) && (${endcov} > 0)} {
+ set cpl [* ${epl} [/ ${endcov} 100.0]]
+ } else {
+ set cpl $epl
+ }
+
+ # Ensure additional overlap of diffusion contact if required
+ set dov [* ${end_overlap_cont} 2]
+ if {[- ${epl} ${cpl}] < $dov} {
+ set cpl [- ${epl} $dov] ;# additional end contact width
+ }
+
+ set hepl [+ [/ ${epl} 2.0] ${end_surround}]
+ set hesz [/ ${end_contact_size} 2.0]
+
+ # LV substrate diffusion types have a different surround requirement
+ set lv_sub_types {"psd" "nsd"}
+ if {[lsearch $lv_sub_types $end_type] < 0} {
+ set hesz [+ ${hesz} ${end_surround}]
+ }
+
+ # Top end material & contact
+ pushbox
+ box move n ${hl}um
+ box move n ${res_to_endcont}um
+
+ pushbox
+ box size 0 0
+ box grow n ${hesz}um
+ box grow s ${hesz}um
+ box grow e ${hepl}um
+ box grow w ${hepl}um
+ paint ${end_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ popbox
+
+ if {${end_contact_type} != ""} {
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
+ ${end_surround} ${metal_surround} ${end_contact_size} \
+ ${end_type} ${end_contact_type} li horz]]
+ }
+ popbox
+
+ # Bottom end material & contact
+ pushbox
+ box move s ${hl}um
+ box move s ${res_to_endcont}um
+
+ pushbox
+ box size 0 0
+ box grow n ${hesz}um
+ box grow s ${hesz}um
+ box grow e ${hepl}um
+ box grow w ${hepl}um
+ paint ${end_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ popbox
+
+ if {${end_contact_type} != ""} {
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
+ ${end_surround} ${metal_surround} ${end_contact_size} \
+ ${end_type} ${end_contact_type} li horz]]
+ }
+ popbox
+
+ popbox
+ return $cext
+}
+
+#----------------------------------------------------------------
+# Resistor: Draw a single device in snake geometry
+#----------------------------------------------------------------
+
+proc sky130::res_snake_device {nf parameters} {
+ # nf is the number of fingers of the snake geometry
+
+ # Epsilon for avoiding round-off errors
+ set eps 0.0005
+
+ # Set local default values if they are not in parameters
+ set endcov 100 ;# percent coverage of end contacts
+ set well_res_overlap 0 ;# not a well resistor
+ set end_contact_type "" ;# no contacts for metal resistors
+ set mask_clearance 0 ;# additional length to clear mask
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ if {![dict exists $parameters end_contact_size]} {
+ set end_contact_size $contact_size
+ }
+
+ # Compute half width and length
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+
+ # Reduce contact sizes by (end type) surround so that
+ # the contact area edges match the device type width.
+ # (Minimum dimensions will be enforced by the contact drawing routine)
+ set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
+
+ # Reduce contact size for well resistor types
+ if {$well_res_overlap > 0} {
+ set epl [- ${epl} [* ${well_res_overlap} 2]]
+ }
+
+ # Reduce contact part of end by coverage percentage
+ if {${endcov} > 0} {
+ set cpl [* ${epl} [/ ${endcov} 100.0]]
+ } else {
+ set cpl $epl
+ }
+
+ set hepl [+ [/ ${epl} 2.0] ${end_surround}]
+ set hesz [+ [/ ${end_contact_size} 2.0] ${end_surround}]
+
+ pushbox
+ box size 0 0 ;# Position is taken from caller
+
+ # Front end contact (always bottom)
+ pushbox
+ box move s ${hl}um
+ pushbox
+ box move s ${mask_clearance}um
+ box move s ${res_to_endcont}um
+
+ pushbox
+ box size 0 0
+ box grow n ${hesz}um
+ box grow s ${hesz}um
+ box grow e ${hepl}um
+ box grow w ${hepl}um
+ paint ${end_type}
+ set cext [sky130::getbox]
+ popbox
+
+ if {${end_contact_type} != ""} {
+ set cext [sky130::draw_contact ${cpl} 0 \
+ ${end_surround} ${metal_surround} ${end_contact_size} \
+ ${end_type} ${end_contact_type} li horz]
+ }
+ popbox
+
+ # Draw portion between resistor end and contact.
+ box grow e ${hw}um
+ box grow w ${hw}um
+ pushbox
+ box grow s ${mask_clearance}um
+ paint ${res_type}
+ popbox
+ box move s ${mask_clearance}um
+ box grow s ${res_to_endcont}um
+ if {$well_res_overlap > 0} {
+ set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
+ box grow s ${well_extend}um
+ paint ${well_res_type}
+ } else {
+ paint ${end_type}
+ }
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ popbox
+
+ # Draw the resistor and endcaps
+ pushbox
+ box grow n ${hl}um
+ box grow s ${hl}um
+ box grow e ${hw}um
+ box grow w ${hw}um
+
+ # Capture these extents in the bounding box in case both contacts
+ # are on one side.
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+
+ set deltax [+ ${res_spacing} ${w}]
+ set deltay [- ${l} ${w}]
+ for {set i 0} {$i < [- $nf 1]} {incr i} {
+ paint ${res_type}
+ pushbox
+ if {[% $i 2] == 0} {
+ box move n ${deltay}um
+ }
+ box height ${w}um
+ box width ${deltax}um
+ paint ${res_type}
+ popbox
+ box move e ${deltax}um
+ }
+ paint ${res_type}
+ # Capture these extents in the bounding box
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ popbox
+
+ # Move box to last finger
+ set lastf [* [- $nf 1] $deltax]
+ box move e ${lastf}um
+
+ # Back-end contact (top or bottom, depending if odd or even turns)
+ pushbox
+
+ if {[% $nf 2] == 1} {
+ set dir n
+ } else {
+ set dir s
+ }
+ box move $dir ${hl}um
+ pushbox
+ box move $dir ${mask_clearance}um
+ box move $dir ${res_to_endcont}um
+
+ pushbox
+ box size 0 0
+ box grow n ${hesz}um
+ box grow s ${hesz}um
+ box grow e ${hepl}um
+ box grow w ${hepl}um
+ paint ${end_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ popbox
+
+ if {${end_contact_type} != ""} {
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
+ ${end_surround} ${metal_surround} ${end_contact_size} \
+ ${end_type} ${end_contact_type} li horz]]
+ }
+ popbox
+ # Draw portion between resistor end and contact.
+ box grow e ${hw}um
+ box grow w ${hw}um
+ pushbox
+ box grow $dir ${mask_clearance}um
+ paint ${res_type}
+ popbox
+ box move $dir ${mask_clearance}um
+ box grow $dir ${res_to_endcont}um
+
+ if {$well_res_overlap > 0} {
+ set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
+ box grow $dir ${well_extend}um
+ paint ${well_res_type}
+ } else {
+ paint ${end_type}
+ }
+ popbox
+
+ popbox
+ return $cext
+}
+
+#----------------------------------------------------------------
+# Resistor: Draw the tiled device
+#----------------------------------------------------------------
+
+proc sky130::res_draw {parameters} {
+ tech unlock *
+ set savesnap [snap]
+ snap internal
+
+ # Set defaults if they are not in parameters
+ set snake 0 ;# some resistors don't allow snake geometry
+ set roverlap 0 ;# overlap resistors at contacts
+ set guard 1 ;# draw a guard ring
+ set plus_diff_type nsd ;# guard ring diffusion type
+ set overlap_compress 0 ;# special Y distance compression
+ set well_res_overlap 0 ;# additional well extension behind contact
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # For devices where inter-device space is smaller than device-to-guard ring
+ if {![dict exists $parameters end_to_end_space]} {
+ set end_to_end_space $end_spacing
+ }
+
+ if {![dict exists $parameters end_contact_size]} {
+ set end_contact_size $contact_size
+ }
+
+ # Normalize distance units to microns
+ set w [magic::spice2float $w]
+ set l [magic::spice2float $l]
+
+ pushbox
+ box values 0 0 0 0
+
+ # Determine the base device dimensions by drawing one device
+ # while all layers are locked (nothing drawn). This allows the
+ # base drawing routine to do complicated geometry without having
+ # to duplicate it here with calculations.
+
+ tech lock *
+ set nf $nx
+ if {($snake == 1) && ($nx == 1)} {set snake 0}
+ if {$snake == 1} {
+ set bbox [sky130::res_snake_device $nf $parameters]
+ set nx 1
+ } else {
+ set bbox [sky130::res_device $parameters]
+ }
+ # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
+ tech unlock *
+
+ set fw [- [lindex $bbox 2] [lindex $bbox 0]]
+ set fh [- [lindex $bbox 3] [lindex $bbox 1]]
+ set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
+ set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
+
+ # Determine tile width and height (depends on overlap)
+ # Snake resistors cannot overlap.
+ # However, snake resistors with an odd number of fingers can
+ # compress the space if overlap_compress is defined
+
+ if {($roverlap == 1) && ($snake == 1) && ([% $nf 2] == 1) && ($m > 1)} {
+ set dy [- $fh $overlap_compress]
+ } elseif {($roverlap == 0) || ($snake == 1)} {
+ set dy [+ $fh $end_to_end_space]
+ } else {
+ # overlap poly
+ set dy [- $fh [+ [* [+ $end_surround $well_res_overlap] 2.0] $end_contact_size]]
+ }
+ set dx [+ $fw $res_spacing]
+
+ # Determine core width and height
+ set corex [+ [* [- $nx 1] $dx] $fw]
+ set corey [+ [* [- $m 1] $dy] $fh]
+ set corellx [/ [+ [- $corex $fw] $lw] 2.0]
+ set corelly [/ [+ [- $corey $fh] $lh] 2.0]
+
+ set lv_sub_types {"psd" "nsd"}
+ if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
+ set guard_diff_surround 0
+ } else {
+ set guard_diff_surround ${diff_surround}
+ }
+
+ if {$guard != 0} {
+ # Calculate guard ring size (measured to contact center)
+ set gx [+ $corex [* 2.0 [+ $res_diff_spacing $guard_diff_surround]] $contact_size]
+ set gy [+ $corey [* 2.0 [+ $end_spacing $guard_diff_surround]] $contact_size]
+
+ # Draw the guard ring first, because well resistors are on the substrate plane
+ sky130::guard_ring $gx $gy $parameters
+ }
+
+ pushbox
+ box move w ${corellx}um
+ box move s ${corelly}um
+ # puts "Device position at = [sky130::getbox]"
+ for {set xp 0} {$xp < $nx} {incr xp} {
+ pushbox
+ for {set yp 0} {$yp < $m} {incr yp} {
+ if {$snake == 1} {
+ sky130::res_snake_device $nf $parameters
+ } else {
+ sky130::res_device $parameters
+ }
+ box move n ${dy}um
+ }
+ popbox
+ box move e ${dx}um
+ }
+ popbox
+ popbox
+
+ snap $savesnap
+ tech revert
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrp1_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type npres \
+ end_type poly \
+ end_contact_type pc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ sub_type nwell \
+ end_surround $poly_surround \
+ end_spacing 0.48 \
+ end_to_end_space 0.52 \
+ res_to_endcont $res_to_cont \
+ res_spacing $poly_spacing \
+ res_diff_spacing 0.48 \
+ mask_clearance 0.52 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::xhrpoly_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type ppres \
+ end_type xpc \
+ end_contact_type xpc \
+ end_contact_size 0 \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ end_surround $poly_surround \
+ end_spacing 0.48 \
+ end_to_end_space 0.52 \
+ end_contact_size 0.19 \
+ res_to_endcont 1.985 \
+ res_spacing 1.24 \
+ res_diff_spacing 0.48 \
+ mask_clearance 0.52 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::uhrpoly_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type xpres \
+ end_type xpc \
+ end_contact_type xpc \
+ end_contact_size 0 \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ end_surround $poly_surround \
+ end_spacing 0.48 \
+ end_to_end_space 0.52 \
+ end_contact_size 0.19 \
+ res_to_endcont 1.985 \
+ res_spacing 1.24 \
+ res_diff_spacing 0.48 \
+ mask_clearance 0.52 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrdn_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type rdn \
+ end_type ndiff \
+ end_contact_type ndc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ sub_type psub \
+ end_surround $diff_surround \
+ end_spacing 0.44 \
+ res_to_endcont 0.37 \
+ res_spacing 0.30 \
+ res_diff_spacing 0.44 \
+ mask_clearance 0.22 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrdn_hv_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type mvrdn \
+ end_type mvndiff \
+ end_contact_type mvndc \
+ plus_diff_type mvpsd \
+ plus_contact_type mvpsc \
+ sub_type psub \
+ end_surround $diff_surround \
+ end_spacing 0.44 \
+ res_to_endcont 0.37 \
+ res_spacing 0.30 \
+ res_diff_spacing 0.44 \
+ mask_clearance 0.22 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrdp_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type rdp \
+ end_type pdiff \
+ end_contact_type pdc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ sub_type nwell \
+ end_surround $diff_surround \
+ end_spacing 0.44 \
+ res_to_endcont 0.37 \
+ res_spacing $diff_spacing \
+ res_diff_spacing 0.44 \
+ mask_clearance 0.22 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrdp_hv_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ res_type mvrdp \
+ end_type mvpdiff \
+ end_contact_type mvpdc \
+ plus_diff_type mvnsd \
+ plus_contact_type mvnsc \
+ sub_type nwell \
+ end_surround $diff_surround \
+ guard_sub_surround 0.33 \
+ end_spacing 0.44 \
+ res_to_endcont 0.37 \
+ res_spacing 0.30 \
+ res_diff_spacing 0.44 \
+ mask_clearance 0.22 \
+ overlap_compress 0.36 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::xpwres_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ well_res_type pwell \
+ res_type rpw \
+ end_type psd \
+ end_contact_type psc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ sub_type dnwell \
+ sub_surround 0.23 \
+ guard_sub_type nwell \
+ guard_sub_surround 0.63 \
+ end_surround $diff_surround \
+ end_spacing 0.63 \
+ end_to_end_space 1.15 \
+ end_overlap_cont 0.06 \
+ end_contact_size 0.53 \
+ overlap_compress -0.17 \
+ res_to_endcont 0.265 \
+ res_spacing 1.4 \
+ res_diff_spacing 0.63 \
+ well_res_overlap 0.2 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrl1_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rli \
+ end_type li \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ res_to_endcont 0.2 \
+ end_to_end_space 0.23 \
+ res_spacing $metal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrm1_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rm1 \
+ end_type m1 \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ end_to_end_space 0.28 \
+ res_to_endcont 0.2 \
+ res_spacing $mmetal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrm2_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rm2 \
+ end_type m2 \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ end_to_end_space 0.28 \
+ res_to_endcont 0.2 \
+ res_spacing $mmetal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+proc sky130::mrm3_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rm3 \
+ end_type m3 \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ end_to_end_space 0.28 \
+ res_to_endcont 0.2 \
+ res_spacing $mmetal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+
+#ifdef METAL5
+proc sky130::mrm4_draw {parameters} {
+
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rm4 \
+ end_type m4 \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ end_to_end_space 0.28 \
+ res_to_endcont 0.2 \
+ res_spacing $mmetal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+
+proc sky130::mrm5_draw {parameters} {
+ # Set a local variable for each rule in ruleset
+ foreach key [dict keys $sky130::ruleset] {
+ set $key [dict get $sky130::ruleset $key]
+ }
+
+ set newdict [dict create \
+ guard 0 \
+ res_type rm5 \
+ end_type m5 \
+ end_surround 0.0 \
+ end_spacing 0.0 \
+ end_to_end_space 1.6 \
+ res_to_endcont 0.2 \
+ res_spacing $mmetal_spacing \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::res_draw $drawdict]
+}
+#endif (METAL5)
+
+#----------------------------------------------------------------
+# Resistor total length computation
+#----------------------------------------------------------------
+
+proc sky130::compute_ltot {parameters} {
+ # In case snake not defined
+ set snake 0
+ set caplen 0
+
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ set l [magic::spice2float $l]
+ set l [magic::3digitpastdecimal $l]
+
+ # Compute total length. Use catch to prevent error in batch/scripted mode.
+ if {$snake == 1} {
+ catch {set magic::ltot_val [expr ($caplen * ($nx - 1)) + ($l * $nx) + ($nx - 1)]}
+ } else {
+ catch {set magic::ltot_val $l}
+ }
+}
+
+#----------------------------------------------------------------
+# resistor: Check device parameters for out-of-bounds values
+#----------------------------------------------------------------
+
+proc sky130::res_check {device parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ set snake 0
+ set sterm 0.0
+ set caplen 0
+
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set w [magic::spice2float $w]
+ set w [magic::3digitpastdecimal $w]
+ set l [magic::spice2float $l]
+ set l [magic::3digitpastdecimal $l]
+
+ set val [magic::spice2float $val]
+ set rho [magic::spice2float $rho]
+
+ # nf, m must be integer
+ if {![string is int $nx]} {
+ puts stderr "X repeat must be an integer!"
+ dict set parameters nx 1
+ }
+ if {![string is int $m]} {
+ puts stderr "Y repeat must be an integer!"
+ dict set parameters m 1
+ }
+
+ # Width always needs to be specified
+ if {$w < $wmin} {
+ puts stderr "Resistor width must be >= $wmin um"
+ dict set parameters w $wmin
+ }
+ # Val and W specified - no L
+ if {$l == 0} {
+ set l [expr ($w - $dw) * $val / $rho]
+ set l [magic::3digitpastdecimal $l]
+ set stringval [magic::float2spice $val]
+ dict set parameters l [magic::float2spice [expr $l * 1e-6]]
+ # L and W specified - ignore Val if specified
+ } else {
+ if {$snake == 0} {
+ set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
+ } else {
+ set val [expr $rho * ($nx - 1) + ((2 * ($term + $sterm)) \
+ + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
+ / ($w - $dw)]
+ }
+ set val [magic::float2spice $val]
+ dict set parameters val $val
+ }
+ if {$l < $lmin} {
+ puts stderr "Resistor length must be >= $lmin um"
+ dict set parameters l $lmin
+ }
+ if {$nx < 1} {
+ puts stderr "X repeat must be >= 1"
+ dict set parameters nx 1
+ }
+ if {$m < 1} {
+ puts stderr "Y repeat must be >= 1"
+ dict set parameters m 1
+ }
+
+ # Snake resistors cannot have width greater than length
+ if {$snake == 1} {
+ if {$w > $l} {
+ puts stderr "Snake resistor width must be < length"
+ dict set parameters w $l
+ }
+ }
+
+ # Diffusion resistors must satisfy diffusion-to-tap spacing of 20um.
+ # Therefore the maximum of guard ring width or height cannot exceed 40um.
+ # If in violation, reduce counts first, as these are easiest to recover
+ # by duplicating the device and overlapping the wells.
+ if {$device == "rdn" || $device == "rdp"} {
+ set origm $m
+ set orignx $nx
+ while true {
+ set xext [expr ($w + 0.8) * $nx + 1.0]
+ set yext [expr ($l + 1.7) * $m + 1.7]
+ if {[expr min($xext, $yext)] > 40.0} {
+ if {$yext > 40.0 && $m > 1} {
+ incr m -1
+ } elseif {$xext > 40.0 && $nx > 1} {
+ incr nx -1
+ } elseif {$yext > 40.0} {
+ set l 36.6
+ puts -nonewline stderr "Diffusion resistor length must be < 36.6 um"
+ puts stderr " to avoid tap spacing violation."
+ dict set parameters l $l
+ } elseif {$xext > 40.0} {
+ set w 38.2
+ puts -nonewline stderr "Diffusion resistor width must be < 38.2 um"
+ puts stderr " to avoid tap spacing violation."
+ dict set parameters w $w
+ }
+ } else {
+ break
+ }
+ }
+ if {$m != $origm} {
+ puts stderr "Y repeat reduced to prevent tap distance violation"
+ dict set parameters m $m
+ }
+ if {$nx != $orignx} {
+ puts stderr "X repeat reduced to prevent tap distance violation"
+ dict set parameters nx $nx
+ }
+ }
+ sky130::compute_ltot $parameters
+ return $parameters
+}
+
+#----------------------------------------------------------------
+
+proc sky130::xpwres_check {parameters} {
+ return [sky130::res_check xpwres $parameters]
+}
+
+proc sky130::mrp1_check {parameters} {
+ return [sky130::res_check mrp1 $parameters]
+}
+
+proc sky130::xhrpoly_check {parameters} {
+ return [sky130::res_check xhrpoly $parameters]
+}
+
+proc sky130::uhrpoly_check {parameters} {
+ return [sky130::res_check uhrpoly $parameters]
+}
+
+proc sky130::mrdn_check {parameters} {
+ return [sky130::res_check mrdn $parameters]
+}
+
+proc sky130::mrdp_check {parameters} {
+ return [sky130::res_check mrdp $parameters]
+}
+
+proc sky130::mrdn_hv_check {parameters} {
+ return [sky130::res_check mrdn_hv $parameters]
+}
+
+proc sky130::mrdp_hv_check {parameters} {
+ return [sky130::res_check mrdp_hv $parameters]
+}
+
+proc sky130::mrl1_check {parameters} {
+ return [sky130::res_check mrl1 $parameters]
+}
+
+proc sky130::mrm1_check {parameters} {
+ return [sky130::res_check mrm1 $parameters]
+}
+
+proc sky130::mrm2_check {parameters} {
+ return [sky130::res_check mrm2 $parameters]
+}
+
+proc sky130::mrm3_check {parameters} {
+ return [sky130::res_check mrm3 $parameters]
+}
+
+#ifdef METAL5
+proc sky130::mrm4_check {parameters} {
+ return [sky130::res_check mrm4 $parameters]
+}
+proc sky130::mrm5_check {parameters} {
+ return [sky130::res_check mrm5 $parameters]
+}
+#endif (METAL5)
+
+#----------------------------------------------------------------
+# MOS defaults:
+#----------------------------------------------------------------
+# w = Gate width
+# l = Gate length
+# m = Multiplier
+# nf = Number of fingers
+# diffcov = Diffusion contact coverage
+# polycov = Poly contact coverage
+# topc = Top gate contact
+# botc = Bottom gate contact
+# guard = Guard ring
+#
+# (not user-editable)
+#
+# lmin = Gate minimum length
+# wmin = Gate minimum width
+#----------------------------------------------------------------
+
+#----------------------------------------------------------------
+# pmos: Specify all user-editable default values and those
+# needed by mos_check
+#----------------------------------------------------------------
+
+proc sky130::pshort_defaults {} {
+ return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
+ compatible {pshort plowvt phighvt phv} full_metal 1}
+}
+
+proc sky130::plowvt_defaults {} {
+ return {w 0.42 l 0.35 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.35 wmin 0.42 \
+ compatible {pshort plowvt phighvt phv} full_metal 1}
+}
+
+proc sky130::phighvt_defaults {} {
+ return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
+ compatible {pshort plowvt phighvt phv} full_metal 1}
+}
+
+proc sky130::phv_defaults {} {
+ return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
+ compatible {pshort plowvt phighvt phv} full_metal 1}
+}
+
+#----------------------------------------------------------------
+# nmos: Specify all user-editable default values and those
+# needed by mos_check
+#----------------------------------------------------------------
+
+proc sky130::nshort_defaults {} {
+ return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
+ compatible {nshort nlowvt sonos_e nhv nhvnative} full_metal 1}
+}
+
+proc sky130::nlowvt_defaults {} {
+ return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
+ compatible {nshort nlowvt sonos_e nhv nhvnative} full_metal 1}
+}
+
+proc sky130::sonos_e_defaults {} {
+ return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
+ compatible {nshort nlowvt sonos_e nhv nhvnative} full_metal 1}
+}
+
+proc sky130::nhv_defaults {} {
+ return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
+ compatible {nshort nlowvt sonos_e nhv nhvnative} full_metal 1}
+}
+
+proc sky130::nhvnative_defaults {} {
+ return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
+ compatible {nshort nlowvt sonos_e nhv nhvnative} full_metal 1}
+}
+
+#----------------------------------------------------------------
+# mos varactor: Specify all user-editable default values and those
+# needed by mosvc_check
+#----------------------------------------------------------------
+
+proc sky130::xcnwvc_defaults {} {
+ return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
+ compatible {xcnwvc xcnwvc2 xchvnwc} full_metal 1}
+}
+
+proc sky130::xcnwvc2_defaults {} {
+ return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
+ compatible {xcnwvc xcnwvc2 xchvnwc} full_metal 1}
+}
+
+proc sky130::xchvnwc_defaults {} {
+ return {w 1.0 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
+ guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
+ topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 1.0 \
+ compatible {xcnwvc xcnwvc2 xchvnwc} full_metal 1}
+}
+
+#----------------------------------------------------------------
+# mos: Conversion from SPICE netlist parameters to toolkit
+#----------------------------------------------------------------
+
+proc sky130::mos_convert {parameters} {
+ set pdkparams [dict create]
+ dict for {key value} $parameters {
+ switch -nocase $key {
+ l -
+ w {
+ # Length and width are converted to units of microns
+ set value [magic::spice2float $value]
+ # set value [expr $value * 1e6]
+ set value [magic::3digitpastdecimal $value]
+ dict set pdkparams [string tolower $key] $value
+ }
+ m {
+ # M value in an expression like '1*1' convert to
+ # M and NF
+ if {[regexp {\'([0-9]+)\*([0-9]+)\'} $value valid m nf]} {
+ dict set pdkparams [string tolower $key] $m
+ dict set pdkparams nf $nf
+ } else {
+ dict set pdkparams [string tolower $key] $value
+ }
+ }
+ }
+ }
+ return $pdkparams
+}
+
+#----------------------------------------------------------------
+
+proc sky130::nshort_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::nlowvt_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::sonos_e_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::nhv_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::nhvnative_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::pshort_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::plowvt_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::phighvt_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::phv_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::xcnwvc_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::xcnwvc2_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+proc sky130::xchvnwc_convert {parameters} {
+ return [sky130::mos_convert $parameters]
+}
+
+#----------------------------------------------------------------
+# mos: Interactively specifies the fixed layout parameters
+#----------------------------------------------------------------
+
+proc sky130::mos_dialog {device parameters} {
+ # Editable fields: w, l, nf, m, diffcov, polycov
+ # Checked fields: topc, botc
+ # For specific devices, gate type is a selection list
+
+ magic::add_entry w "Width (um)" $parameters
+ magic::add_entry l "Length (um)" $parameters
+ magic::add_entry nf "Fingers" $parameters
+ magic::add_entry m "M" $parameters
+
+ if {[dict exists $parameters compatible]} {
+ set sellist [dict get $parameters compatible]
+ magic::add_selectlist gencell "Device type" $sellist $parameters $device
+ }
+
+ magic::add_entry diffcov "Diffusion contact coverage (%)" $parameters
+ magic::add_entry polycov "Poly contact coverage (%)" $parameters
+ magic::add_entry rlcov "Guard ring contact coverage (%)" $parameters
+ if {[dict exists $parameters gbc]} {
+ magic::add_entry tbcov "Guard ring top/bottom contact coverage (%)" $parameters
+ }
+
+ magic::add_checkbox poverlap "Overlap at poly contact" $parameters
+ magic::add_checkbox doverlap "Overlap at diffusion contact" $parameters
+ magic::add_checkbox topc "Add top gate contact" $parameters
+ magic::add_checkbox botc "Add bottom gate contact" $parameters
+
+ magic::add_checkbox guard "Add guard ring" $parameters
+ magic::add_checkbox full_metal "Full metal guard ring" $parameters
+ magic::add_checkbox glc "Add left guard ring contact" $parameters
+ magic::add_checkbox grc "Add right guard ring contact" $parameters
+ if {[dict exists $parameters gbc]} {
+ magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
+ }
+ if {[dict exists $parameters gtc]} {
+ magic::add_checkbox gtc "Add top guard ring contact" $parameters
+ }
+}
+
+#----------------------------------------------------------------
+
+proc sky130::nshort_dialog {parameters} {
+ sky130::mos_dialog nshort $parameters
+}
+
+proc sky130::nlowvt_dialog {parameters} {
+ sky130::mos_dialog nlowvt $parameters
+}
+
+proc sky130::sonos_e_dialog {parameters} {
+ sky130::mos_dialog sonos_e $parameters
+}
+
+proc sky130::nhv_dialog {parameters} {
+ sky130::mos_dialog nhv $parameters
+}
+
+proc sky130::nhvnative_dialog {parameters} {
+ sky130::mos_dialog nhvnative $parameters
+}
+
+proc sky130::pshort_dialog {parameters} {
+ sky130::mos_dialog pshort $parameters
+}
+
+proc sky130::plowvt_dialog {parameters} {
+ sky130::mos_dialog plowvt $parameters
+}
+
+proc sky130::phighvt_dialog {parameters} {
+ sky130::mos_dialog phighvt $parameters
+}
+
+proc sky130::phv_dialog {parameters} {
+ sky130::mos_dialog phv $parameters
+}
+
+proc sky130::xcnwvc_dialog {parameters} {
+ sky130::mos_dialog xcnwvc $parameters
+}
+
+proc sky130::xcnwvc2_dialog {parameters} {
+ sky130::mos_dialog xcnwvc2 $parameters
+}
+
+proc sky130::xchvnwc_dialog {parameters} {
+ sky130::mos_dialog xchvnwc $parameters
+}
+
+#----------------------------------------------------------------
+# getbox: Get the current cursor box, in microns
+#----------------------------------------------------------------
+
+proc sky130::getbox {} {
+ set curbox [box values]
+ set newbox []
+ set oscale [cif scale out]
+ for {set i 0} {$i < 4} {incr i} {
+ set v [* [lindex $curbox $i] $oscale]
+ lappend newbox $v
+ }
+ return $newbox
+}
+
+#----------------------------------------------------------------
+# unionbox: Get the union bounding box of box1 and box2
+#----------------------------------------------------------------
+
+proc sky130::unionbox {box1 box2} {
+ set newbox []
+ for {set i 0} {$i < 2} {incr i} {
+ set v [lindex $box1 $i]
+ set o [lindex $box2 $i]
+ if {$v < $o} {
+ lappend newbox $v
+ } else {
+ lappend newbox $o
+ }
+ }
+ for {set i 2} {$i < 4} {incr i} {
+ set v [lindex $box1 $i]
+ set o [lindex $box2 $i]
+ if {$v > $o} {
+ lappend newbox $v
+ } else {
+ lappend newbox $o
+ }
+ }
+ return $newbox
+}
+
+#----------------------------------------------------------------
+# Draw a contact
+#----------------------------------------------------------------
+
+proc sky130::draw_contact {w h s o x atype ctype mtype {orient vert}} {
+
+ # Draw a minimum-size diff contact centered at current position
+ # w is width, h is height. Minimum size ensured.
+ # x is contact size
+ # s is contact diffusion (or poly) surround
+ # o is contact metal surround
+ # atype is active (e.g., ndiff) or bottom metal if a via
+ # ctype is contact (e.g., ndc)
+ # mtype is metal (e.g., m1) or top metal if a via
+ # orient is the orientation of the contact
+
+ # Set orientations for the bottom material based on material type.
+ # Substrate diffusions (tap) need not overlap the contact in all
+ # directions, but other (diff) types do. The metal (local
+ # interconnect) layer always overlaps in two directions only.
+
+ set lv_sub_types {"psd" "nsd"}
+ if {[lsearch $lv_sub_types $atype] >= 0} {
+ set aorient $orient
+ } else {
+ set aorient "full"
+ }
+
+ pushbox
+ box size 0 0
+ if {$w < $x} {set w $x}
+ if {$h < $x} {set h $x}
+ set hw [/ $w 2.0]
+ set hh [/ $h 2.0]
+ box grow n ${hh}um
+ box grow s ${hh}um
+ box grow e ${hw}um
+ box grow w ${hw}um
+ paint ${ctype}
+ pushbox
+ # Bottom layer surrounded on sides as declared by aorient
+ if {($aorient == "vert") || ($aorient == "full")} {
+ box grow n ${s}um
+ box grow s ${s}um
+ }
+ if {($aorient == "horz") || ($aorient == "full")} {
+ box grow e ${s}um
+ box grow w ${s}um
+ }
+ paint ${atype}
+ set extents [sky130::getbox]
+ popbox
+ # Top layer surrounded on sides as declared by orient
+ if {($orient == "vert") || ($orient == "full")} {
+ box grow n ${o}um
+ box grow s ${o}um
+ }
+ if {($orient == "horz") || ($orient == "full")} {
+ box grow e ${o}um
+ box grow w ${o}um
+ }
+ paint ${mtype}
+ popbox
+ return $extents
+}
+
+#----------------------------------------------------------------
+# Draw a guard ring
+#----------------------------------------------------------------
+
+proc sky130::guard_ring {gw gh parameters} {
+
+ # Set local default values if they are not in parameters
+ set rlcov 100 ;# Right-left contact coverage percentage
+ set tbcov 100 ;# Top-bottom contact coverage percentage
+ set grc 1 ;# Draw right side contact
+ set glc 1 ;# Draw left side contact
+ set gtc 1 ;# Draw right side contact
+ set gbc 1 ;# Draw left side contact
+ set full_metal 1 ;# Draw full (continuous) metal ring
+ set guard_sub_type pwell ;# substrate type under guard ring
+ set guard_sub_surround 0 ;# substrate type surrounds guard ring
+ set plus_diff_type nsd ;# guard ring diffusion type
+ set plus_contact_type nsc ;# guard ring diffusion contact type
+ set sub_type pwell ;# substrate type
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Set guard_sub_type to sub_type if it is not defined
+ if {![dict exists $parameters guard_sub_type]} {
+ set guard_sub_type $sub_type
+ }
+
+ set hx [/ $contact_size 2.0]
+ set hw [/ $gw 2.0]
+ set hh [/ $gh 2.0]
+
+ # Watch for (LV) substrate diffusion types, which have a different
+ # contact surround amount depending on the direction
+
+ set lv_sub_types {"psd" "nsd"}
+ if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
+ set diff_surround 0
+ }
+
+ # Compute diffusion width
+ set difft [+ $contact_size $diff_surround $diff_surround]
+ set hdifft [/ $difft 2.0]
+ # Compute guard ring diffusion width and height
+ set hdiffw [/ [+ $gw $difft] 2.0]
+ set hdiffh [/ [+ $gh $difft] 2.0]
+
+ pushbox
+ box size 0 0
+
+ pushbox
+ box move n ${hh}um
+ box grow n ${hdifft}um
+ box grow s ${hdifft}um
+ box grow e ${hdiffw}um
+ box grow w ${hdiffw}um
+ paint $plus_diff_type
+ if {$guard_sub_surround > 0} {
+ box grow c ${guard_sub_surround}um
+ paint $guard_sub_type
+ }
+ popbox
+ pushbox
+ box move s ${hh}um
+ box grow n ${hdifft}um
+ box grow s ${hdifft}um
+ box grow e ${hdiffw}um
+ box grow w ${hdiffw}um
+ paint $plus_diff_type
+ if {$guard_sub_surround > 0} {
+ box grow c ${guard_sub_surround}um
+ paint $guard_sub_type
+ }
+ popbox
+ pushbox
+ box move e ${hw}um
+ box grow e ${hdifft}um
+ box grow w ${hdifft}um
+ box grow n ${hdiffh}um
+ box grow s ${hdiffh}um
+ paint $plus_diff_type
+ if {$guard_sub_surround > 0} {
+ box grow c ${guard_sub_surround}um
+ paint $guard_sub_type
+ }
+ popbox
+ pushbox
+ box move w ${hw}um
+ box grow e ${hdifft}um
+ box grow w ${hdifft}um
+ box grow n ${hdiffh}um
+ box grow s ${hdiffh}um
+ paint $plus_diff_type
+ if {$guard_sub_surround > 0} {
+ box grow c ${guard_sub_surround}um
+ paint $guard_sub_type
+ }
+ popbox
+
+ if {$full_metal} {
+ set hmetw [/ [+ $gw $contact_size] 2.0]
+ set hmeth [/ [+ $gh $contact_size] 2.0]
+ pushbox
+ box move n ${hh}um
+ box grow n ${hx}um
+ box grow s ${hx}um
+ box grow e ${hmetw}um
+ box grow w ${hmetw}um
+ paint li
+ popbox
+ pushbox
+ box move s ${hh}um
+ box grow n ${hx}um
+ box grow s ${hx}um
+ box grow e ${hmetw}um
+ box grow w ${hmetw}um
+ paint li
+ popbox
+ pushbox
+ box move e ${hw}um
+ box grow e ${hx}um
+ box grow w ${hx}um
+ box grow n ${hmeth}um
+ box grow s ${hmeth}um
+ paint li
+ popbox
+ pushbox
+ box move w ${hw}um
+ box grow e ${hx}um
+ box grow w ${hx}um
+ box grow n ${hmeth}um
+ box grow s ${hmeth}um
+ paint li
+ popbox
+ }
+
+ # Set guard ring height so that contact metal reaches to end, scale by $per
+ # set ch [* [+ $gh $contact_size [* $metal_surround -2.0]] [/ $rlcov 100.0]]
+ set ch [* [- $gh $contact_size [* [+ $metal_surround $metal_spacing] \
+ 2.0]] [/ $rlcov 100.0]]
+ if {$ch < $contact_size} {set ch $contact_size}
+
+ # Set guard ring width so that contact metal reaches to side contacts
+ set cw [* [- $gw $contact_size [* [+ $metal_surround $metal_spacing] \
+ 2.0]] [/ $tbcov 100.0]]
+ if {$cw < $contact_size} {set cw $contact_size}
+
+ if {$tbcov > 0.0} {
+ if {$gtc == 1} {
+ pushbox
+ box move n ${hh}um
+ sky130::draw_contact $cw 0 $diff_surround $metal_surround \
+ $contact_size $plus_diff_type $plus_contact_type li horz
+ popbox
+ }
+ if {$gbc == 1} {
+ pushbox
+ box move s ${hh}um
+ sky130::draw_contact $cw 0 $diff_surround $metal_surround \
+ $contact_size $plus_diff_type $plus_contact_type li horz
+ popbox
+ }
+ }
+ if {$rlcov > 0.0} {
+ if {$grc == 1} {
+ pushbox
+ box move e ${hw}um
+ sky130::draw_contact 0 $ch $diff_surround $metal_surround \
+ $contact_size $plus_diff_type $plus_contact_type li vert
+ popbox
+ }
+ if {$glc == 1} {
+ pushbox
+ box move w ${hw}um
+ sky130::draw_contact 0 $ch $diff_surround $metal_surround \
+ $contact_size $plus_diff_type $plus_contact_type li vert
+ popbox
+ }
+ }
+
+ pushbox
+ box grow e ${hw}um
+ box grow w ${hw}um
+ box grow n ${hh}um
+ box grow s ${hh}um
+ # Create boundary using properties
+ property FIXED_BBOX [box values]
+ box grow c ${hx}um ;# to edge of contact
+ box grow c ${diff_surround}um ;# to edge of diffusion
+ box grow c ${sub_surround}um ;# sub/well overlap of diff (NOT guard_sub)
+ paint $sub_type
+ set cext [sky130::getbox]
+ popbox
+ popbox
+
+ return $cext
+}
+
+#----------------------------------------------------------------
+# MOSFET: Draw a single device
+#----------------------------------------------------------------
+
+proc sky130::mos_device {parameters} {
+
+ # Epsilon for avoiding round-off errors
+ set eps 0.0005
+
+ # Set local default values if they are not in parameters
+ set diffcov 100 ;# percent coverage of diffusion contact
+ set polycov 100 ;# percent coverage of poly contact
+ set topc 1 ;# draw top poly contact
+ set botc 1 ;# draw bottom poly contact
+ set evenodd 1 ;# even or odd numbered device finger, in X
+ set dev_sub_type "" ;# device substrate type (if different from guard ring)
+ set min_effl 0 ;# gate length below which finger pitch must be stretched
+ set diff_overlap_cont 0 ;# extra overlap of end contact by diffusion
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Draw the diffusion and poly
+ pushbox
+ box size 0 0
+ pushbox
+ set hw [/ $w 2.0]
+ set hl [/ $l 2.0]
+ set he [/ $min_effl 2.0]
+ if {$nf == 1 || $he < $hl} {set he $hl}
+ box grow n ${hw}um
+ box grow s ${hw}um
+ box grow e ${hl}um
+ box grow w ${hl}um
+ pushbox
+ if {${diff_extension} > ${gate_to_diffcont}} {
+ box grow e ${diff_extension}um
+ box grow w ${diff_extension}um
+ } else {
+ box grow e ${gate_to_diffcont}um
+ box grow w ${gate_to_diffcont}um
+ }
+ paint ${diff_type}
+ popbox
+ pushbox
+ if {${gate_extension} > ${gate_to_polycont}} {
+ box grow n ${gate_extension}um
+ box grow s ${gate_extension}um
+ } else {
+ if {$topc} {
+ box grow n ${gate_to_polycont}um
+ } else {
+ box grow n ${gate_extension}um
+ }
+ if {$botc} {
+ box grow s ${gate_to_polycont}um
+ } else {
+ box grow s ${gate_extension}um
+ }
+ }
+ paint ${poly_type}
+ set cext [sky130::getbox]
+ popbox
+ # save gate area now and paint later, so that diffusion surrounding the
+ # contact does not paint over the gate area, in case the gate type is
+ # not part of a "compose" entry in the techfile.
+ set gaterect [box values]
+ popbox
+
+ # Adjust position of contacts for dogbone geometry
+ # Rule 1: Minimize diffusion length. Contacts only move out
+ # if width < contact diffusion height. They move out enough
+ # that the diffusion-to-poly spacing is satisfied.
+
+ set ddover 0
+ set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
+ set cstem [- ${gate_to_diffcont} [/ ${cdwmin} 2.0]]
+ set cgrow [- ${diff_poly_space} ${cstem}]
+ if {[+ ${w} ${eps}] < ${cdwmin}} {
+ if {${cgrow} > 0} {
+ set gate_to_diffcont [+ ${gate_to_diffcont} ${cgrow}]
+ }
+ set ddover [/ [- ${cdwmin} ${w}] 2.0]
+ }
+
+ # Rule 2: Minimum poly width. Poly contacts only move out
+ # if length < contact poly width. They move out enough
+ # that the diffusion-to-poly spacing is satisfied.
+
+ set gporig ${gate_to_polycont}
+ set cplmin [+ ${contact_size} [* ${poly_surround} 2]]
+ set cstem [- ${gate_to_polycont} [/ ${cplmin} 2.0]]
+ set cgrow [- ${diff_poly_space} ${cstem}]
+ if {[+ ${l} ${eps}] < ${cplmin}} {
+ if {${cgrow} > 0} {
+ set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
+ }
+ }
+
+ # Rule 3: If both poly and diffusion are dogboned, then move
+ # poly out further to clear spacing to the diffusion contact
+
+ if {[+ ${w} ${eps}] < ${cdwmin}} {
+ if {[+ ${l} ${eps}] < ${cplmin}} {
+ set cgrow [/ [- ${cplmin} ${w}] 2.0]
+ set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
+ }
+ }
+
+ # Rule 4: If M > 1 and poly contacts overlap, then increase the
+ # transistor-to-poly-contact distance by the amount of any
+ # diffusion dogbone overhang.
+
+ if {($poverlap == 1) && ($m > 1)} {
+ if {${gate_to_polycont} - $gporig < $ddover} {
+ set gate_to_polycont [+ ${gporig} ${ddover}]
+ }
+ }
+
+ # Reduce contact sizes by poly or diffusion surround so that
+ # the contact area edges match the device diffusion or poly.
+ # (Minimum dimensions will be enforced by the contact drawing routine)
+ set tsurround [+ ${diff_surround} ${diff_overlap_cont}]
+ set cdw [- ${w} [* ${tsurround} 2]] ;# diff contact height
+ set cpl [- ${l} [* ${poly_surround} 2]] ;# poly contact width
+
+ # Reduce by coverage percentage. NOTE: If overlapping multiple devices,
+ # keep maximum poly contact coverage.
+
+ set cdw [* ${cdw} [/ ${diffcov} 100.0]]
+ if {($poverlap == 0) || ($m == 1)} {
+ set cpl [* ${cpl} [/ ${polycov} 100.0]]
+ }
+
+ # Right diffusion contact
+ pushbox
+ box move e ${he}um
+ box move e ${gate_to_diffcont}um
+ set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
+ ${diff_surround} ${metal_surround} ${contact_size}\
+ ${diff_type} ${diff_contact_type} li vert]]
+ popbox
+ # Left diffusion contact
+ pushbox
+ box move w ${he}um
+ box move w ${gate_to_diffcont}um
+ set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
+ ${diff_surround} ${metal_surround} ${contact_size} \
+ ${diff_type} ${diff_contact_type} li vert]]
+ set diffarea $cext
+ popbox
+ # Top poly contact
+ if {$topc} {
+ pushbox
+ box move n ${hw}um
+ box move n ${gate_to_polycont}um
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
+ ${poly_surround} ${metal_surround} ${contact_size} \
+ ${poly_type} ${poly_contact_type} li horz]]
+ popbox
+ }
+ # Bottom poly contact
+ if {$botc} {
+ pushbox
+ box move s ${hw}um
+ box move s ${gate_to_polycont}um
+ set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
+ ${poly_surround} ${metal_surround} ${contact_size} \
+ ${poly_type} ${poly_contact_type} li horz]]
+ popbox
+ }
+
+ # Now draw the gate, after contacts have been drawn
+ pushbox
+ box values {*}${gaterect}
+ # gate_type need not be defined if poly over diff paints the right type.
+ catch {paint ${gate_type}}
+ # sub_surround_dev, if defined, may create a larger area around the gate
+ # than sub_surround creates around the diffusion/poly area.
+ if [dict exists $parameters sub_surround_dev] {
+ box grow n ${sub_surround_dev}um
+ box grow s ${sub_surround_dev}um
+ box grow e ${sub_surround_dev}um
+ box grow w ${sub_surround_dev}um
+ paint ${dev_sub_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ }
+ popbox
+
+ if {$dev_sub_type != ""} {
+ box values [lindex $diffarea 0]um [lindex $diffarea 1]um \
+ [lindex $diffarea 2]um [lindex $diffarea 3]um
+ box grow n ${sub_surround}um
+ box grow s ${sub_surround}um
+ box grow e ${sub_surround}um
+ box grow w ${sub_surround}um
+ paint ${dev_sub_type}
+ set cext [sky130::unionbox $cext [sky130::getbox]]
+ # puts stdout "Diagnostic: bounding box is $cext"
+ }
+
+ popbox
+ return $cext
+}
+
+#----------------------------------------------------------------
+# MOSFET: Draw the tiled device
+#----------------------------------------------------------------
+
+proc sky130::mos_draw {parameters} {
+ tech unlock *
+ set savesnap [snap]
+ snap internal
+
+ # Set defaults if they are not in parameters
+ set poverlap 0 ;# overlap poly contacts when tiling
+ set doverlap 1 ;# overlap diffusion contacts when tiling
+ set dev_sub_dist 0 ;# substrate to guard ring, if dev_sub_type defined
+ set dev_sub_space 0 ;# distance between substrate areas for arrayed devices
+ set min_allc 0 ;# gate length below which poly contacts must be interleaved
+ set id_type "" ;# additional type covering everything
+ set id_surround 0 ;# amount of surround on above type
+ set id2_type "" ;# additional type covering everything
+ set id2_surround 0 ;# amount of surround on above type
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Diff-to-tap spacing is by default the same as diff spacing
+ if {![dict exist $parameters diff_tap_space]} {
+ set diff_tap_space $diff_spacing
+ }
+
+ # If poverlap is 1 then both poly contacts must be present
+ if {$poverlap == 1} {
+ set topc 1
+ set botc 1
+ dict set parameters topc 1
+ dict set parameters botc 1
+ }
+
+ # Normalize distance units to microns
+ set w [magic::spice2float $w]
+ set l [magic::spice2float $l]
+
+ pushbox
+ box values 0 0 0 0
+
+ # If dx < (poly contact space + poly contact width), then there is not
+ # enough room for a row of contacts, so force alternating contacts
+
+ if {$nf > 1 && $l < $min_allc} {
+ set intc 1
+ set evenodd 1
+ set topc 1
+ set botc 1
+ dict set parameters topc 1
+ dict set parameters botc 1
+ set poverlap 0
+ } else {
+ set intc 0
+ }
+
+ # Determine the base device dimensions by drawing one device
+ # while all layers are locked (nothing drawn). This allows the
+ # base drawing routine to do complicated geometry without having
+ # to duplicate it here with calculations.
+
+ tech lock *
+ set bbox [sky130::mos_device $parameters]
+ # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
+ tech unlock *
+
+ set fw [- [lindex $bbox 2] [lindex $bbox 0]]
+ set fh [- [lindex $bbox 3] [lindex $bbox 1]]
+ set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
+ set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
+
+ # If dev_sub_dist > 0 then each device must be in its own substrate
+ # (well) area, and overlaps are disallowed. dev_sub_space determines
+ # the distance between individual devices in an array.
+
+ if {$dev_sub_dist > 0} {
+ set poverlap 0
+ set doverlap 0
+
+ if {$dev_sub_space > $poly_spacing} {
+ set dx [+ $fw $dev_sub_space]
+ set dy [+ $fh $dev_sub_space]
+ } else {
+ set dx [+ $fw $poly_spacing]
+ set dy [+ $fh $poly_spacing]
+ }
+
+ } else {
+
+ # Determine tile width and height (depends on overlap)
+ if {$poverlap == 0} {
+ set dy [+ $fh $poly_spacing]
+ } else {
+ # overlap poly
+ set dy [- $fh [+ $poly_surround $poly_surround $contact_size]]
+ }
+
+ if {$doverlap == 0} {
+ set dx [+ $fw $diff_spacing]
+ } else {
+ # overlap diffusions
+ set dx [- $fw [+ $diff_surround $diff_surround $contact_size]]
+ }
+ }
+
+ # Determine core width and height
+ set corex [+ [* [- $nf 1] $dx] $fw]
+ set corey [+ [* [- $m 1] $dy] $fh]
+ set corellx [/ [+ [- $corex $fw] $lw] 2.0]
+ set corelly [/ [+ [- $corey $fh] $lh] 2.0]
+
+ # If there is a diffusion dogbone, and no top poly contact, then
+ # increase the core height by the amount of the dogbone overhang.
+
+ if {$topc == 0} {
+ set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
+ if {${w} < ${cdwmin}} {
+ set corey [+ $corey [/ [- ${cdwmin} ${w}] 2.0]]
+ }
+ }
+
+ if {$guard != 0} {
+ # Calculate guard ring size (measured to contact center)
+ if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_tap_space)} {
+ set gx [+ $corex [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
+ } else {
+ set gx [+ $corex [* 2.0 [+ $diff_tap_space $diff_surround]] $contact_size]
+ }
+ if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_gate_space)} {
+ set gy [+ $corey [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
+ } else {
+ set gy [+ $corey [* 2.0 [+ $diff_gate_space $diff_surround]] $contact_size]
+ }
+
+ # Somewhat tricky. . . if the width is small and the diffusion is
+ # a dogbone, and the top or bottom poly contact is missing, then
+ # the spacing to the guard ring may be limited by diffusion spacing, not
+ # poly to diffusion.
+
+ set inset [/ [+ $contact_size [* 2.0 $diff_surround] -$w] 2.0]
+ set sdiff [- [+ $inset $diff_tap_space] [+ $gate_extension $diff_gate_space]]
+
+ if {$sdiff > 0} {
+ if {$topc == 0} {
+ set gy [+ $gy $sdiff]
+ set corelly [+ $corelly [/ $sdiff 2.0]]
+ }
+ if {$botc == 0} {
+ set gy [+ $gy $sdiff]
+ set corelly [- $corelly [/ $sdiff 2.0]]
+ }
+ }
+
+ # Draw the guard ring first, as MOS well may interact with guard ring substrate
+ sky130::guard_ring $gx $gy $parameters
+ }
+
+ pushbox
+ # If any surrounding identifier type is defined, draw it
+ if {${id_type} != ""} {
+ set hw [/ $gx 2]
+ set hh [/ $gy 2]
+ box grow e ${hw}um
+ box grow w ${hw}um
+ box grow n ${hh}um
+ box grow s ${hh}um
+ box grow c ${id_surround}um
+ paint ${id_type}
+ }
+ popbox
+ pushbox
+ box move w ${corellx}um
+ box move s ${corelly}um
+ for {set xp 0} {$xp < $nf} {incr xp} {
+ pushbox
+ if {$intc == 1} {
+ set evenodd [- 1 $evenodd]
+ if {$evenodd == 1} {
+ dict set parameters topc 1
+ dict set parameters botc 0
+ } else {
+ dict set parameters topc 0
+ dict set parameters botc 1
+ }
+ set saveeo $evenodd
+ }
+ for {set yp 0} {$yp < $m} {incr yp} {
+ sky130::mos_device $parameters
+ box move n ${dy}um
+ if {$intc == 1} {
+ set evenodd [- 1 $evenodd]
+ if {$evenodd == 1} {
+ dict set parameters topc 1
+ dict set parameters botc 0
+ } else {
+ dict set parameters topc 0
+ dict set parameters botc 1
+ }
+ }
+ }
+ if {$intc == 1} {
+ set evenodd $saveeo
+ }
+ popbox
+ box move e ${dx}um
+ }
+ popbox
+ popbox
+
+ snap $savesnap
+ tech revert
+}
+
+#-------------------
+# nMOS 1.8V
+#-------------------
+
+proc sky130::nshort_draw {parameters} {
+ set newdict [dict create \
+ gate_type nfet \
+ diff_type ndiff \
+ diff_contact_type ndc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::nlowvt_draw {parameters} {
+ set newdict [dict create \
+ gate_type nfetlvt \
+ diff_type ndiff \
+ diff_contact_type ndc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::sonos_e_draw {parameters} {
+ set newdict [dict create \
+ gate_type nsonos \
+ diff_type ndiff \
+ diff_contact_type ndc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ id_type dnwell \
+ id_surround 1.355 \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#-------------------
+# pMOS 1.8V
+#-------------------
+
+proc sky130::pshort_draw {parameters} {
+ set newdict [dict create \
+ gate_type pfet \
+ diff_type pdiff \
+ diff_contact_type pdc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type nwell \
+ gate_to_polycont 0.32 \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::plowvt_draw {parameters} {
+ set newdict [dict create \
+ gate_type pfetlvt \
+ diff_type pdiff \
+ diff_contact_type pdc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type nwell \
+ gate_to_polycont 0.32 \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::phighvt_draw {parameters} {
+ set newdict [dict create \
+ gate_type pfethvt \
+ diff_type pdiff \
+ diff_contact_type pdc \
+ plus_diff_type nsd \
+ plus_contact_type nsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type nwell \
+ gate_to_polycont 0.32 \
+ min_effl 0.185 \
+ min_allc 0.26 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#-------------------
+# pMOS 5.0V
+#-------------------
+
+proc sky130::phv_draw {parameters} {
+ set newdict [dict create \
+ gate_type mvpfet \
+ diff_type mvpdiff \
+ diff_contact_type mvpdc \
+ plus_diff_type mvnsd \
+ plus_contact_type mvnsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type nwell \
+ guard_sub_surround 0.33 \
+ gate_to_polycont 0.32 \
+ diff_spacing 0.31 \
+ diff_tap_space 0.38 \
+ diff_gate_space 0.38 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#-------------------
+# nMOS 5.0V
+#-------------------
+
+proc sky130::nhv_draw {parameters} {
+ set newdict [dict create \
+ gate_type mvnfet \
+ diff_type mvndiff \
+ diff_contact_type mvndc \
+ plus_diff_type mvpsd \
+ plus_contact_type mvpsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ diff_spacing 0.31 \
+ diff_tap_space 0.38 \
+ diff_gate_space 0.38 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::nhvnative_draw {parameters} {
+ set newdict [dict create \
+ gate_type mvnnfet \
+ diff_type mvndiff \
+ diff_contact_type mvndc \
+ plus_diff_type mvpsd \
+ plus_contact_type mvpsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ diff_spacing 0.30 \
+ diff_tap_space 0.38 \
+ diff_gate_space 0.38 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#------------------------
+# MOS varactor (1.8V)
+#------------------------
+
+proc sky130::xcnwvc_draw {parameters} {
+ set newdict [dict create \
+ gate_type var \
+ diff_type nnd \
+ diff_contact_type nsc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ dev_sub_type nwell \
+ diff_overlap_cont 0.06 \
+ dev_sub_dist 0.14 \
+ dev_sub_space 1.27 \
+ gate_to_diffcont 0.34 \
+ diff_extension 0.485 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+proc sky130::xcnwvc2_draw {parameters} {
+ set newdict [dict create \
+ gate_type varhvt \
+ diff_type nnd \
+ diff_contact_type nsc \
+ plus_diff_type psd \
+ plus_contact_type psc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ dev_sub_type nwell \
+ diff_overlap_cont 0.06 \
+ dev_sub_dist 0.14 \
+ dev_sub_space 1.27 \
+ gate_to_diffcont 0.34 \
+ diff_extension 0.485 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#---------------------------------------------------------
+# MOS varactor (5.0V)
+# NOTE: dev_sub_space set to 2.0 assuming different nets.
+# Should have option for same-net with merged wells.
+#---------------------------------------------------------
+
+proc sky130::xchvnwc_draw {parameters} {
+ set newdict [dict create \
+ gate_type mvvar \
+ diff_type mvnsd \
+ diff_contact_type mvnsc \
+ plus_diff_type mvpsd \
+ plus_contact_type mvpsc \
+ poly_type poly \
+ poly_contact_type pc \
+ sub_type psub \
+ dev_sub_type nwell \
+ sub_surround 0.38 \
+ sub_surround_dev 0.56 \
+ guard_sub_surround 0.18 \
+ diff_overlap_cont 0.06 \
+ dev_sub_dist 0.785 \
+ dev_sub_space 2.0 \
+ gate_to_diffcont 0.34 \
+ diff_extension 0.485 \
+ ]
+ set drawdict [dict merge $sky130::ruleset $newdict $parameters]
+ return [sky130::mos_draw $drawdict]
+}
+
+#----------------------------------------------------------------
+# MOSFET: Check device parameters for out-of-bounds values
+#----------------------------------------------------------------
+
+proc sky130::mos_check {device parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set l [magic::spice2float $l]
+ set l [magic::3digitpastdecimal $l]
+ set w [magic::spice2float $w]
+ set w [magic::3digitpastdecimal $w]
+
+ # nf, m must be integer
+ if {![string is int $nf]} {
+ puts stderr "NF must be an integer!"
+ dict set parameters nf 1
+ }
+ if {![string is int $m]} {
+ puts stderr "M must be an integer!"
+ dict set parameters m 1
+ }
+ # diffcov, polycov must be numeric
+ if {[catch {expr abs($diffcov)}]} {
+ puts stderr "diffcov must be numeric!"
+ set diffcov 100
+ }
+ if {[catch {expr abs($polycov)}]} {
+ puts stderr "polycov must be numeric!"
+ set polycov 100
+ }
+
+ if {$l < $lmin} {
+ puts stderr "Mos length must be >= $lmin um"
+ dict set parameters l $lmin
+ }
+ if {$w < $wmin} {
+ puts stderr "Mos width must be >= $wmin um"
+ dict set parameters w $wmin
+ }
+ if {$nf < 1} {
+ puts stderr "NF must be >= 1"
+ dict set parameters nf 1
+ }
+ if {$m < 1} {
+ puts stderr "M must be >= 1"
+ dict set parameters m 1
+ }
+ if {$diffcov < 20 } {
+ puts stderr "Diffusion contact coverage must be at least 20%"
+ dict set parameters diffcov 20
+ } elseif {$diffcov > 100 } {
+ puts stderr "Diffusion contact coverage can't be more than 100%"
+ dict set parameters diffcov 100
+ }
+ if {$polycov < 20 } {
+ puts stderr "Poly contact coverage must be at least 20%"
+ dict set parameters polycov 20
+ } elseif {$polycov > 100 } {
+ puts stderr "Poly contact coverage can't be more than 100%"
+ dict set parameters polycov 100
+ }
+
+ # Values must satisfy diffusion-to-tap spacing of 20um.
+ # Therefore the maximum of guard ring width or height cannot exceed 40um.
+ # If in violation, reduce counts first, as these are easiest to recover
+ # by duplicating the device and overlapping the wells.
+ set origm $m
+ set orignf $nf
+ while true {
+ set yext [expr ($w + 3.0) * $m]
+ set xext [expr ($l + 1.0) * $nf + 1.1]
+ if {[expr min($xext, $yext)] > 40.0} {
+ if {$yext > 40.0 && $m > 1} {
+ incr m -1
+ } elseif {$xext > 40.0 && $nf > 1} {
+ incr nf -1
+ } elseif {$yext > 40.0} {
+ set w 37
+ puts -nonewline stderr "Transistor width must be < 37 um"
+ puts stderr " to avoid tap spacing violation."
+ dict set parameters w $w
+ } elseif {$xext > 40.0} {
+ set l 37.9
+ puts -nonewline stderr "Transistor length must be < 37.9 um"
+ puts stderr " to avoid tap spacing violation."
+ dict set parameters l $l
+ }
+ } else {
+ break
+ }
+ }
+ if {$m != $origm} {
+ puts stderr "Y repeat reduced to prevent tap distance violation"
+ dict set parameters m $m
+ }
+ if {$nf != $orignf} {
+ puts stderr "X repeat reduced to prevent tap distance violation"
+ dict set parameters nf $nf
+ }
+
+ return $parameters
+}
+
+#----------------------------------------------------------------
+
+proc sky130::nshort_check {parameters} {
+ return [sky130::mos_check nshort $parameters]
+}
+
+proc sky130::nlowvt_check {parameters} {
+ return [sky130::mos_check nlowvt $parameters]
+}
+
+proc sky130::sonos_e_check {parameters} {
+ return [sky130::mos_check sonos_e $parameters]
+}
+
+proc sky130::nhv_check {parameters} {
+ return [sky130::mos_check nhv $parameters]
+}
+
+proc sky130::nhvnative_check {parameters} {
+ return [sky130::mos_check nhvnative $parameters]
+}
+
+proc sky130::pshort_check {parameters} {
+ return [sky130::mos_check pshort $parameters]
+}
+
+proc sky130::plowvt_check {parameters} {
+ return [sky130::mos_check plowvt $parameters]
+}
+
+proc sky130::phighvt_check {parameters} {
+ return [sky130::mos_check phighvt $parameters]
+}
+
+proc sky130::phv_check {parameters} {
+ return [sky130::mos_check phv $parameters]
+}
+
+proc sky130::xcnwvc_check {parameters} {
+ return [sky130::mos_check xcnwvc $parameters]
+}
+
+proc sky130::xcnwvc2_check {parameters} {
+ return [sky130::mos_check xcnwvc2 $parameters]
+}
+
+proc sky130::xchvnwc_check {parameters} {
+ return [sky130::mos_check xchvnwc $parameters]
+}
+
+#----------------------------------------------------------------
+# Fixed device: Specify all user-editable default values
+#
+# deltax --- Additional horizontal space between devices
+# deltay --- Additional vertical space between devices
+# nx --- Number of arrayed devices in X
+# ny --- Number of arrayed devices in Y
+#
+# Note that these values, specifically nx, ny, deltax,
+# and deltay, are properties of the instance, not the cell.
+# They translate to the instance array x and y counts; while
+# deltax is the x pitch less the cell width, and deltay is the
+# y pitch less the cell height.
+#
+# non-user-editable
+#
+# nocell --- Indicates that this cell has a predefined layout
+# and therefore there is no cell to draw.
+# xstep --- Width of the cell (nominal array pitch in X)
+# ystep --- Height of the cell (nominal array pitch in Y)
+#----------------------------------------------------------------
+
+# Fixed-layout devices (from sky130_fd_pr_base, _rf, and _rf2 libraries)
+#
+# Bipolar transistors:
+#
+# sky130_fd_pr_rf_npn_1x1
+# sky130_fd_pr_rf_npn_1x2
+# sky130_fd_pr_rf_pnp5x
+#
+# Parallel Plate Capacitors:
+#
+# sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield
+# sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield
+# sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield
+# sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield
+# sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield
+# sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield
+# sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield
+# sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield
+# sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield
+# sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4
+# sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield
+# sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield
+# sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield
+# sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield
+# sky130_fd_pr_rf_xcmvpp2
+# sky130_fd_pr_rf_xcmvpp2_nwell
+# sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield
+# sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield
+# sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield
+# sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield
+#
+# Inductors:
+#
+# balun
+# xind4_011
+# xind4_02
+
+proc sky130::sky130_fd_pr_rf_npn_1x1_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 7.03}
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x2_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 8.03}
+}
+
+proc sky130::sky130_fd_pr_rf_pnp5x_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44}
+}
+
+proc sky130::balun_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 292 ystep 292}
+}
+
+proc sky130::xind4_02_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 258 ystep 258}
+}
+
+proc sky130::xind4_011_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.47 ystep 5.76}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.47 ystep 5.76}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 10.41 ystep 11.54}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 1.77 ystep 1.77}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 3.88 ystep 3.88}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.55 ystep 4.76}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_nwell_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.55 ystep 4.76}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield_defaults {} {
+ return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
+}
+
+#----------------------------------------------------------------
+# Fixed device: Conversion from SPICE netlist parameters to toolkit
+#----------------------------------------------------------------
+
+proc sky130::fixed_convert {parameters} {
+ set pdkparams [dict create]
+ dict for {key value} $parameters {
+ switch -nocase $key {
+ m {
+ dict set pdkparams nx $value
+ }
+ }
+ }
+ return $pdkparams
+}
+
+#----------------------------------------------------------------
+
+proc sky130::sky130_fd_pr_rf_npn_1x1_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x2_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_pnp5x_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::balun_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::xind4_011_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::xind4_02_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_nwell_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield_convert {parameters} {
+ return [sky130::fixed_convert $parameters]
+}
+
+#----------------------------------------------------------------
+# Fixed device: Interactively specifies the fixed layout parameters
+#----------------------------------------------------------------
+
+proc sky130::fixed_dialog {parameters} {
+ # Instance fields: nx, ny, pitchx, pitchy
+ # Editable fields: nx, ny, deltax, deltay
+ # Non-editable fields: nocell, xstep, ystep
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # "nocell" field causes nx and ny to be dropped in from
+ # "array count". Also "pitchx" and "pitchy" are passed
+ # in internal units. Convert these to microns and generate
+ # If there is no pitchx and pitchy, then the device has not
+ # yet been created, so keep the deltax and deltay defaults.
+
+ if [dict exists $parameters pitchx] {
+ set pitchux [magic::i2u $pitchx]
+ set stepux [magic::spice2float $xstep]
+ set deltax [magic::3digitpastdecimal [expr $pitchux - $stepux]]
+ # An array size 1 should not cause deltax to go negative
+ if {$deltax < 0.0} {set deltax 0.0}
+ dict set parameters deltax $deltax
+ }
+ if [dict exists $parameters pitchy] {
+ set pitchuy [magic::i2u $pitchy]
+ set stepuy [magic::spice2float $ystep]
+ set deltay [magic::3digitpastdecimal [expr $pitchuy - $stepuy]]
+ # An array size 1 should not cause deltay to go negative
+ if {$deltay < 0.0} {set deltay 0.0}
+ dict set parameters deltay $deltay
+ }
+
+ magic::add_entry nx "NX" $parameters
+ magic::add_entry ny "NY" $parameters
+ magic::add_entry deltax "X step (um)" $parameters
+ magic::add_entry deltay "Y step (um)" $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x1_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x2_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_pnp5x_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::balun_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::xind4_011_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::xind4_02_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_nwell_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield_dialog {parameters} {
+ sky130::fixed_dialog $parameters
+}
+
+#----------------------------------------------------------------
+# Fixed device: Draw the device
+#----------------------------------------------------------------
+
+proc sky130::fixed_draw {devname parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # This cell declares "nocell" in parameters, so it needs to
+ # instance the cell and set properties.
+
+ # Instantiate the cell. The name corresponds to the cell in the sky130_fd_pr_* directory.
+ set instname [getcell ${devname}]
+
+ set deltax [magic::spice2float $deltax]
+ set deltay [magic::spice2float $deltay]
+ set xstep [magic::spice2float $xstep]
+ set ystep [magic::spice2float $ystep]
+
+ # Array stepping
+ if {$nx > 1 || $ny > 1} {
+ set xstep [expr $xstep + $deltax]
+ set ystep [expr $ystep + $deltay]
+ box size ${xstep}um ${ystep}um
+ array $nx $ny
+ }
+ select cell $instname
+ expand
+ return $instname
+}
+
+#----------------------------------------------------------------
+# No additional parameters declared for drawing
+#----------------------------------------------------------------
+
+proc sky130::sky130_fd_pr_rf_npn_1x1_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_npn_1x1 $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x2_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_npn_1x2 $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_pnp5x_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_pnp5x $parameters]
+}
+
+proc sky130::balun_draw {parameters} {
+ return [sky130::fixed_draw balun $parameters]
+}
+
+proc sky130::xind4_011_draw {parameters} {
+ return [sky130::fixed_draw xind4_011 $parameters]
+}
+
+proc sky130::xind4_02_draw {parameters} {
+ return [sky130::fixed_draw xind4_02 $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4 $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp2 $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_nwell_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp2_nwell $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield_draw {parameters} {
+ return [sky130::fixed_draw sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield $parameters]
+}
+
+#----------------------------------------------------------------
+# Fixed device: Check device parameters for out-of-bounds values
+#----------------------------------------------------------------
+
+proc sky130::fixed_check {parameters} {
+
+ # Set a local variable for each parameter (e.g., $l, $w, etc.)
+ foreach key [dict keys $parameters] {
+ set $key [dict get $parameters $key]
+ }
+
+ # Normalize distance units to microns
+ set deltax [magic::spice2float $deltax -1]
+ set deltax [magic::3digitpastdecimal $deltax]
+ set deltay [magic::spice2float $deltay -1]
+ set deltay [magic::3digitpastdecimal $deltay]
+
+ # nx, ny must be integer
+ if {![string is int $nx]} {
+ puts stderr "NX must be an integer!"
+ dict set parameters nx 1
+ }
+ if {![string is int $ny]} {
+ puts stderr "NY must be an integer!"
+ dict set parameters nx 1
+ }
+
+ # Number of devices in X and Y must be at least 1
+ if {$nx < 1} {
+ puts stderr "NX must be >= 1"
+ dict set parameters nx 1
+ }
+ if {$ny < 1} {
+ puts stderr "NY must be >= 1"
+ dict set parameters nx 1
+ }
+ # Step less than zero violates DRC
+ if {$deltax < 0} {
+ puts stderr "X step must be >= 0"
+ dict set parameters deltax 0
+ }
+ if {$deltay < 0} {
+ puts stderr "Y step must be >= 0"
+ dict set parameters deltay 0
+ }
+ return $parameters
+}
+
+#----------------------------------------------------------------
+
+proc sky130::sky130_fd_pr_rf_npn_1x1_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_npn_1x2_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_pnp5x_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::balun_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::xind4_011_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::xind4_02_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp2_nwell_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
+proc sky130::sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield_check {parameters} {
+ return [sky130::fixed_check $parameters]
+}
+
diff --git a/sky130/sky130.tech b/sky130/sky130.tech
new file mode 100644
index 0000000..881eee2
--- /dev/null
+++ b/sky130/sky130.tech
@@ -0,0 +1,4004 @@
+###
+### Source file sky130.tech
+### Process this file with the preproc.py macro processor
+### Note that the tech name is always TECHNAME for
+### magic; this keeps compatibility between layouts
+### for all process variants.
+###
+#----------------------------------------------------------
+# Copyright (c) 2020 R. Timothy Edwards
+# Revisions: See below
+#
+# This file is an Open Source foundry process describing
+# the SkyWater S8 hybrid 0.18um / 0.13um fabrication
+# process. The file may be distributed under the terms
+# of the (Apache 2.0(?)) license agreement.
+#
+#----------------------------------------------------------
+# This file is designed to be used with magic versions
+# 8.3.24 or newer.
+#----------------------------------------------------------
+tech
+ format 35
+ TECHNAME
+end
+
+version
+ version REVISION
+ description "SkyWater SKY130: PRE ALPHA Vendor Open Source rules and DRC"
+end
+
+#----------------------------------------------------------
+# Status: 3/17/19: s8.tech created from xh018.tech
+#
+# Status: 3/20/19: Rev 0 (pre-alpha):
+# Work in progress. Converted from original techfile to S8
+# with all sections updated with as much information as could
+# be immediately gleaned from the documentation. Cifinput and
+# DRC sections have been checked against one standard cell
+# library.
+#
+# Status 5/5/20: Rev 1 (alpha):
+# Changed name from s8 to sky130
+#--------------------------------------------------------------
+
+#--------------------------------------------------------------
+# Supported device types
+#--------------------------------------------------------------
+# device name magic ID layer description
+#-------------------------------------------------------------
+# nshort nfet standard nFET
+# nshort scnfet standard nFET in standard cell**
+# nlowvt nfetlvt low Vt nFET
+# sonos_p/e nsonos SONOS nFET
+# pshort pfet standard pFET
+# pshort scpfet standard pFET in standard cell**
+# plowvt pfetlvt low Vt pFET
+# phighvt pfethvt high Vt pFET
+# ntvnative --- native nFET
+# phv mvpfet thickox pFET
+# nhv mvnfet thickox nFET
+# nhvnative mvnnfet thickox native nFET
+# ndiode ndiode n+ diff diode
+# ndiode_h mvndiode thickox n+ diff diode
+# pdiode pdiode p+ diff diode
+# pdiode_h mvpdiode thickox p+ diff diode
+# ndiode_native nndiode diode with nndiff
+# ndiode_lvt ndiodelvt low Vt n+ diff diode
+# pdiode_lvt pdiodelvt low Vt p+ diff diode
+# pdiode_hvt pdiodehvt high Vt p+ diff diode
+# nwdiode --- nwell diode
+# dnwdiode_psub --- deep nwell diode to substrate
+# dnwdiode_pw --- deep nwell diode to pwell
+# xcmimc1 mimcap MiM cap 1st plate
+# xcmimc2 mimcap2 MiM cap 2nd plate
+# mrdn rdn n+ diff resistor
+# mrdn_hv mvrdn thickox n+ diff resistor
+# mrdp rdp p+ diff resistor
+# mrdp_hv mvrdp thickox p+ diff resistor
+# mrl1 rli local interconnect resistor
+# mrp1 npres n+ poly resistor
+# xhrpoly_* ppres (*) p+ poly resistor (300 Ohms/sq)
+# uhrpoly_* xres (*) p+ poly resistor (2k Ohms/sq)
+# xcnwvc varactor varactor (low Vt?)
+# xcnwvc2 varactorhvt high Vt varactor
+# xchvnwc mvvaractor thickox varactor
+# xpwres rpw pwell resistor (in deep nwell)
+#
+# (*) Note that ppres may extract into some generic type
+# called "xhrpoly", but only specific sizes of xhrpoly are
+# allowed, and these are created from fixed layouts like the
+# types below.
+#
+# (**) nFET and pFET in standard cells are the same as devices
+# outside of the standard cell except for the DRC rule for
+# FET to diffusion contact spacing (which is 0.05um, not 0.055um)
+#
+# To avoid creating a large number of types, a few ID layers are
+# used in conjunction with standard devices types: "lvt" for
+# low threshold voltage, and "hvt" for high threshold voltage.
+# "dnwell" is used as an identifier layer where appropriate.
+# Layer HVI (thick oxide) is treated differently, and types
+# "mv*" are defined where thick oxide is required.
+#
+#-------------------------------------------------------------
+# The following devices are not extracted but are represented
+# only by script-generated subcells in the PDK.
+#-------------------------------------------------------------
+# nshortesd ESD nFET
+# nhvesd ESD thickox nFET
+# nhvnativeesd ESD native nFET
+# phvesd ESD thickox pFET
+# fnpass flash nFET device
+# npnpar1x* parasitic NPN
+# npn_1x1_2p0_hv thickox gated parasitic NPN
+# pnppar parasitic PNP
+# pnppar5x parasitic PNP
+# xesd_ndiode_h_*** ESD n+ diode
+# xesd_pdiode_h_*** ESD p+ diode
+# reslocsub local substrate island indicator
+# xcmvpp Vpp cap
+# xcmvpp_2 Vpp cap
+# xcmvpp_* Vpp cap
+# xcmvpp* Vpp cap
+# balun balun inductor
+# ind4 inductor
+# fuse metal fuse device
+#--------------------------------------------------------------
+
+#-----------------------------------------------------
+# Tile planes
+#-----------------------------------------------------
+
+planes
+ dwell,dw
+ well,w
+ active,a
+ locali,li1,li
+ metal1,m1
+ metal2,m2
+ metal3,m3
+#ifdef METAL5
+#ifdef MIM
+ cap1,c1
+#endif (MIM)
+ metal4,m4
+#ifdef MIM
+ cap2,c2
+#endif (MIM)
+ metal5,m5
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ metali,mi
+#endif
+ block,b
+ comment,c
+end
+
+#-----------------------------------------------------
+# Tile types
+#-----------------------------------------------------
+
+types
+# Deep nwell
+ dwell dnwell,dnw
+
+# Wells
+ well nwell,nw
+ -well pwell,pw
+ -well rpw,rpwell
+ -well obswell
+
+# Transistors
+ active nmos,ntransistor,nfet
+ -active scnmos,scntransistor,scnfet
+ active pmos,ptransistor,pfet
+ -active scpmos,scptransistor,scpfet
+ -active nnmos,nntransistor
+ active mvnmos,mvntransistor,mvnfet
+ active mvpmos,mvptransistor,mvpfet
+ -active mvnnmos,mvnntransistor,mvnnfet,nnfet
+ -active varactor,varact,var
+ -active mvvaractor,mvvaract,mvvar
+
+ -active pmoslvt,pfetlvt
+ -active pmoshvt,pfethvt
+ -active nmoslvt,nfetlvt
+ -active varactorhvt,varacthvt,varhvt
+ -active nsonos,sonos
+
+# Diffusions
+ active ndiff,ndiffusion,ndif
+ active pdiff,pdiffusion,pdif
+ -active mvndiff,mvndiffusion,mvndif
+ -active mvpdiff,mvpdiffusion,mvpdif
+ active ndiffc,ndcontact,ndc
+ active pdiffc,pdcontact,pdc
+ -active mvndiffc,mvndcontact,mvndc
+ -active mvpdiffc,mvpdcontact,mvpdc
+ active psubdiff,psubstratepdiff,ppdiff,ppd,psd
+ active nsubdiff,nsubstratendiff,nndiff,nnd,nsd
+ -active mvpsubdiff,mvpsubstratepdiff,mvppdiff,mvppd,mvpsd
+ -active mvnsubdiff,mvnsubstratendiff,mvnndiff,mvnnd,mvnsd
+ active psubdiffcont,psubstratepcontact,psc
+ active nsubdiffcont,nsubstratencontact,nsc
+ -active mvpsubdiffcont,mvpsubstratepcontact,mvpsc
+ -active mvnsubdiffcont,mvnsubstratencontact,mvnsc
+ -active obsactive
+ -active mvobsactive
+
+# Poly
+ active poly,p,polysilicon
+ active polycont,pc,pcontact,polycut,polyc
+ active xpolycontact,xpolyc,xpc
+
+# Resistors
+ -active npolyres,npres,mrp1
+ -active ppolyres,ppres,xhrpoly
+ -active xpolyres,xpres,xres,uhrpoly
+ -active ndiffres,rnd,rdn,rndiff
+ -active pdiffres,rpd,rdp,rpdiff
+ -active mvndiffres,mvrnd,mvrdn,mvrndiff
+ -active mvpdiffres,mvrpd,mvrdp,mvrpdiff
+ -active rmp
+
+# Diodes
+ -active pdiode,pdi
+ -active ndiode,ndi
+ -active nndiode,nndi
+ -active pdiodec,pdic
+ -active ndiodec,ndic
+ -active nndiodec,nndic
+ -active mvpdiode,mvpdi
+ -active mvndiode,mvndi
+ -active mvpdiodec,mvpdic
+ -active mvndiodec,mvndic
+ -active pdiodelvt,pdilvt
+ -active pdiodehvt,pdihvt
+ -active ndiodelvt,ndilvt
+ -active pdiodelvtc,pdilvtc
+ -active pdiodehvtc,pdihvtc
+ -active ndiodelvtc,ndilvtc
+
+# Local Interconnect
+ locali locali,li1,li
+ -locali corelocali,coreli1,coreli
+ -locali rlocali,rli1,rli
+ locali viali,vial,lic,licon,m1c,v0
+ -locali obsli1,obsli
+ -locali obsli1c,obslic,obslicon
+
+# Metal 1
+ metal1 metal1,m1,met1
+ -metal1 rmetal1,rm1,rmet1
+ metal1 via1,m2contact,m2cut,m2c,via,v,v1
+ -metal1 obsm1
+ -metal1 padl
+
+# Metal 2
+ metal2 metal2,m2,met2
+ -metal2 rmetal2,rm2,rmet2
+ metal2 via2,m3contact,m3cut,m3c,v2
+ -metal2 obsm2
+
+# Metal 3
+ metal3 metal3,m3,met3
+ -metal3 rmetal3,rm3,rmet3
+ -metal3 obsm3
+#ifdef METAL5
+ metal3 via3,v3
+
+#ifdef MIM
+ -cap1 mimcap,mim,capm
+ -cap1 mimcapcontact,mimcapc,mimcc,capmc
+#endif
+
+# Metal 4
+ metal4 metal4,m4,met4
+ -metal4 rmetal4,rm4,rmet4
+ -metal4 obsm4
+ metal4 via4,v4
+
+#ifdef MIM
+ -cap2 mimcap2,mim2,capm2
+ -cap2 mimcap2contact,mimcap2c,mim2cc,capm2c
+#endif
+
+# Metal 5
+ metal5 metal5,m5,met5
+ -metal5 rm5,rmetal5,rmet5
+ -metal5 obsm5
+#endif (METAL5)
+
+#ifdef REDISTRIBUTION
+ -metal5 mrdlcontact,mrdlc
+ -metali metalrdl,mrdl,metrdl
+ -metali obsmrdl
+#endif (REDISTRIBUTION)
+
+# Miscellaneous
+ -block glass
+ -block fillblock
+ -comment comment
+ -comment obscomment
+
+end
+
+#-----------------------------------------------------
+# Magic contact types
+#-----------------------------------------------------
+
+contact
+ pc poly locali
+ ndc ndiff locali
+ pdc pdiff locali
+ nsc nsd locali
+ psc psd locali
+ ndic ndiode locali
+ ndilvtc ndiodelvt locali
+ nndic nndiode locali
+ pdic pdiode locali
+ pdilvtc pdiodelvt locali
+ pdihvtc pdiodehvt locali
+ xpc xpc locali
+
+ mvndc mvndiff locali
+ mvpdc mvpdiff locali
+ mvnsc mvnsd locali
+ mvpsc mvpsd locali
+ mvndic mvndiode locali
+ mvpdic mvpdiode locali
+
+ lic locali metal1
+ obslic obsli obsm1
+
+ via1 metal1 metal2
+ via2 metal2 metal3
+#ifdef METAL5
+ via3 metal3 metal4
+ via4 metal4 metal5
+#endif (METAL5)
+ stackable
+
+#ifdef METAL5
+#ifdef MIM
+ # MiM cap contacts are not stackable!
+ mimcc mimcap metal4
+ mim2cc mimcap2 metal5
+#endif (MIM)
+
+ padl m1 m2 m3 m4 m5 glass
+#else
+ padl m1 m2 m3 glass
+#endif (!METAL5)
+
+#ifdef REDISTRIBUTION
+ mrdlc metal5 mrdl
+#endif (REDISTRIBUTION)
+end
+
+#-----------------------------------------------------
+# Layer aliases
+#-----------------------------------------------------
+
+aliases
+
+ allwellplane nwell
+ allnwell nwell,obswell
+
+ allnfets nfet,scnfet,mvnfet,mvnnfet,nfetlvt,nsonos
+ allpfets pfet,scpfet,mvpfet,pfethvt,pfetlvt
+ allfets allnfets,allpfets,varactor,mvvaractor,varhvt
+
+ allnactivenonfet *ndiff,*nsd,*ndiode,*nndiode,*mvndiff,*mvnsd,*mvndiode,*ndiodelvt
+ allnactive allnactivenonfet,allnfets
+ allnactivenontap *ndiff,*ndiode,*nndiode,*mvndiff,*mvndiode,*ndiodelvt,allnfets
+ allnactivetap *nsd,*mvnsd,var,varhvt,mvvar
+
+ allpactivenonfet *pdiff,*psd,*pdiode,*mvpdiff,*mvpsd,*mvpdiode,*pdiodelvt,*pdiodehvt
+ allpactive allpactivenonfet,allpfets
+ allpactivenontap *pdiff,*pdiode,*mvpdiff,*mvpdiode,*pdiodelvt,*pdiodehvt,allpfets
+ allpactivetap *psd,*mvpsd
+
+ allactivenonfet allnactivenonfet,allpactivenonfet
+ allactive allactivenonfet,allfets
+
+ allactiveres ndiffres,pdiffres,mvndiffres,mvpdiffres
+
+ allndifflv *ndif,*nsd,*ndiode,ndiffres,nfet,scnfet,nfetlvt,nsonos
+ allpdifflv *pdif,*psd,*pdiode,pdiffres,pfet,scpfet,pfetlvt,pfethvt
+ alldifflv allndifflv,allpdifflv
+ allndifflvnonfet *ndif,*nsd,*ndiode,*nndiode,ndiffres,*ndiodelvt
+ allpdifflvnonfet *pdif,*psd,*pdiode,pdiffres,*pdiodelvt,*pdiodehvt
+ alldifflvnonfet allndifflvnonfet,allpdifflvnonfet
+
+ allndiffmv *mvndif,*mvnsd,*mvndiode,*nndiode,mvndiffres,mvnfet,mvnnfet
+ allpdiffmv *mvpdif,*mvpsd,*mvpdiode,mvpdiffres,mvpfet
+ alldiffmv allndiffmv,allpdiffmv
+ allndiffmvnontap *mvndif,*mvndiode,*nndiode,mvndiffres,mvnfet,mvnnfet
+ allpdiffmvnontap *mvpdif,*mvpdiode,mvpdiffres,mvpfet
+ alldiffmvnontap allndiffmvnontap,allpdiffmvnontap
+ allndiffmvnonfet *mvndif,*mvnsd,*mvndiode,*nndiode,mvndiffres
+ allpdiffmvnonfet *mvpdif,*mvpsd,*mvpdiode,mvpdiffres
+ alldiffmvnonfet allndiffmvnonfet,allpdiffmvnonfet
+
+ alldiffnonfet alldifflvnonfet,alldiffmvnonfet
+ alldiff alldifflv,alldiffmv
+
+ allpolyres mrp1,xhrpoly,uhrpoly,rmp
+ allpolynonfet *poly,allpolyres,xpc
+ allpolynonres *poly,allfets,xpc
+
+ allpoly allpolynonfet,allfets
+ allpolynoncap *poly,xpc,allfets,allpolyres
+
+ allndiffcontlv ndc,nsc,ndic,nndic,ndilvtc
+ allpdiffcontlv pdc,psc,pdic,pdilvtc,pdihvtc
+ allndiffcontmv mvndc,mvnsc,mvndic
+ allpdiffcontmv mvpdc,mvpsc,mvpdic
+ allndiffcont allndiffcontlv,allndiffcontmv
+ allpdiffcont allpdiffcontlv,allpdiffcontmv
+ alldiffcontlv allndiffcontlv,allpdiffcontlv
+ alldiffcontmv allndiffcontmv,allpdiffcontmv
+ alldiffcont alldiffcontlv,alldiffcontmv
+
+ allcont alldiffcont,pc
+
+ allres allpolyres,allactiveres
+
+ allli *locali,coreli,rli
+ allm1 *m1,rm1
+ allm2 *m2,rm2
+ allm3 *m3,rm3
+#ifdef METAL5
+ allm4 *m4,rm4
+ allm5 *m5,rm5
+#endif (METAL5)
+
+ allpad padl
+
+ psub pwell
+
+end
+
+#-----------------------------------------------------
+# Layer drawing styles
+#-----------------------------------------------------
+
+styles
+ styletype mos
+ dnwell cwell
+ nwell nwell
+ pwell pwell
+ rpwell pwell ptransistor_stripes
+ ndiff ndiffusion
+ pdiff pdiffusion
+ nsd ndiff_in_nwell
+ psd pdiff_in_pwell
+ nfet ntransistor ntransistor_stripes
+ scnfet ntransistor ntransistor_stripes
+ pfet ptransistor ptransistor_stripes
+ scpfet ptransistor ptransistor_stripes
+ var polysilicon ndiff_in_nwell
+ ndc ndiffusion metal1 contact_X'es
+ pdc pdiffusion metal1 contact_X'es
+ nsc ndiff_in_nwell metal1 contact_X'es
+ psc pdiff_in_pwell metal1 contact_X'es
+
+ pfetlvt ptransistor ptransistor_stripes implant1
+ pfethvt ptransistor ptransistor_stripes implant2
+ nfetlvt ntransistor ntransistor_stripes implant1
+ nsonos ntransistor implant3
+ varhvt polysilicon ndiff_in_nwell implant2
+
+ mvndiff ndiffusion hvndiff_mask
+ mvpdiff pdiffusion hvpdiff_mask
+ mvnsd ndiff_in_nwell hvndiff_mask
+ mvpsd pdiff_in_pwell hvpdiff_mask
+ mvnfet ntransistor ntransistor_stripes hvndiff_mask
+ mvnnfet ntransistor ndiff_in_nwell hvndiff_mask
+ mvpfet ptransistor ptransistor_stripes
+ mvvar polysilicon ndiff_in_nwell hvndiff_mask
+ mvndc ndiffusion metal1 contact_X'es hvndiff_mask
+ mvpdc pdiffusion metal1 contact_X'es hvpdiff_mask
+ mvnsc ndiff_in_nwell metal1 contact_X'es hvndiff_mask
+ mvpsc pdiff_in_pwell metal1 contact_X'es hvpdiff_mask
+
+ poly polysilicon
+ pc polysilicon metal1 contact_X'es
+ npolyres polysilicon silicide_block nselect2
+ ppolyres polysilicon silicide_block pselect2
+ xpc polysilicon pselect2 metal1 contact_X'es
+ rmp polysilicon poly_resist_stripes
+
+ pdiode pdiffusion pselect2
+ ndiode ndiffusion nselect2
+ pdiodec pdiffusion pselect2 metal1 contact_X'es
+ ndiodec ndiffusion nselect2 metal1 contact_X'es
+
+ nndiode ndiffusion nselect2 implant3
+ ndiodelvt ndiffusion nselect2 implant1
+ pdiodelvt pdiffusion pselect2 implant1
+ pdiodehvt pdiffusion pselect2 implant2
+ pdilvtc pdiffusion pselect2 implant1 metal1 contact_X'es
+ pdihvtc pdiffusion pselect2 implant2 metal1 contact_X'es
+ ndilvtc ndiffusion nselect2 implant1 metal1 contact_X'es
+
+ mvpdiode pdiffusion pselect2 hvpdiff_mask
+ mvndiode ndiffusion nselect2 hvndiff_mask
+ mvpdiodec pdiffusion pselect2 metal1 contact_X'es hvpdiff_mask
+ mvndiodec ndiffusion nselect2 metal1 contact_X'es hvndiff_mask
+ nndiodec ndiff_in_nwell nselect2 metal1 contact_X'es hvndiff_mask
+
+ locali metal1
+ coreli metal1
+ rli metal1 poly_resist_stripes
+ lic metal1 metal2 via1arrow
+ obsli metal1
+ obslic metal1 metal2 via1arrow
+
+ metal1 metal2
+ rm1 metal2 poly_resist_stripes
+ obsm1 metal2
+ m2c metal2 metal3 via2arrow
+ metal2 metal3
+ rm2 metal3 poly_resist_stripes
+ obsm2 metal3
+ m3c metal3 metal4 via3alt
+ metal3 metal4
+ rm3 metal4 poly_resist_stripes
+ obsm3 metal4
+#ifdef METAL5
+#ifdef MIM
+ mimcap metal3 mems
+ mimcc metal3 contact_X'es mems
+ mimcap2 metal4 mems
+ mim2cc metal4 contact_X'es mems
+#endif (MIM)
+ via3 metal4 metal5 via4
+ metal4 metal5
+ rm4 metal5 poly_resist_stripes
+ obsm4 metal5
+ via4 metal5 metal6 via5
+ metal5 metal6
+ rm5 metal6 poly_resist_stripes
+ obsm5 metal6
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ mrdlc metal6 metal7 via6
+ metalrdl metal7
+ obsmrdl metal7
+#endif (REDISTRIBUTION)
+
+ glass overglass
+ mrp1 poly_resist poly_resist_stripes
+ xhrpoly poly_resist silicide_block
+ uhrpoly poly_resist
+ ndiffres ndiffusion ndop_stripes
+ pdiffres pdiffusion pdop_stripes
+ mvndiffres ndiffusion hvndiff_mask ndop_stripes
+ mvpdiffres pdiffusion hvpdiff_mask pdop_stripes
+ comment comment
+ error_p error_waffle
+ error_s error_waffle
+ error_ps error_waffle
+ fillblock cwell
+
+ obswell cwell
+ obsactive implant4
+
+#ifndef METAL5
+ padl metal4 via4 overglass
+#else
+ padl metal6 via6 overglass
+#endif
+
+ magnet substrate_field_implant
+ rotate via3alt
+ fence via5
+end
+
+#-----------------------------------------------------
+# Special paint/erase rules
+#-----------------------------------------------------
+
+compose
+ compose nfet poly ndiff
+ compose pfet poly pdiff
+ compose var poly nsd
+
+ compose mvnfet poly mvndiff
+ compose mvpfet poly mvpdiff
+ compose mvvar poly mvnsd
+
+ paint ndc nwell pdc
+ paint nfet nwell pfet
+ paint scnfet nwell scpfet
+ paint ndiff nwell pdiff
+ paint psd nwell nsd
+ paint psc nwell nsc
+
+ paint pdc pwell ndc
+ paint pfet pwell nfet
+ paint scpfet pwell scnfet
+ paint pdiff pwell ndiff
+ paint nsd pwell psd
+ paint nsc pwell psc
+
+ paint pdc coreli pdc
+ paint ndc coreli ndc
+ paint pc coreli pc
+ paint nsc coreli pc
+ paint psc coreli pc
+ paint viali coreli viali
+
+ paint coreli pdc pdc
+ paint coreli ndc ndc
+ paint coreli pc pc
+ paint coreli nsc nsc
+ paint coreli psc psc
+ paint coreli viali viali
+
+#ifdef METAL5
+ paint m4 obsm4 m4
+ paint m5 obsm5 m5
+#endif (METAL5)
+end
+
+#-----------------------------------------------------
+# Electrical connectivity
+#-----------------------------------------------------
+
+connect
+ *nwell,*nsd,*mvnsd,dnwell *nwell,*nsd,*mvnsd,dnwell
+ pwell,*psd,*mvpsd pwell,*psd,*mvpsd
+ *li,coreli *li,coreli
+ *m1 *m1
+ *m2 *m2
+ *m3 *m3
+#ifdef METAL5
+ *m4 *m4
+ *m5 *m5
+#ifdef MIM
+ *mimcap *mimcap
+ *mimcap2 *mimcap2
+#endif (MIM)
+#endif (METAL5)
+ allnactivenonfet allnactivenonfet
+ allpactivenonfet allpactivenonfet
+ *poly,xpc,allfets *poly,xpc,allfets
+#ifdef REDISTRIBUTION
+ # RDL connects to m5 (i.e., padl) through glass cut
+ *mrdl *mrdl
+ glass metrdl
+#endif (REDISTRIBUTION)
+end
+
+#-----------------------------------------------------
+# CIF/GDS output layer definitions
+#-----------------------------------------------------
+# NOTE: All values in this section MUST be multiples of 25
+# or else magic will scale below the allowed layout grid size
+
+cifoutput
+
+#----------------------------------------------------------------
+style gdsii
+# NOTE: This section is used for actual GDS output
+#----------------------------------------------------------------
+ scalefactor 10 nanometers
+ options calma-permissive-labels
+ gridlimit 5
+
+#----------------------------------------------------------------
+# Create a temp layer from the cell bounding box for use in
+# generating ID layers. Note that "boundary", unlike "bbox",
+# requires the FIXED_BBOX property (abutment box) in the cell.
+#----------------------------------------------------------------
+ templayer CELLBOUND
+ boundary
+
+#----------------------------------------------------------------
+# BOUND
+#----------------------------------------------------------------
+ layer BOUND CELLBOUND
+ calma 235 4
+
+# Create a boundary outside of an abutment box, so that layers
+# can be made to stretch to the abutment box edges. First strink
+# so that any box that would be so small as to interact with
+# itself will be removed.
+
+ templayer CELLRING CELLBOUND
+ shrink 345
+ grow 545
+ and-not CELLBOUND
+
+#----------------------------------------------------------------
+# DNWELL
+#----------------------------------------------------------------
+
+ layer DNWELL dnwell
+ calma 64 18
+
+ layer PWRES rpw
+ and dnwell
+ calma 64 13
+
+#----------------------------------------------------------------
+# NWELL
+#----------------------------------------------------------------
+
+ layer NWELL allnwell
+ bloat-all rpw dnwell
+ and-not rpw,pwell
+ calma 64 20
+
+ layer WELLTXT
+ labels allnwell noport
+ calma 64 16
+
+ layer WELLPIN
+ labels allnwell port
+ calma 64 5
+
+#----------------------------------------------------------------
+# SUB (text/port only)
+#----------------------------------------------------------------
+
+ layer SUBTXT
+ labels pwell noport
+ calma 122 16
+
+ layer SUBPIN
+ labels pwell port
+ calma 64 59
+
+#----------------------------------------------------------------
+# DIFF
+#----------------------------------------------------------------
+
+ layer DIFF allnactivenontap,allpactivenontap,allactiveres
+ labels allnactivenontap,allpactivenontap
+ calma 65 20
+
+#----------------------------------------------------------------
+# TAP
+#----------------------------------------------------------------
+
+ layer TAP allnactivetap,allpactivetap
+ labels allnactivetap,allpactivetap
+ calma 65 44
+
+#----------------------------------------------------------------
+# PPLUS, NPLUS (PSDM, NSDM)
+#----------------------------------------------------------------
+
+ templayer basePPLUS pdiffres,mvpdiffres
+ grow 15
+ or xhrpoly,uhrpoly,xpc
+ grow 110
+ bloat-or allpactivetap * 125 allnactivenontap 0
+ bloat-or allpactivenontap * 125 allnactivetap 0
+ bridge 380 380
+
+ templayer extendPPLUS basePPLUS,CELLRING
+ grow 185
+ shrink 185
+ and-not CELLRING
+
+ layer PPLUS basePPLUS,extendPPLUS
+ close 265000
+ calma 94 20
+
+ templayer baseNPLUS ndiffres,mvndiffres
+ grow 125
+ bloat-or allnactivetap * 125 allpactivenontap 0
+ bloat-or allnactivenontap * 125 allpactivetap 0
+ bridge 380 380
+
+ templayer extendNPLUS baseNPLUS,CELLRING
+ grow 185
+ shrink 185
+ and-not CELLRING
+
+ layer NPLUS baseNPLUS,extendNPLUS
+ close 265000
+ calma 93 44
+
+#----------------------------------------------------------------
+# LVTN
+#----------------------------------------------------------------
+
+ layer LVTN pfetlvt,nfetlvt,mvvar,mvnnfet,nsonos,*pdiodelvt,*ndiodelvt,*nndiode
+ grow 180
+ bridge 380 380
+ grow 185
+ shrink 185
+ close 265000
+ calma 125 44
+
+#----------------------------------------------------------------
+# HVTP
+#----------------------------------------------------------------
+
+ layer HVTP pfethvt,varhvt,*pdiodehvt
+ grow 180
+ bridge 380 380
+ grow 185
+ shrink 185
+ close 265000
+ calma 78 44
+
+#----------------------------------------------------------------
+# SONOS
+#----------------------------------------------------------------
+
+ layer SONOS nsonos
+ grow 100
+ grow-min 410
+ bridge 500 410
+ grow 250
+ shrink 250
+ calma 80 20
+
+#----------------------------------------------------------------
+# SONOS requires COREID around area (areaid.ce). Also, the
+# coreli layer indicates a cell needing COREID.
+#----------------------------------------------------------------
+
+ layer COREID
+ bloat-all nsonos,coreli CELLBOUND
+ calma 81 2
+
+#----------------------------------------------------------------
+# STDCELL applies to all cells containing scnfet or scpfet.
+#----------------------------------------------------------------
+
+ layer STDCELL scnfet
+ bloat-all scpfet,scnfet CELLBOUND
+ calma 81 4
+
+#----------------------------------------------------------------
+# RPM
+#----------------------------------------------------------------
+
+ layer RPM
+ bloat-all xhrpoly xpc
+ grow 200
+ grow-min 1270
+ grow 420
+ shrink 420
+ calma 86 20
+
+#----------------------------------------------------------------
+# URPM (2kOhms/sq. poly implant)
+#----------------------------------------------------------------
+
+ layer URPM
+ bloat-all uhrpoly xpc
+ grow 200
+ grow-min 1270
+ grow 420
+ shrink 420
+ calma 79 20
+
+#----------------------------------------------------------------
+# LDNTM (Tip implant for SONOS FETs)
+#----------------------------------------------------------------
+
+ layer LDNTM
+ bloat-all nsonos *ndiff
+ grow 185
+ grow 345
+ shrink 345
+ calma 11 44
+
+#----------------------------------------------------------------
+# HVNTM (Tip implant for MV ndiff devices)
+#----------------------------------------------------------------
+
+ templayer hvntm_block *mvpsd
+ grow 185
+
+ layer HVNTM
+ bloat-all mvnfet,mvnnfet,*mvndiode,mvrdn,*nndiode *mvndiff
+ bloat-all mvvaractor *mvnsd
+ and-not hvntm_block
+ grow 185
+ grow 345
+ shrink 345
+ calma 125 20
+
+#----------------------------------------------------------------
+# POLY
+#----------------------------------------------------------------
+
+ layer POLY allpoly
+ calma 66 20
+
+ layer POLYTXT
+ labels allpoly noport
+ calma 66 16
+
+ layer POLYPIN
+ labels allpoly port
+ calma 66 5
+
+#----------------------------------------------------------------
+# THKOX (HVI) (includes rules NWELL 8-11 and DIFFTAP 14-26)
+#----------------------------------------------------------------
+
+ templayer baseTHKOX *mvpsd
+ grow-min 470
+ or alldiffmv,mvvar
+ grow 185
+ bloat-all alldiffmv nwell
+ grow-min 600
+ bridge 700 600
+
+ templayer extendTHKOX baseTHKOX,CELLRING
+ grow 345
+ shrink 345
+ and-not CELLRING
+
+ layer THKOX baseTHKOX,extendTHKOX
+ calma 75 20
+
+#----------------------------------------------------------------
+# CONT (LICON)
+#----------------------------------------------------------------
+
+ layer CONT allcont
+ squares-grid 0 170 170
+ calma 66 44
+
+ # Contact for pres is different than other LICON contacts
+ # See rules LICON 1b, 1c (width/length) and 2b (spacing)
+ templayer xpc_horiz xpc
+ shrink 1007
+ grow 1007
+
+ layer CONT xpc
+ and-not xpc_horiz
+ # Force long edge vertical for contacts narrower than 2um
+ # Minimum space is 350 but 520 satisfies no. of contacts rule
+ slots 80 190 520 80 2000 350
+ calma 66 44
+
+ layer CONT xpc
+ and xpc_horiz
+ # Force long edge vertical for contacts wider than 2um
+ # Minimum space is 350 but 520 satisfies no. of contacts rule
+ slots 80 2000 350 80 190 520
+ calma 66 44
+
+#----------------------------------------------------------------
+# NPC (Nitride poly cut)
+# surrounds CONT (LICON) on poly only (i.e., pc)
+#----------------------------------------------------------------
+
+ layer NPC pc
+ squares-grid 0 170 170
+ grow 100
+ bridge 270 270
+ grow 130
+ shrink 130
+ calma 95 20
+
+ # NPC is also generated on xhrpoly and uhrpoly resistors
+
+ layer NPC xpc,xhrpoly,uhrpoly
+ # xpc surrounds precision_resistor by 0.095um
+ grow 95
+ grow 130
+ shrink 130
+ calma 95 20
+
+#----------------------------------------------------------------
+# Device markers
+#----------------------------------------------------------------
+
+ layer DIFFRES rdn,mvrdn,rdp,mvrdp
+ calma 65 13
+
+ layer POLYRES mrp1
+ calma 66 13
+
+ # POLYSHORT is a poly layer resistor like rli, rm1, etc., for metal layers
+ layer POLYSHORT rmp
+ calma 66 15
+
+ # POLYRES extends to edge of contact cut
+ layer POLYRES xhrpoly,uhrpoly
+ grow 60
+ and xpc
+ or xhrpoly,uhrpoly
+ calma 66 13
+
+ layer DIODE *pdi,*ndi,*nndi,*mvpdi,*mvndi,*pdilvt,*pdihvt,*ndilvt
+ # To be done: Expand to include anode, cathode, and guard ring
+ calma 81 23
+
+#----------------------------------------------------------------
+# LI
+#----------------------------------------------------------------
+ layer LI allli
+ calma 67 20
+
+ layer LITXT
+ labels *locali,coreli noport
+ calma 67 16
+
+ layer LIPIN
+ labels *locali,coreli port
+ calma 67 5
+
+ layer LIRES rli
+ labels rli
+ calma 67 13
+
+#----------------------------------------------------------------
+# MCON
+#----------------------------------------------------------------
+ layer MCON lic
+ squares-grid 0 170 190
+ calma 67 44
+
+#----------------------------------------------------------------
+# MET1
+#----------------------------------------------------------------
+ layer MET1 allm1
+ calma 68 20
+
+ layer MET1TXT
+ labels allm1 noport
+ calma 68 16
+
+ layer MET1PIN
+ labels allm1 port
+ calma 68 5
+
+ layer MET1RES rm1
+ labels rm1
+ calma 68 13
+
+#----------------------------------------------------------------
+# VIA1
+#----------------------------------------------------------------
+ layer VIA1 via1
+ squares-grid 55 150 170
+ calma 68 44
+
+#----------------------------------------------------------------
+# MET2
+#----------------------------------------------------------------
+ layer MET2 allm2
+ calma 69 20
+
+ layer MET2TXT
+ labels allm2 noport
+ calma 69 16
+
+ layer MET2PIN
+ labels allm2 port
+ calma 69 5
+
+ layer MET2RES rm2
+ labels rm2
+ calma 69 13
+
+#----------------------------------------------------------------
+# VIA2
+#----------------------------------------------------------------
+ layer VIA2 via2
+ squares-grid 40 200 200
+ calma 69 44
+
+#----------------------------------------------------------------
+# MET3
+#----------------------------------------------------------------
+ layer MET3 allm3
+ calma 70 20
+
+ layer MET3TXT
+ labels allm3 noport
+ calma 70 16
+
+ layer MET3PIN
+ labels allm3 port
+ calma 70 5
+
+ layer MET3RES rm3
+ labels rm3
+ calma 70 13
+
+#ifdef METAL5
+#----------------------------------------------------------------
+# VIA3
+#----------------------------------------------------------------
+ layer VIA3 via3
+#ifdef MIM
+ or mimcc
+#endif (MIM)
+ squares-grid 60 200 200
+ calma 70 44
+
+#----------------------------------------------------------------
+# MET4
+#----------------------------------------------------------------
+ layer MET4 allm4
+ calma 71 20
+
+ layer MET4TXT
+ labels allm4 noport
+ calma 71 16
+
+ layer MET4PIN
+ labels allm4 port
+ calma 71 5
+
+ layer MET4RES rm4
+ labels rm4
+ calma 71 13
+
+#----------------------------------------------------------------
+# VIA4
+#----------------------------------------------------------------
+ layer VIA4 via4
+#ifdef MIM
+ or mim2cc
+#endif (MIM)
+ squares-grid 190 800 800
+ calma 71 44
+
+#----------------------------------------------------------------
+# MET5
+#----------------------------------------------------------------
+ layer MET5 allm5
+ calma 72 20
+
+ layer MET5TXT
+ labels allm5 noport
+ calma 72 16
+
+ layer MET5PIN
+ labels allm5 port
+ calma 72 5
+
+ layer MET5RES rm5
+ labels rm5
+ calma 72 13
+
+#endif (METAL5)
+
+#ifdef REDISTRIBUTION
+#----------------------------------------------------------------
+# RDL
+#----------------------------------------------------------------
+ layer RDL *metrdl
+ calma 74 20
+
+ layer RDLTXT
+ labels *metrdl noport
+ calma 74 16
+
+ layer RDLPIN
+ labels *metrdl port
+ calma 74 5
+
+#endif REDISTRIBUTION
+
+#----------------------------------------------------------------
+# GLASS
+#----------------------------------------------------------------
+ layer GLASS glass
+ calma 76 20
+
+#ifdef MIM
+#----------------------------------------------------------------
+# CAPM
+#----------------------------------------------------------------
+ layer CAPM *mimcap
+ labels mimcap
+ calma 89 44
+
+ layer CAPM2 *mimcap2
+ labels mimcap2
+ calma 97 44
+#endif (MIM)
+
+#----------------------------------------------------------------
+# Chip top level marker for DRC latchup rules to check 15um
+# distance to taps (otherwise 6um is used)
+#----------------------------------------------------------------
+
+ layer LOWTAPDENSITY
+ bbox top
+ # Clear 200um for pads + 50um for required high tap density
+ # in critical area.
+ shrink 250000
+ calma 81 14
+
+#----------------------------------------------------------------
+# FILLBLOCK
+#----------------------------------------------------------------
+ layer FILLOBSM1 fillblock
+ calma 62 24
+
+ layer FILLOBSM2 fillblock
+ calma 105 52
+
+ layer FILLOBSM3 fillblock
+ calma 107 24
+
+ layer FILLOBSM4 fillblock
+ calma 112 4
+
+ render DNWELL cwell -0.1 0.1
+ render NWELL nwell 0.0 0.2062
+ render DIFF ndiffusion 0.2062 0.12
+ render TAP pdiffusion 0.2062 0.12
+ render POLY polysilicon 0.3262 0.18
+ render CONT via 0.5062 0.43
+ render LI metal1 0.9361 0.10
+ render MCON via 1.0361 0.34
+ render MET1 metal2 1.3761 0.36
+ render VIA1 via 1.7361 0.27
+ render MET2 metal3 2.0061 0.36
+ render VIA2 via 2.3661 0.42
+ render MET3 metal4 2.7861 0.845
+#ifdef METAL5
+ render VIA3 via 3.6311 0.39
+ render MET4 metal5 4.0211 0.845
+ render VIA4 via 4.8661 0.505
+ render MET5 metal6 5.3711 1.26
+ render CAPM metal8 2.4661 0.2
+ render CAPM2 metal9 3.7311 0.2
+#ifdef REDISTRIBUTION
+ render RDL metal7 11.8834 4.0
+#endif (!REDISTRIBUTION)
+#endif (!METAL5)
+
+#----------------------------------------------------------------
+style drc
+#----------------------------------------------------------------
+# NOTE: This style is used for DRC only, not for GDS output
+#----------------------------------------------------------------
+ scalefactor 10 nanometers
+ options calma-permissive-labels
+
+ # Ensure nwell overlaps dnwell at least 0.4um outside and 1.03um inside
+ templayer dnwell_shrink dnwell
+ shrink 1030
+
+ templayer nwell_missing dnwell
+ grow 400
+ and-not dnwell_shrink
+ and-not nwell
+
+ # SONOS nFET devices must be in deep nwell
+ templayer dnwell_missing nsonos
+ and-not dnwell
+
+ # Define MiM cap bottom plate for spacing rule
+ templayer mim_bottom
+ bloat-all *mimcap *metal3
+
+ # Define MiM2 cap bottom plate for spacing rule
+ templayer mim2_bottom
+ bloat-all *mimcap2 *metal4
+
+ # Note that metal fill is performed by the foundry and so is not
+ # an option for a cifoutput style.
+
+ # Check latchup rule (15um minimum from tap LICON center to any
+ # non-tap diffusion. Note that to count as a tap, the diffusion
+ # must be contacted to LI
+
+ templayer ptap_reach psc,mvpsc
+ and-not dnwell
+ # grow total is 15um. grow in 0.84um increments to ensure that
+ # no nwell ring is crossed
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 840
+ and-not nwell,dnwell
+ grow 635
+ and-not nwell,dnwell
+
+ templayer ptap_missing *ndiff,*mvndiff
+ and-not dnwell
+ and-not ptap_reach
+
+ templayer ntap_reach nsc,mvnsc
+ # grow total is 15um. grow in 1.27um increments to ensure that
+ # no nwell ring is crossed. There is no difference between
+ # ntaps in and out of deep nwell.
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 1270
+ and nwell
+ grow 945
+ and nwell
+
+ templayer ntap_missing *pdiff,*mvpdiff
+ and-not dnwell
+ and-not ntap_reach
+
+ templayer dptap_reach psc,mvpsc
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 840
+ and-not nwell
+ and dnwell
+ grow 635
+ and-not nwell
+ and dnwell
+
+ templayer dptap_missing *ndiff,*mvndiff
+ and dnwell
+ and-not dptap_reach
+
+ templayer m1_small_hole *m1
+ close 140000
+
+ templayer m1_hole_empty m1_small_hole
+ and-not *m1
+
+ templayer m2_small_hole *m2
+ close 140000
+
+ templayer m2_hole_empty m2_small_hole
+ and-not *m2
+
+#ifdef EXPERIMENTAL
+#----------------------------------------------------------------
+style paint
+#----------------------------------------------------------------
+# NOTE: This style is used for database manipulations only via
+# the "cif paint" command.
+#----------------------------------------------------------------
+
+ scalefactor 10 nanometers
+
+ templayer m1grow *m1
+ grow 290
+
+ # layer listrap: Use the following set of commands to strap local
+ # interconnect wires with metal1 (inside the cursor box) to satisfy
+ # the maximum aspect ratio rule for local interconnect:
+ #
+ # tech unlock *
+ # cif ostyle paint
+ # cif paint m1strap comment
+ # cif paint m1strap m1
+ # cif paint listrap licon
+ # erase comment
+
+ templayer m1strap *li
+ and-not m1grow
+ grow 30
+
+ templayer listrap comment
+ slots 30 170 170 60
+
+#endif (EXPERIMENTAL)
+
+end
+
+#-----------------------------------------------------------------------
+cifinput
+#-----------------------------------------------------------------------
+# NOTE: All values in this section MUST be multiples of 25
+# or else magic will scale below the allowed layout grid size
+#-----------------------------------------------------------------------
+
+style vendorimport
+ scalefactor 10 nanometers
+ gridlimit 5
+
+ options ignore-unknown-layer-labels no-reconnect-labels
+
+#ifndef MIM
+ ignore CAPM
+ ignore CAPM2
+#endif (!MIM)
+#ifndef METAL5
+ ignore MET4,VIA3
+ ignore MET5,VIA4
+#endif
+ ignore NPC
+ ignore SEALID
+ ignore NPNID
+ ignore PNPID
+ ignore CAPID
+ ignore LDNTM
+ ignore HVNTM
+ ignore POLYMOD
+ ignore LOWTAPDENSITY
+
+ layer nwell NWELL,WELLTXT,WELLPIN
+ labels NWELL
+ labels WELLTXT text
+ labels WELLPIN port
+
+ layer pwell SUBTXT,SUBPIN
+ labels SUBTXT text
+ labels SUBPIN port
+
+ layer dnwell DNWELL
+ labels DNWELL
+
+ layer rpw PWRES
+ and DNWELL
+ labels PWRES
+
+ templayer ndiffarea DIFF,DIFFTXT,DIFFPIN
+ and-not POLY
+ and-not NWELL
+ and-not PPLUS
+ and-not DIODE
+ and-not DIFFRES
+ and-not THKOX
+ and NPLUS
+ copyup ndifcheck
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+ labels TAPPIN port
+
+ layer ndiff ndiffarea
+
+ # Copy ndiff areas up for contact checks
+ templayer xndifcheck ndifcheck
+ copyup ndifcheck
+
+ templayer mvndiffarea DIFF,DIFFTXT,DIFFPIN
+ and-not POLY
+ and-not NWELL
+ and-not PPLUS
+ and-not DIODE
+ and-not DIFFRES
+ and THKOX
+ and NPLUS
+ copyup ndifcheck
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+
+ layer mvndiff mvndiffarea
+
+ # Copy ndiff areas up for contact checks
+ templayer mvxndifcheck mvndifcheck
+ copyup mvndifcheck
+
+ layer ndiode DIFF
+ and NPLUS
+ and DIODE
+ and-not NWELL
+ and-not POLY
+ and-not PPLUS
+ and-not THKOX
+ and-not LVTN
+ labels DIFF
+
+ layer ndiodelvt DIFF
+ and NPLUS
+ and DIODE
+ and-not NWELL
+ and-not POLY
+ and-not PPLUS
+ and-not THKOX
+ and LVTN
+ labels DIFF
+
+ templayer ndiodearea DIODE
+ and NPLUS
+ and-not THKOX
+ and-not NWELL
+ copyup DIODE,NPLUS
+
+ layer ndiffres DIFFRES
+ and NPLUS
+ and-not THKOX
+ labels DIFF
+
+ templayer pdiffarea DIFF,DIFFTXT,DIFFPIN
+ and-not POLY
+ and NWELL
+ and-not NPLUS
+ and-not DIODE
+ and-not THKOX
+ and PPLUS
+ copyup pdifcheck
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+
+ layer pdiff pdiffarea
+
+ layer mvndiode DIFF
+ and NPLUS
+ and DIODE
+ and THKOX
+ and-not POLY
+ and-not PPLUS
+ and-not LVTN
+ labels DIFF
+
+ layer nndiode DIFF
+ and NPLUS
+ and DIODE
+ and THKOX
+ and-not POLY
+ and-not PPLUS
+ and LVTN
+ labels DIFF
+
+ templayer mvndiodearea DIODE
+ and NPLUS
+ and THKOX
+ and-not NWELL
+ copyup DIODE,NPLUS
+
+ layer mvndiffres DIFFRES
+ and NPLUS
+ and THKOX
+ labels DIFF
+
+ templayer mvpdiffarea DIFF,DIFFTXT,DIFFPIN
+ and-not POLY
+ and NWELL
+ and-not NPLUS
+ and THKOX
+ and-not DIODE
+ and-not DIFFRES
+ and PPLUS
+ copyup mvpdifcheck
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+
+ layer mvpdiff mvpdiffarea
+
+ # Copy pdiff areas up for contact checks
+ templayer xpdifcheck pdifcheck
+ copyup pdifcheck
+
+ layer pdiode DIFF
+ and PPLUS
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and-not LVTN
+ and-not HVTP
+ and DIODE
+ labels DIFF
+
+ layer pdiodelvt DIFF
+ and PPLUS
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and LVTN
+ and-not HVTP
+ and DIODE
+ labels DIFF
+
+ layer pdiodehvt DIFF
+ and PPLUS
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and-not LVTN
+ and HVTP
+ and DIODE
+ labels DIFF
+
+ templayer pdiodearea DIODE
+ and PPLUS
+ and-not THKOX
+ copyup DIODE,PPLUS
+
+ # Define pfet areas as known pdiff, regardless of the presence of a well.
+
+ templayer pfetarea DIFF
+ and-not NPLUS
+ and-not THKOX
+ and POLY
+
+ layer pfet pfetarea
+ and-not LVTN
+ and-not HVTP
+ and-not STDCELL
+ labels DIFF
+
+ layer scpfet pfetarea
+ and-not LVTN
+ and-not HVTP
+ and STDCELL
+ labels DIFF
+
+ layer pfetlvt pfetarea
+ and LVTN
+ labels DIFF
+
+ layer pfethvt pfetarea
+ and HVTP
+ labels DIFF
+
+ # Always force nwell under pfet (nwell encloses pdiff by 0.18)
+ layer nwell pfetarea
+ grow 180
+
+ # Copy mvpdiff areas up for contact checks
+ templayer mvxpdifcheck mvpdifcheck
+ copyup mvpdifcheck
+
+ layer mvpdiode DIFF
+ and PPLUS
+ and-not POLY
+ and-not NPLUS
+ and THKOX
+ and DIODE
+ labels DIFF
+
+ templayer mvpdiodearea DIODE
+ and PPLUS
+ and THKOX
+ copyup DIODE,PPLUS
+
+ # Define pfet areas as known pdiff,
+ # regardless of the presence of a
+ # well.
+
+ templayer mvpfetarea DIFF
+ and-not NPLUS
+ and THKOX
+ and POLY
+
+ layer mvpfet mvpfetarea
+ labels DIFF
+
+ layer pdiff DIFF,DIFFTXT,DIFFPIN
+ and-not NPLUS
+ and-not POLY
+ and-not THKOX
+ and-not DIODE
+ and-not DIFFRES
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+
+ layer pdiffres DIFFRES
+ and PPLUS
+ and NWELL
+ and-not THKOX
+ labels DIFF
+
+ layer nfet DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and-not THKOX
+ and-not LVTN
+ and-not SONOS
+ and-not STDCELL
+ labels DIFF
+
+ layer scnfet DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and-not THKOX
+ and-not LVTN
+ and-not SONOS
+ and STDCELL
+ labels DIFF
+
+ layer nfetlvt DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and-not THKOX
+ and LVTN
+ and-not SONOS
+ labels DIFF
+
+ layer nsonos DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and-not THKOX
+ and LVTN
+ and SONOS
+ labels DIFF
+
+ templayer nsdarea DIFF
+ and NPLUS
+ and NWELL
+ and-not POLY
+ and-not PPLUS
+ and-not THKOX
+ copyup nsubcheck
+
+ layer nsd nsdarea
+ labels DIFF
+
+ layer nsd TAP,TAPPIN
+ and NPLUS
+ labels TAP
+ labels TAPPIN port
+
+ templayer nsdexpand nsdarea
+ grow 500
+
+ # Copy nsub areas up for contact checks
+ templayer xnsubcheck nsubcheck
+ copyup nsubcheck
+
+ templayer psdarea DIFF
+ and PPLUS
+ and-not NWELL
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and-not pfetexpand
+ copyup psubcheck
+
+ layer psd psdarea
+ labels DIFF
+
+ layer psd TAP,TAPPIN
+ and PPLUS
+ and-not THKOX
+ labels TAP
+ labels TAPPIN port
+
+ templayer psdexpand psdarea
+ grow 500
+
+ layer mvpdiff DIFF,DIFFTXT,DIFFPIN
+ and-not NPLUS
+ and-not POLY
+ and THKOX
+ and mvpfetexpand
+ labels DIFF
+ labels DIFFTXT text
+ labels DIFFPIN port
+
+ layer mvpdiffres DIFFRES
+ and PPLUS
+ and NWELL
+ and THKOX
+ and-not mvrdpioedge
+ labels DIFF
+
+ layer mvnfet DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and-not LVTN
+ and THKOX
+ labels DIFF
+
+ layer mvnnfet DIFF
+ and POLY
+ and-not PPLUS
+ and NPLUS
+ and LVTN
+ and THKOX
+ labels DIFF
+
+ templayer mvnsdarea DIFF
+ and NPLUS
+ and NWELL
+ and-not POLY
+ and-not PPLUS
+ and THKOX
+ copyup mvnsubcheck
+
+ layer mvnsd mvnsdarea
+ labels DIFF
+
+ layer mvnsd TAP,TAPPIN
+ and NPLUS
+ and THKOX
+ labels TAP
+ labels TAPPIN port
+
+ templayer mvnsdexpand mvnsdarea
+ grow 500
+
+ # Copy nsub areas up for contact checks
+ templayer mvxnsubcheck mvnsubcheck
+ copyup mvnsubcheck
+
+ templayer mvpsdarea DIFF
+ and PPLUS
+ and-not NWELL
+ and-not POLY
+ and-not NPLUS
+ and THKOX
+ and-not mvpfetexpand
+ copyup mvpsubcheck
+
+ layer mvpsd mvpsdarea
+ labels DIFF
+
+ layer mvpsd TAP,TAPPIN
+ and PPLUS
+ and THKOX
+ labels TAP
+ labels TAPPIN port
+
+ templayer mvpsdexpand mvpsdarea
+ grow 500
+
+ # Copy psub areas up for contact checks
+ templayer xpsubcheck psubcheck
+ copyup psubcheck
+
+ templayer mvxpsubcheck mvpsubcheck
+ copyup mvpsubcheck
+
+ layer psd DIFF
+ and-not PPLUS
+ and-not NPLUS
+ and-not POLY
+ and-not THKOX
+ and-not pfetexpand
+ and psdexpand
+
+ layer nsd DIFF
+ and-not PPLUS
+ and-not NPLUS
+ and-not POLY
+ and-not THKOX
+ and nsdexpand
+
+ layer mvpsd DIFF
+ and-not PPLUS
+ and-not NPLUS
+ and-not POLY
+ and THKOX
+ and-not mvpfetexpand
+ and mvpsdexpand
+
+ layer mvnsd DIFF
+ and-not PPLUS
+ and-not NPLUS
+ and-not POLY
+ and THKOX
+ and mvnsdexpand
+
+ templayer hresarea POLY
+ and RPM
+ grow 3000
+
+ templayer uresarea POLY
+ and URPM
+ grow 3000
+
+ templayer diffresarea DIFFRES
+ and-not THKOX
+ grow 3000
+
+ templayer mvdiffresarea DIFFRES
+ and THKOX
+ grow 3000
+
+ templayer resarea diffresarea,mvdiffresarea,hresarea,uresarea
+
+ layer pfet POLY
+ and DIFF
+ and diffresarea
+ and-not NPLUS
+ and-not STDCELL
+
+ layer scpfet POLY
+ and DIFF
+ and diffresarea
+ and-not NPLUS
+ and STDCELL
+
+ templayer xpolyterm RPM,URPM
+ and POLY
+ and-not POLYRES
+ # add back the 0.06um contact surround in the direction of the resistor
+ grow 60
+ and POLY
+
+ layer xpc xpolyterm
+
+ templayer polyarea POLY
+ and-not POLYRES
+ and-not POLYSHORT
+ and-not DIFF
+ and-not RPM
+ and-not URPM
+ copyup polycheck
+
+ layer poly polyarea,POLYTXT,POLYPIN
+ labels POLY
+ labels POLYTXT text
+ labels POLYPIN port
+
+ # Copy (non-resistor) poly areas up for contact checks
+ templayer xpolycheck polycheck
+ copyup polycheck
+
+ layer mrp1 POLY
+ and POLYRES
+ and-not RPM
+ and-not URPM
+ labels POLY
+
+ layer rmp POLY
+ and POLYSHORT
+ labels POLY
+
+ layer xhrpoly POLY
+ and POLYRES
+ and RPM
+ and-not URPM
+ and PPLUS
+ and NPC
+ and-not xpolyterm
+ labels POLY
+
+ layer uhrpoly POLY
+ and POLYRES
+ and URPM
+ and-not RPM
+ and NPC
+ and-not xpolyterm
+ labels POLY
+
+ templayer ndcbase CONT
+ and DIFF
+ and NPLUS
+ and-not NWELL
+ and LI
+ and-not THKOX
+
+ layer ndc ndcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or ndcbase
+ labels CONT
+
+ templayer nscbase CONT
+ and DIFF,TAP
+ and NPLUS
+ and NWELL
+ and LI
+ and-not THKOX
+
+ layer nsc nscbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or nscbase
+ labels CONT
+
+ templayer pdcbase CONT
+ and DIFF
+ and PPLUS
+ and NWELL
+ and LI
+ and-not THKOX
+
+ layer pdc pdcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdcbase
+ labels CONT
+
+ templayer pdcnowell CONT
+ and DIFF
+ and PPLUS
+ and pfetexpand
+ and LI
+ and-not THKOX
+
+ layer pdc pdcnowell
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdcnowell
+ labels CONT
+
+ templayer pscbase CONT
+ and DIFF,TAP
+ and PPLUS
+ and-not NWELL
+ and-not pfetexpand
+ and LI
+ and-not THKOX
+
+ layer psc pscbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pscbase
+ labels CONT
+
+ templayer pcbase CONT
+ and POLY
+ and-not DIFF
+ and-not RPM,URPM
+ and LI
+
+ layer pc pcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pcbase
+ labels CONT
+
+ templayer ndicbase CONT
+ and DIFF
+ and NPLUS
+ and DIODE
+ and-not POLY
+ and-not PPLUS
+ and-not THKOX
+ and-not LVTN
+
+ layer ndic ndicbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or ndicbase
+ labels CONT
+
+ templayer ndilvtcbase CONT
+ and DIFF
+ and NPLUS
+ and DIODE
+ and-not POLY
+ and-not PPLUS
+ and-not THKOX
+ and LVTN
+
+ layer ndilvtc ndilvtcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or ndilvtcbase
+ labels CONT
+
+ templayer pdicbase CONT
+ and DIFF
+ and PPLUS
+ and DIODE
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and-not LVTN
+ and-not HVTP
+
+ layer pdic pdicbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdicbase
+ labels CONT
+
+ templayer pdilvtcbase CONT
+ and DIFF
+ and PPLUS
+ and DIODE
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and LVTN
+ and-not HVTP
+
+ layer pdilvtc pdilvtcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdilvtcbase
+ labels CONT
+
+ templayer pdihvtcbase CONT
+ and DIFF
+ and PPLUS
+ and DIODE
+ and-not POLY
+ and-not NPLUS
+ and-not THKOX
+ and-not LVTN
+ and HVTP
+
+ layer pdihvtc pdihvtcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdihvtcbase
+ labels CONT
+
+ templayer mvndcbase CONT
+ and DIFF
+ and NPLUS
+ and-not NWELL
+ and LI
+ and THKOX
+
+ layer mvndc mvndcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvndcbase
+ labels CONT
+
+ templayer mvnscbase CONT
+ and DIFF,TAP
+ and NPLUS
+ and NWELL
+ and LI
+ and THKOX
+
+ layer mvnsc mvnscbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvnscbase
+ labels CONT
+
+ templayer mvpdcbase CONT
+ and DIFF
+ and PPLUS
+ and NWELL
+ and LI
+ and THKOX
+
+ layer mvpdc mvpdcbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpdcbase
+ labels CONT
+
+ templayer mvpdcnowell CONT
+ and DIFF
+ and PPLUS
+ and mvpfetexpand
+ and MET1
+ and THKOX
+
+ layer mvpdc mvpdcnowell
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpdcnowell
+ labels CONT
+
+ templayer mvpscbase CONT
+ and DIFF,TAP
+ and PPLUS
+ and-not NWELL
+ and-not mvpfetexpand
+ and LI
+ and THKOX
+
+ layer mvpsc mvpscbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpscbase
+ labels CONT
+
+ templayer mvndicbase CONT
+ and DIFF
+ and NPLUS
+ and DIODE
+ and-not POLY
+ and-not PPLUS
+ and-not LVTN
+ and THKOX
+
+ layer mvndic mvndicbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvndicbase
+ labels CONT
+
+ templayer nndicbase CONT
+ and DIFF
+ and NPLUS
+ and DIODE
+ and-not POLY
+ and-not PPLUS
+ and LVTN
+ and THKOX
+
+ layer nndic nndicbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or nndicbase
+ labels CONT
+
+ templayer mvpdicbase CONT
+ and DIFF
+ and PPLUS
+ and DIODE
+ and-not POLY
+ and-not NPLUS
+ and THKOX
+
+ layer mvpdic mvpdicbase
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpdicbase
+ labels CONT
+
+ layer locali LI,LITXT,LIPIN
+ and-not LIRES,LISHORT
+ and-not COREID
+ labels LI
+ labels LITXT text
+ labels LIPIN port
+
+ layer coreli LI,LITXT,LIPIN
+ and-not LIRES,LISHORT
+ and COREID
+ labels LI
+ labels LITXT text
+ labels LIPIN port
+
+ layer rli LI
+ and LIRES,LISHORT
+ labels LIRES,LISHORT
+
+ layer lic MCON
+ grow 95
+ shrink 95
+ shrink 85
+ grow 85
+ or MCON
+ labels MCON
+
+ layer m1 MET1,MET1TXT,MET1PIN
+ and-not MET1RES,MET1SHORT
+ labels MET1
+ labels MET1TXT text
+ labels MET1PIN port
+
+ layer rm1 MET1
+ and MET1RES,MET1SHORT
+ labels MET1RES,MET1SHORT
+
+#ifdef MIM
+ layer mimcap MET3
+ and CAPM
+ labels CAPM
+
+ layer mimcc VIA3
+ and CAPM
+ grow 60
+ grow 40
+ shrink 40
+ labels CAPM
+
+ layer mimcap2 MET4
+ and CAPM2
+ labels CAPM2
+
+ layer mim2cc VIA4
+ and CAPM2
+ grow 190
+ grow 210
+ shrink 210
+ labels CAPM2
+
+#endif (MIM)
+
+ templayer m2cbase VIA1
+ grow 55
+
+ layer m2c m2cbase
+ grow 30
+ shrink 30
+ shrink 130
+ grow 130
+ or m2cbase
+
+ layer m2 MET2,MET2TXT,MET2PIN
+ and-not MET2RES,MET2SHORT
+ labels MET2
+ labels MET2TXT text
+ labels MET2PIN port
+
+ layer rm2 MET2
+ and MET2RES,MET2SHORT
+ labels MET2RES,MET2SHORT
+
+ templayer m3cbase VIA2
+ grow 40
+
+ layer m3c m3cbase
+ grow 60
+ shrink 60
+ shrink 140
+ grow 140
+ or m3cbase
+
+ layer m3 MET3,MET3TXT,MET3PIN
+ and-not MET3RES,MET3SHORT
+#ifdef MIM
+ and-not CAPM
+#endif (MIM)
+ labels MET3
+ labels MET3TXT text
+ labels MET3PIN port
+
+ layer rm3 MET3
+ and MET3RES,MET3SHORT
+ labels MET3RES,MET3SHORT
+
+#ifdef (METAL5)
+
+ templayer via3base VIA3
+#ifdef MIM
+ and-not CAPM
+#endif (MIM)
+ grow 60
+
+ layer via3 via3base
+ grow 40
+ shrink 40
+ shrink 160
+ grow 160
+ or via3base
+
+ layer m4 MET4,MET4TXT,MET4PIN
+ and-not MET4RES,MET4SHORT
+#ifdef MIM
+ and-not CAPM2
+#endif (MIM)
+ labels MET4
+ labels MET4TXT text
+ labels MET4PIN port
+
+ layer rm4 MET4
+ and MET4RES,MET4SHORT
+ labels MET4RES,MET4SHORT
+
+ layer m5 MET5,MET5TXT,MET5PIN
+ and-not MET5RES,MET5SHORT
+ labels MET5
+ labels MET5TXT text
+ labels MET5PIN port
+
+ layer rm5 MET5
+ and MET5RES,MET5SHORT
+ labels MET5RES,MET5SHORT
+
+ templayer via4base VIA4
+#ifdef MIM
+ and-not CAPM2
+#endif (MIM)
+ grow 190
+
+ layer via4 via4base
+ grow 210
+ shrink 210
+ shrink 590
+ grow 590
+ or via4base
+#endif (METAL5)
+
+#ifdef REDISTRIBUTION
+ layer metrdl RDL,RDLTXT,RDLPIN
+ labels RDL
+ labels RDLTXT text
+ labels RDLPIN port
+#endif
+
+ # Find diffusion not covered in
+ # NPLUS or PPLUS and pull it into
+ # the next layer up
+
+ templayer gentrans DIFF
+ and-not PPLUS
+ and-not NPLUS
+ and POLY
+ copyup DIFF,POLY
+
+ templayer gendiff DIFF,TAP
+ and-not PPLUS
+ and-not NPLUS
+ and-not POLY
+ copyup DIFF
+
+ # Handle contacts found by copyup
+
+ templayer ndiccopy CONT
+ and LI
+ and DIODE
+ and NPLUS
+ and-not THKOX
+
+ layer ndic ndiccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or ndiccopy
+ labels CONT
+
+ templayer mvndiccopy CONT
+ and LI
+ and DIODE
+ and NPLUS
+ and THKOX
+
+ layer mvndic mvndiccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvndiccopy
+ labels CONT
+
+ templayer pdiccopy CONT
+ and LI
+ and DIODE
+ and PPLUS
+ and-not THKOX
+
+ layer pdic pdiccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdiccopy
+ labels CONT
+
+ templayer mvpdiccopy CONT
+ and LI
+ and DIODE
+ and PPLUS
+ and THKOX
+
+ layer mvpdic mvpdiccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpdiccopy
+ labels CONT
+
+ templayer ndccopy CONT
+ and ndifcheck
+
+ layer ndc ndccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or ndccopy
+ labels CONT
+
+ templayer mvndccopy CONT
+ and mvndifcheck
+
+ layer mvndc mvndccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvndccopy
+ labels CONT
+
+ templayer pdccopy CONT
+ and pdifcheck
+
+ layer pdc pdccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pdccopy
+ labels CONT
+
+ templayer mvpdccopy CONT
+ and mvpdifcheck
+
+ layer mvpdc mvpdccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpdccopy
+ labels CONT
+
+ templayer pccopy CONT
+ and polycheck
+
+ layer pc pccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or pccopy
+ labels CONT
+
+ templayer nsccopy CONT
+ and nsubcheck
+
+ layer nsc nsccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or nsccopy
+ labels CONT
+
+ templayer mvnsccopy CONT
+ and mvnsubcheck
+
+ layer mvnsc mvnsccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvnsccopy
+ labels CONT
+
+ templayer psccopy CONT
+ and psubcheck
+
+ layer psc psccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or psccopy
+ labels CONT
+
+ templayer mvpsccopy CONT
+ and mvpsubcheck
+
+ layer mvpsc mvpsccopy
+ grow 85
+ shrink 85
+ shrink 85
+ grow 85
+ or mvpsccopy
+ labels CONT
+
+ # Find contacts not covered in
+ # metal and pull them into the
+ # next layer up
+
+ templayer gencont CONT
+ and LI
+ and-not DIFF,TAP
+ and-not POLY
+ and-not DIODE
+ and-not nsubcheck
+ and-not psubcheck
+ and-not mvnsubcheck
+ and-not mvpsubcheck
+ copyup CONT,LI
+
+ templayer barecont CONT
+ and-not LI
+ and-not nsubcheck
+ and-not psubcheck
+ and-not mvnsubcheck
+ and-not mvpsubcheck
+ copyup CONT
+
+ layer glass GLASS,PADTXT,PADPIN
+ labels GLASS
+ labels PADTXT text
+ labels PADPIN port
+
+ templayer boundary BOUND,STDCELL,PADCELL
+ boundary
+
+ layer comment LVSTEXT
+ labels LVSTEXT text
+
+ layer comment TTEXT
+ labels TTEXT text
+
+ layer fillblock FILLOBSM1,FILLOBSM2,FILLOBSM3,FILLOBSM4
+ labels FILLOBSM1,FILLOBSM2,FILLOBSM3,FILLOBSM4
+
+# MOS Varactor
+
+ layer var POLY
+ and DIFF
+ and NPLUS
+ and NWELL
+ and-not THKOX
+ and-not HVTP
+ grow 25
+ labels POLY
+
+ layer varhvt POLY
+ and DIFF
+ and NPLUS
+ and NWELL
+ and-not THKOX
+ and HVTP
+ grow 25
+ labels POLY
+
+ layer mvvar POLY
+ and DIFF
+ and NPLUS
+ and NWELL
+ and THKOX
+ grow 25
+ labels POLY
+
+ calma NWELL 64 20
+ calma DIFF 65 20
+ calma DNWELL 64 18
+ calma PWRES 64 13
+ calma TAP 65 44
+ # LVTN
+ calma LVTN 125 44
+ # HVTP
+ calma HVTP 78 44
+ # SONOS (TUNM)
+ calma SONOS 80 20
+ # NPLUS = NSDM
+ calma NPLUS 93 44
+ # PPLUS = PSDM
+ calma PPLUS 94 20
+ # HVI
+ calma THKOX 75 20
+ # NPC
+ calma NPC 95 20
+ # P+ POLY MASK
+ calma RPM 86 20
+ calma URPM 79 20
+ calma LDNTM 11 44
+ calma HVNTM 125 20
+ # Poly resistor ID mark
+ calma POLYRES 66 13
+ # Diffusion resistor ID mark
+ calma DIFFRES 65 13
+ calma POLY 66 20
+ calma POLYMOD 66 83
+ # Diode ID mark
+ calma DIODE 81 23
+ # Bipolar NPN mark
+ calma NPNID 82 20
+ # Bipolar PNP mark
+ calma PNPID 82 20
+ # Capacitor ID
+ calma CAPID 82 64
+ # Core area ID mark
+ calma COREID 81 2
+ # Standard cell ID mark
+ calma STDCELL 81 4
+ # Padframe cell ID mark
+ calma PADCELL 81 3
+ # Seal ring ID mark
+ calma SEALID 81 1
+ # Low tap density ID mark
+ calma LOWTAPDENSITY 81 14
+
+ # LICON
+ calma CONT 66 44
+ calma LI 67 20
+ calma MCON 67 44
+
+ calma MET1 68 20
+ calma VIA1 68 44
+ calma MET2 69 20
+ calma VIA2 69 44
+ calma MET3 70 20
+#ifdef METAL5
+ calma VIA3 70 44
+ calma MET4 71 20
+ calma VIA4 71 44
+ calma MET5 72 20
+#endif
+#ifdef REDISTRIBUTION
+ calma RDL 74 20
+#endif
+ calma GLASS 76 20
+
+ calma SUBPIN 64 59
+ calma PADPIN 76 5
+ calma DIFFPIN 65 6
+ calma TAPPIN 65 5
+ calma WELLPIN 64 5
+ calma LIPIN 67 5
+ calma POLYPIN 66 5
+ calma MET1PIN 68 5
+ calma MET2PIN 69 5
+ calma MET3PIN 70 5
+#ifdef METAL5
+ calma MET4PIN 71 5
+ calma MET5PIN 72 5
+#endif
+#ifdef REDISTRIBUTION
+ calma RDLPIN 74 5
+#endif
+
+ calma LIRES 67 13
+ calma MET1RES 68 13
+ calma MET2RES 69 13
+ calma MET3RES 70 13
+#ifdef METAL5
+ calma MET4RES 71 13
+ calma MET5RES 72 13
+#endif
+
+ calma POLYSHORT 66 15
+ calma LISHORT 67 15
+ calma MET1SHORT 68 15
+ calma MET2SHORT 69 15
+ calma MET3SHORT 70 15
+#ifdef METAL5
+ calma MET4SHORT 71 15
+ calma MET5SHORT 72 15
+#endif
+
+ calma SUBTXT 122 16
+ calma PADTXT 76 16
+ calma DIFFTXT 65 16
+ calma POLYTXT 66 16
+ calma WELLTXT 64 16
+ calma LITXT 67 16
+ calma MET1TXT 68 16
+ calma MET2TXT 69 16
+ calma MET3TXT 70 16
+#ifdef METAL5
+ calma MET4TXT 71 16
+ calma MET5TXT 72 16
+#endif
+#ifdef REDISTRIBUTION
+ calma RDLPIN 74 16
+#endif
+
+ calma BOUND 235 4
+
+ calma LVSTEXT 83 44
+
+#ifdef (MIM)
+ calma CAPM 89 44
+ calma CAPM2 97 44
+#endif (MIM)
+
+ calma FILLOBSM1 62 24
+ calma FILLOBSM2 105 52
+ calma FILLOBSM3 107 24
+ calma FILLOBSM4 112 4
+
+end
+
+#-----------------------------------------------------
+# Digital flow maze router cost parameters
+#-----------------------------------------------------
+
+mzrouter
+end
+
+#-----------------------------------------------------
+# Vendor DRC rules
+#-----------------------------------------------------
+
+drc
+
+ style drc variants (fast),(full),(routing)
+
+ scalefactor 10
+
+ cifstyle drc
+
+ variants (fast),(full)
+
+#-----------------------------
+# DNWELL
+#-----------------------------
+
+ width dnwell 3000 "Deep N-well width < %d (Dnwell 2)"
+ spacing dnwell dnwell 6300 touching_ok "Deep N-well spacing < %d (Dnwell 3)"
+ spacing dnwell allnwell 4500 surround_ok \
+ "Deep N-well spacing to N-well < %d (Nwell 7)"
+ cifmaxwidth nwell_missing 0 bend_illegal \
+ "N-well overlap of Deep N-well < 0.4um outside, 1.03um inside (Nwell 5a, 7)"
+ cifmaxwidth dnwell_missing 0 bend_illegal \
+ "SONOS nFET must be in Deep N-well (Tunm 6a)"
+
+#-----------------------------
+# NWELL
+#-----------------------------
+
+ width allnwell 840 "N-well width < %d (Nwell 1)"
+ spacing allnwell allnwell 1270 touching_ok "N-well spacing < %d (Nwell 2a)"
+
+#-----------------------------
+# DIFF
+#-----------------------------
+
+ width *ndiff,nfet,scnfet,*nsd,*ndiode,ndiffres,*pdiff,pfet,scpfet,*psd,*pdiode,pdiffres \
+ 150 "Diffusion width < %d (Diff/tap 1)"
+ width *mvndiff,mvnfet,mvnnfet,*mvndiode,*nndiode,mvndiffres,*mvpdiff,mvpfet,*mvpdiode 290 \
+ "MV Diffusion width < %d (Diff/tap 14)"
+ width *mvnsd,*mvpsd 150 "MV Tap width < %d (Diff/tap 1)"
+ extend *mvpsd *mvndiff 700 "MV Butting tap length < %d (Diff/tap 16)"
+ extend *mvnsd *mvpdiff 700 "MV Butting tap length < %d (Diff/tap 16)"
+ extend *psd *ndiff 290 "Butting tap length < %d (Diff/tap 4)"
+ extend *nsd *pdiff 290 "Butting tap length < %d (Diff/tap 4)"
+ width mvpdiffres 150 "MV P-Diffusion resistor width < %d (Diff/tap 14a)"
+ spacing alldifflv,var,varhvt alldifflv,var,varhvt 270 touching_ok \
+ "Diffusion spacing < %d (Diff/tap 3)"
+ spacing alldiffmvnontap,mvvar alldiffmvnontap,mvvar 300 touching_ok \
+ "MV Diffusion spacing < %d (Diff/tap 15a)"
+ spacing alldiffmv *mvnsd,*mvpsd 270 touching_ok \
+ "MV Diffusion to MV tap spacing < %d (Diff/tap 3)"
+ spacing *mvndiff,mvnfet,mvnnfet,*mvndiode,*nndiode,mvndiffres,mvvar *mvpsd 370 \
+ touching_ok "MV P-Diffusion to MV N-tap spacing < %d (Diff/tap 15b)"
+ spacing *mvnsd,*mvpdiff,mvpfet,mvvar,*mvpdiode *mvpsd,*psd 760 touching_illegal \
+ "MV Diffusion in N-well to P-tap spacing < %d (Diff/tap 20 + Diff/tap 17,19)"
+ spacing *ndiff,*ndiode,nfet allnwell 340 touching_illegal \
+ "N-Diffusion spacing to N-well < %d (Diff/tap 9)"
+ spacing *mvndiff,*mvndiode,mvnfet,mvnnfet allnwell 340 touching_illegal \
+ "N-Diffusion spacing to N-well < %d (Diff/tap 9)"
+ spacing *psd allnwell 130 touching_illegal \
+ "P-tap spacing to N-well < %d (Diff/tap 11)"
+ spacing *mvpsd allnwell 130 touching_illegal \
+ "P-tap spacing to N-well < %d (Diff/tap 11)"
+ surround *nsd allnwell 180 absence_illegal \
+ "N-well overlap of N-tap < %d (Diff/tap 10)"
+ surround *mvnsd allnwell 330 absence_illegal \
+ "N-well overlap of MV N-tap < %d (Diff/tap 19)"
+ surround *pdiff,*pdiode,pfet,scpfet allnwell 180 absence_illegal \
+ "N-well overlap of P-Diffusion < %d (Diff/tap 8)"
+ surround *mvpdiff,*mvpdiode,mvpfet allnwell 330 absence_illegal \
+ "N-well overlap of P-Diffusion < %d (Diff/tap 17)"
+ surround mvvar allnwell 560 absence_illegal \
+ "N-well overlap of MV varactor < %d (LVTN 10 + LVTN 4b)"
+ spacing *mvndiode *mvndiode 1070 touching_ok \
+ "MV N-diode spacing < %d (HVNTM.2 + 2 * HVNTM.3)"
+
+ # Butting junction rules
+ edge4way (*psd)/a ~(*ndiff,*psd)/a 125 ~(*ndiff)/a (*ndiff)/a 125 \
+ "N-Diffusion to P-tap spacing < %d across butted junction"
+ edge4way (*ndiff)/a ~(*ndiff,*psd)/a 125 ~(*psd)/a (*psd)/a 125 \
+ "N-Diffusion to P-tap spacing < %d across butted junction"
+ edge4way (*nsd)/a ~(*pdiff,*nsd)/a 125 ~(*pdiff)/a (*pdiff)/a 125 \
+ "P-Diffusion to N-tap spacing < %d across butted junction"
+ edge4way (*pdiff)/a ~(*pdiff,*nsd)/a 125 ~(*nsd)/a (*nsd)/a 125 \
+ "P-Diffusion to N-tap spacing < %d across butted junction"
+
+ edge4way (*mvpsd)/a ~(*mvndiff,*mvpsd)/a 125 ~(*mvndiff)/a (*mvndiff)/a 125 \
+ "MV N-Diffusion to MV P-tap spacing < %d across butted junction"
+ edge4way (*mvndiff)/a ~(*mvndiff,*mvpsd)/a 125 ~(*mvpsd)/a (*mvpsd)/a 125 \
+ "MV N-Diffusion to MV P-tap spacing < %d across butted junction"
+ edge4way (*mvnsd)/a ~(*mvpdiff,*mvnsd)/a 125 ~(*mvpdiff)/a (*mvpdiff)/a 125 \
+ "MV P-Diffusion to MV N-tap spacing < %d across butted junction"
+ edge4way (*mvpdiff)/a ~(*mvpdiff,*mvnsd)/a 125 ~(*mvnsd)/a (*mvnsd)/a 125 \
+ "MV P-Diffusion to MV N-tap spacing < %d across butted junction"
+
+ variants (full)
+
+ # Latchup rules
+ cifmaxwidth ptap_missing 0 bend_illegal \
+ "N-diff distance to P-tap must be < 15.0um (LU 2)"
+ cifmaxwidth dptap_missing 0 bend_illegal \
+ "N-diff distance to P-tap in deep Nwell must be < 15.0um (LU 2.1)"
+ cifmaxwidth ntap_missing 0 bend_illegal \
+ "P-diff distance to N-tap must be < 15.0um (LU 3)"
+
+ variants *
+
+#-----------------------------
+# POLY
+#-----------------------------
+
+ width allpoly 150 "Poly width < %d (Poly 1a)"
+ spacing allpoly allpoly 210 touching_ok "Poly spacing < %d (Poly 2)"
+ spacing allpolynonfet alldifflvnonfet 75 corner_ok allfets \
+ "Poly spacing to Diffusion < %d (Poly 4a)"
+ spacing npres *nsd 480 touching_illegal \
+ "Poly resistor spacing to N-tap < %d (Poly 9)"
+ overhang *ndiff,rndiff nfet,scnfet 250 "N-Diffusion overhang of nmos < %d (Poly 7)"
+ overhang *mvndiff,mvrndiff mvnfet,mvnnfet 250 \
+ "N-Diffusion overhang of nmos < %d (Poly 7)"
+ overhang *pdiff,rpdiff pfet,scpfet 250 "P-Diffusion overhang of pmos < %d (Poly 7)"
+ overhang *mvpdiff,mvrpdiff mvpfet 250 "P-Diffusion overhang of pmos < %d (Poly 7)"
+ overhang *poly allfets 130 "Poly overhang of transistor < %d (Poly 8)"
+ rect_only allfets "No bends in transistors (Poly 11)"
+ rect_only xhrpoly,uhrpoly "No bends in poly resistors (Poly 11)"
+ extend xpc/a xhrpoly,uhrpoly 2160 \
+ "Poly contact extends poly resistor by < %d (LIcon 1c + LI 5)"
+ spacing xhrpoly,uhrpoly xhrpoly,uhrpoly 1240 touching_illegal \
+ "Distance between precision resistors < %d (RPM 2 + 2 * RPM 3)"
+
+#--------------------------------------------------------------------
+# NPC (Nitride Poly Cut)
+#--------------------------------------------------------------------
+
+# Layer NPC is defined automatically around poly contacts (grow 0.1um)
+
+#--------------------------------------------------------------------
+# CONT (LICON, contact between poly/diff and LI)
+#--------------------------------------------------------------------
+
+ width ndc/li 170 "N-diffusion contact width < %d (LIcon 1)"
+ width nsc/li 170 "N-tap contact width < %d (LIcon 1)"
+ width pdc/li 170 "P-diffusion contact width < %d (LIcon 1)"
+ width psc/li 170 "P-tap contact width < %d (LIcon 1)"
+ width ndic/li 170 "N-diode contact width < %d (LIcon 1)"
+ width pdic/li 170 "P-diode contact width < %d (LIcon 1)"
+ width pc/li 170 "Poly contact width < %d (LIcon 1)"
+
+ width xpc/li 350 "Poly resistor contact width < %d (LIcon 1b + 2 * LI 5)"
+
+ width mvndc/li 170 "N-diffusion contact width < %d (LIcon 1)"
+ width mvnsc/li 170 "N-tap contact width < %d (LIcon 1)"
+ width mvpdc/li 170 "P-diffusion contact width < %d (LIcon 1)"
+ width mvpsc/li 170 "P-tap contact width < %d (LIcon 1)"
+ width mvndic/li 170 "N-diode contact width < %d (LIcon 1)"
+ width mvpdic/li 170 "P-diode contact width < %d (LIcon 1)"
+
+ spacing allpdiffcont allndiffcont 170 touching_illegal \
+ "Diffusion contact spacing < %d (LIcon 2)"
+ spacing allndiffcont allndiffcont 170 touching_ok \
+ "Diffusion contact spacing < %d (LIcon 2)"
+ spacing allpdiffcont allpdiffcont 170 touching_ok \
+ "Diffusion contact spacing < %d (LIcon 2)"
+ spacing pc pc 170 touching_ok "Poly1 contact spacing < %d (LIcon 2)"
+
+ spacing pc alldiff 190 touching_illegal \
+ "Poly contact spacing to diffusion < %d (LIcon 14)"
+ spacing pc allpfets 235 touching_illegal \
+ "Poly contact spacing to pFET < %d (LIcon 9 + PSDM 5a)"
+
+ spacing ndc,pdc nfet,pfet 55 touching_illegal \
+ "Diffusion contact to gate < %d (LIcon 11)"
+ spacing ndc,pdc scnfet,scpfet 50 touching_illegal \
+ "Diffusion contact to standard cell gate < %d (LIcon 11)"
+ spacing mvndc,mvpdc mvnfet,mvnnfet,mvpfet 55 touching_illegal \
+ "Diffusion contact to gate < %d (LIcon 11)"
+ spacing ndc,mvndc rnd,mvrnd 60 touching_illegal "Diffusion contact to rndiff < %d ()"
+ spacing pdc,mvpdc rdp,mvrdp 60 touching_illegal "Diffusion contact to rndiff < %d ()"
+ spacing nsc varactor,varhvt 250 touching_illegal \
+ "Diffusion contact to varactor gate < %d (LIcon 10)"
+ spacing mvnsc mvvar 250 touching_illegal \
+ "Diffusion contact to varactor gate < %d (LIcon 10)"
+
+ surround ndc/a *ndiff,nfet,scnfet,nfetlvt 40 absence_illegal \
+ "N-diffusion overlap of N-diffusion contact < %d (LIcon 5a)"
+ surround pdc/a *pdiff,pfet,scpfet,pfethvt,pfetlvt 40 absence_illegal \
+ "P-diffusion overlap of P-diffusion contact < %d (LIcon 5a)"
+ surround ndic/a *ndi 40 absence_illegal \
+ "N-diode overlap of N-diode contact < %d (LIcon 5a)"
+ surround pdic/a *pdi 40 absence_illegal \
+ "P-diode overlap of N-diode contact < %d (LIcon 5a)"
+
+ surround ndc/a *ndiff,nfet,scnfet,nfetlvt 60 directional \
+ "N-diffusion overlap of N-diffusion contact < %d in one direction (LIcon 5c)"
+ surround pdc/a *pdiff,pfet,scpfet,pfethvt,pfetlvt 60 directional \
+ "P-diffusion overlap of P-diffusion contact < %d in one direction (LIcon 5c)"
+ surround ndic/a *ndi 60 directional \
+ "N-diode overlap of N-diode contact < %d in one direction (LIcon 5c)"
+ surround pdic/a *pdi 60 directional \
+ "P-diode overlap of N-diode contact < %d in one direction (LIcon 5c)"
+
+ surround nsc/a *nsd 120 directional \
+ "N-tap overlap of N-tap contact < %d in one direction (LIcon 7)"
+ surround psc/a *psd 120 directional \
+ "P-tap overlap of P-tap contact < %d in one direction (LIcon 7)"
+
+ surround mvndc/a *mvndiff,mvnfet 40 absence_illegal \
+ "N-diffusion overlap of N-diffusion contact < %d (LIcon 5a)"
+ surround mvpdc/a *mvpdiff,mvpfet 40 absence_illegal \
+ "P-diffusion overlap of P-diffusion contact < %d (LIcon 5a)"
+ surround mvndic/a *mvndi 40 absence_illegal \
+ "N-diode overlap of N-diode contact < %d (LIcon 5a)"
+ surround mvpdic/a *mvpdi 40 absence_illegal \
+ "P-diode overlap of N-diode contact < %d (LIcon 5a)"
+
+ surround mvndc/a *mvndiff,mvnfet 60 directional \
+ "N-diffusion overlap of N-diffusion contact < %d in one direction (LIcon 5c)"
+ surround mvpdc/a *mvpdiff,mvpfet 60 directional \
+ "P-diffusion overlap of P-diffusion contact < %d in one direction (LIcon 5c)"
+ surround mvndic/a *mvndi 60 directional \
+ "N-diode overlap of N-diode contact < %d in one direction (LIcon 5c)"
+ surround mvpdic/a *mvpdi 60 directional \
+ "P-diode overlap of N-diode contact < %d in one direction (LIcon 5c)"
+
+ surround mvnsc/a *mvnsd 120 directional \
+ "N-tap overlap of N-tap contact < %d in one direction (LIcon 7)"
+ surround mvpsc/a *mvpsd 120 directional \
+ "P-tap overlap of P-tap contact < %d in one direction (LIcon 7)"
+
+ surround pc/a *poly,mrp1,xhrpoly,uhrpoly 50 absence_illegal \
+ "Poly overlap of poly contact < %d (LIcon 8)"
+ surround pc/a *poly,mrp1,xhrpoly,uhrpoly 80 directional \
+ "Poly overlap of poly contact < %d in one direction (LIcon 8a)"
+
+ exact_overlap ndc/a,pdc/a,psc/a,nsc/a,pc/a,ndic/a,pdic/a
+ exact_overlap mvndc/a,mvpdc/a,mvpsc/a,mvnsc/a,mvndic/a,mvpdic/a
+
+#-------------------------------------------------------------
+# LI - Local interconnect layer
+#-------------------------------------------------------------
+
+ width *li,rli 170 "Local interconnect width < %d (LI 1)"
+ width coreli 140 "Core local interconnect width < %d (LI c1)"
+ spacing allli allli,*obsli 170 touching_ok "Local interconnect spacing < %d (LI 3)"
+ spacing coreli allli,*obsli 140 touching_ok "Core local interconnect spacing < %d (LI c2)"
+
+ surround pc/li *li 80 directional \
+ "Local interconnect overlap of poly contact < %d in one direction (LI 5)"
+
+ surround ndc/li,nsc/li,pdc/li,psc/li,ndic/li,pdic/li,mvndc/li,mvnsc/li,mvpdc/li,mvpsc/li,mvndic/li,mvpdic/li \
+ *li,rli 80 directional \
+ "Local interconnect overlap of diffusion contact < %d in one direction (LI 5)"
+
+ area allli,*obsli 56100 170 "Local interconnect minimum area < %a (LI 6)"
+
+#-------------------------------------------------------------
+# MCON - Contact between local interconnect and metal1
+#-------------------------------------------------------------
+
+ width lic/m1 170 "Mcon width < %d (Mcon 1)"
+ spacing lic/m1 lic/m1,obslic/m1 170 touching_ok "Mcon spacing < %d (Mcon 2)"
+
+ exact_overlap lic/m1
+
+#-------------------------------------------------------------
+# METAL1 -
+#-------------------------------------------------------------
+
+ width *m1,rm1 140 "Metal1 width < %d (Met1 1)"
+ spacing allm1 allm1,*obsm1 140 touching_ok "Metal1 spacing < %d (Met1 2)"
+ area allm1,*obsm1 83000 140 "Metal1 minimum area < %a (Met1 6)"
+
+ surround lic/m1 *met1 30 absence_illegal \
+ "Metal1 overlap of local interconnect contact < %d (Met1 4)"
+ surround lic/m1 *met1 60 directional \
+ "Metal1 overlap of local interconnect contact < %d in one direction (Met1 5)"
+
+variants (fast),(full)
+ widespacing allm1 3000 allm1,*obsm1 280 touching_ok \
+ "Metal1 > 3um spacing to unrelated m1 < %d (Met1 3a)"
+ widespacing *obsm1 3000 allm1 280 touching_ok \
+ "Metal1 > 3um spacing to unrelated m1 < %d (Met1 3a)"
+
+variants (full)
+ cifmaxwidth m1_hole_empty 0 bend_illegal \
+ "Min area of metal1 holes > 0.14um^2 (Met1 7)"
+variants *
+
+#--------------------------------------------------
+# VIA1
+#--------------------------------------------------
+
+ width v1/m1 260 "Via1 width < %d (Via 1a + 2 * Via 4a)"
+ spacing v1 v1 60 touching_ok "Via1 spacing < %d (Via 2 - 2 * Via 4a)"
+ surround v1/m1 *m1 30 directional \
+ "Metal1 overlap of Via1 < %d in one direction (Via 5a - Via 4a)"
+ surround v1/m2 *m2 30 directional \
+ "Metal2 overlap of Via1 < %d in one direction (Met2 5 - Met2 4)"
+
+ exact_overlap v1/m2
+
+#--------------------------------------------------
+# METAL2 -
+#--------------------------------------------------
+
+ width allm2 140 "Metal2 width < %d (Met2 1)"
+ spacing allm2 allm2,obsm2 140 touching_ok "Metal2 spacing < %d (Met2 2)"
+ area allm2,obsm2 67600 140 "Metal2 minimum area < %a (Met2 6)"
+
+variants (fast),(full)
+ widespacing allm2 3000 allm2,obsm2 280 touching_ok \
+ "Metal2 > 3um spacing to unrelated m2 < %d (Met2 3)"
+ widespacing obsm2 3000 allm2 280 touching_ok \
+ "Metal2 > 3um spacing to unrelated m2 < %d (Met2 3)"
+
+variants (full)
+ cifmaxwidth m2_hole_empty 0 bend_illegal \
+ "Min area of metal2 holes > 0.14um^2 (Met2 7)"
+variants *
+
+#--------------------------------------------------
+# VIA2
+#--------------------------------------------------
+
+ width v2/m2 280 "Via2 width < %d (Via2 1a + 2 * Via2 4)"
+
+ spacing v2 v2 120 touching_ok "Via2 spacing < 0.24um (Via2 2 - 2 * Via2 4)"
+
+ surround v2/m2 *m2 45 directional \
+ "Metal2 overlap of Via2 < %d in one direction (Via2 4a - Via2 4)"
+ surround v2/m3 *m3 25 absence_illegal "Metal3 overlap of Via2 < %d (Met3 4)"
+
+ exact_overlap v2/m2
+
+#--------------------------------------------------
+# METAL3 -
+#--------------------------------------------------
+
+ width allm3 300 "Metal3 width < %d (Met3 1)"
+ spacing allm3 allm3,obsm3 300 touching_ok "Metal3 spacing < %d (Met3 2)"
+ area allm3,obsm3 240000 300 "Metal3 minimum area < %a (Met3 6)"
+
+variants (fast),(full)
+ widespacing allm3 3000 allm3,obsm3 400 touching_ok \
+ "Metal3 > 3um spacing to unrelated m3 < %d (Met3 3d)"
+ widespacing obsm3 3000 allm3 400 touching_ok \
+ "Metal3 > 3um spacing to unrelated m3 < %d (Met3 3d)"
+variants *
+
+
+#ifdef METAL5
+#--------------------------------------------------
+# VIA3 - Requires METAL5 Module
+#--------------------------------------------------
+
+ width v3/m3 320 "Via3 width < %d (Via3 1 + 2 * Via3 4)"
+ spacing v3 v3 80 touching_ok "Via3 spacing < %d (Via3 2 - 2 * Via3 4)"
+ surround v3/m3 *m3 30 directional \
+ "Metal3 overlap of Via3 in one direction < %d (Via3 5 - Via3 4)"
+ surround v3/m4 *m4 5 directional \
+ "Metal4 overlap of Via3 in one direction < %d (Met4 3 - Via3 4)"
+
+ exact_overlap v3/m3
+
+#-----------------------------
+# METAL4 - METAL4 Module
+#-----------------------------
+
+variants *
+
+ width allm4 300 "Metal4 width < %d (Met4 1)"
+ spacing allm4 allm4,obsm4 300 touching_ok "Metal4 spacing < %d (Met4 2)"
+ area allm4,obsm4 240000 300 "Metal4 minimum area < %a (Met4 4a)"
+
+variants (fast),(full)
+ widespacing allm4 3000 allm4,obsm4 400 touching_ok \
+ "Metal4 > 3um spacing to unrelated m4 < %d (S2M4)"
+ widespacing obsm4 3000 allm4 400 touching_ok \
+ "Metal4 > 3um spacing to unrelated m4 < %d (S2M4)"
+variants *
+
+#--------------------------------------------------
+# VIA4 - Requires METAL5 Module
+#--------------------------------------------------
+
+ width v4/m4 1180 "Via4 width < %d (Via4 1 + 2 * Via4 4)"
+ spacing v4 v4 420 touching_ok "Via4 spacing < %d (Via4 2 - 2 * Via4 4)"
+ surround v4/m5 *m5 120 absence_illegal \
+ "Metal5 overlap of Via4 < %d (Met5 3 - Via4 4)"
+
+ exact_overlap v4/m4
+
+#-----------------------------
+# METAL5 - METAL5 Module
+#-----------------------------
+
+ width allm5 1600 "Metal5 width < %d (Met5 1)"
+ spacing allm5 allm5,obsm5 1600 touching_ok "Metal5 spacing < %d (Met5 2)"
+ area allm5,obsm5 4000000 1600 "Metal5 minimum area < %a (Met5 4)"
+
+#endif (METAL5)
+
+#ifdef REDISTRIBUTION
+
+variants (full)
+
+ width metrdl 10000 "RDL width < %d (Rdl 1)"
+ spacing metrdl metrdl 10000 touching_ok "RDL spacing < %d (Rdl 2)"
+ surround glass metrdl 10750 absence_ok "RDL must surround glass cut by %d (Rdl 3)"
+ spacing metrdl padl 19660 surround_ok "RDL spacing to unrelated pad < %d (Rdl 6)"
+
+variants *
+
+#endif (REDISTRIBUTION)
+
+#--------------------------------------------------
+# NMOS, PMOS
+#--------------------------------------------------
+
+ extend allfets *poly 420 "Transistor width < %d (Diff/tap 2)"
+ # Except: Note that standard cells allow transistor width minimum 0.36um
+ width pfetlvt 350 "LVT PMOS gate length < %d (Poly 1b)"
+
+ spacing *nsd,*mvnsd allpolynonfet 55 touching_illegal \
+ "N-tap spacing to field poly < %d (Poly 5)"
+ spacing *psd,*mvpsd allpolynonfet 55 touching_illegal \
+ "P-tap spacing to field poly < %d (Poly 5)"
+
+ # Full edge rule required to describe FET to butted tap distance
+ edge4way *psd *ndiff 300 *ndiff *psd 300 \
+ "Butting P-tap spacing to NMOS gate < %d (Poly 6)"
+ edge4way *nsd *pdiff 300 *pdiff *nsd 300 \
+ "Butting N-tap spacing to PMOS gate < %d (Poly 6)"
+ edge4way *mvpsd *mvndiff 300 *mvndiff *mvpsd 300 \
+ "Butting MV P-tap spacing to MV NMOS gate < %d (Poly 6)"
+ edge4way *mvnsd *mvpdiff 300 *mvpdiff *mvnsd 300 \
+ "Butting MV N-tap spacing to MV PMOS gate < %d (Poly 6)"
+
+ # No LV FETs in HV diff
+ spacing pfet,scpfet,pfetlvt,pfethvt,*pdiff *mvpdiff 360 touching_illegal \
+ "LV P-diffusion to MV P-diffusion < %d (Diff/tap 23 + Diff/tap 22)"
+
+ spacing nfet,scnfet,nfetlvt,varactor,varhvt,*ndiff *mvndiff 360 touching_illegal \
+ "LV N-diffusion to MV N-diffusion < %d (Diff/tap 23 + Diff/tap 22)"
+
+ # No HV FETs in LV diff
+ spacing mvpfet,*mvpdiff *pdiff 360 touching_illegal \
+ "MV P-diffusion to LV P-diffusion < %d (Diff/tap 23 + Diff/tap 22)"
+
+ spacing mvnfet,mvvaractor,*mvndiff *ndiff 360 touching_illegal \
+ "MV N-diffusion to LV N-diffusion < %d (Diff/tap 23 + Diff/tap 22)"
+
+ # Minimum length of MV FETs. Note that this is larger than the minimum
+ # width (0.29um), so an edge rule is required
+
+ edge4way mvndiff mvnfet 500 mvnfet 0 0 \
+ "MV NMOS minimum length < %d (Poly 13)"
+
+ edge4way mvnsd mvvaractor 500 mvvaractor 0 0 \
+ "MV Varactor minimum length < %d (Poly 13)"
+
+ edge4way mvpdiff mvpfet 500 mvpfet 0 0 \
+ "MV PMOS minimum length < %d (Poly 13)"
+
+#--------------------------------------------------
+# mrp1 (N+ poly resistor)
+#--------------------------------------------------
+
+ width mrp1 330 "mrp1 resistor width < %d (Poly 3)"
+
+#--------------------------------------------------
+# xhrpoly (P+ poly resistor)
+#--------------------------------------------------
+
+ width xhrpoly 350 "xhrpoly resistor width < %d (P+ Poly 1a)"
+ # NOTE: xhrpoly resistor requires choice of discrete widths 0.35, 0.69, ... up to 1.27.
+
+#--------------------------------------------------
+# uhrpoly (P+ poly resistor, 2kOhm/sq)
+#--------------------------------------------------
+
+ width uhrpoly 350 "uhrpoly resistor width < %d"
+ spacing xhrpoly,uhrpoly,xpc alldiff 480 touching_illegal \
+ "xhrpoly/uhrpoly resistor spacing to diffusion < %d (Poly 9)"
+
+#------------------------------------
+# MOS Varactor device rules
+#------------------------------------
+
+ overhang *nsd var,varhvt 250 \
+ "N-Tap overhang of Varactor < %d (Var 4)"
+
+ overhang *mvnsd mvvar 250 \
+ "N-Tap overhang of Varactor < %d (Var 4)"
+
+ width var,varhvt,mvvar 180 "Varactor length < %d (Var 1)"
+ extend var,varhvt,mvvar *poly 1000 "Varactor width < %d (Var 2)"
+
+#ifdef MIM
+#-----------------------------------------------------------
+# MiM CAP (CAPM) -
+#-----------------------------------------------------------
+
+ width *mimcap 2000 "MiM cap width < %d (Capm 1)"
+ spacing *mimcap *mimcap 840 touching_ok "MiM cap spacing < %d (Capm 2a)"
+ spacing *mimcap via2/m3 1270 touching_illegal \
+ "MiM cap spacing to via2 < %d (Capm 5)"
+ surround *mimcc *mimcap 200 absence_illegal \
+ "MiM cap must surround MiM cap contact by %d (Capm 4)"
+ rect_only *mimcap "MiM cap must be rectangular (Capm 7)
+
+ surround *mimcap *metal3/m3 140 absence_illegal \
+ "Metal3 must surround MiM cap by %d (Capm 3)"
+ spacing via2 *mimcap 50 touching_illegal "MiM cap cannot overlap via2 (Capm 8)"
+ spacing via3 *mimcap 50 touching_illegal "MiM cap cannot overlap via3 (Capm 8)"
+ # (resolve scaling issue!)
+ # cifspacing mim_bottom mim_bottom 1200 touching_ok \
+ # "MiM cap bottom plate spacing < %d (Capm 2b)"
+
+ # MiM cap contact rules (VIA3)
+
+ width mimcc/m3 320 "MiM cap contact width < %d (Via3 1 + 2 * Via3 4)"
+ spacing mimcc mimcc 80 touching_ok "MiM cap contact spacing < %d (Via3 2 - 2 * Via3 4)"
+ surround mimcc/m4 *m4 5 directional \
+ "Metal4 overlap of MiM cap contact in one direction < %d (Met4 3 - Via3 4)"
+ exact_overlap mimcc/m3
+
+ width *mimcap2 2000 "MiM cap width < %d (Cap2m 1)"
+ spacing *mimcap2 *mimcap2 840 touching_ok "MiM cap spacing < %d (Cap2m 2a)"
+ spacing *mimcap2 via3/m4 1270 touching_illegal \
+ "MiM cap spacing to via3 < %d (Cap2m 5)"
+ surround *mim2cc *mimcap2 200 absence_illegal \
+ "MiM cap must surround MiM cap contact by %d (Cap2m 4)"
+ rect_only *mimcap2 "MiM cap must be rectangular (Cap2m 7)
+
+ surround *mimcap2 *metal4/m4 140 absence_illegal \
+ "Metal4 must surround MiM cap by %d (Cap2m 3)"
+ spacing via3 *mimcap2 50 touching_illegal "MiM cap cannot overlap via3 (Cap2m 8)"
+ spacing via4 *mimcap2 50 touching_illegal "MiM cap cannot overlap via4 (Cap2m 8)"
+ # (resolve scaling issue!)
+ # cifspacing mim2_bottom mim2_bottom 1200 touching_ok \
+ # "MiM2 cap bottom plate spacing < %d (Cap2m 2b)"
+
+ # MiM cap contact rules (VIA4)
+
+ width mim2cc/m4 1180 "MiM2 cap contact width < %d (Via4 1 + 2 * Via4 4)"
+ spacing mim2cc mim2cc 420 touching_ok \
+ "MiM2 cap contact spacing < %d (Via4 2 - 2 * Via4 4)"
+ surround mim2cc/m5 *m5 120 absence_illegal \
+ "Metal5 overlap of MiM2 cap contact < %d (Met5 3 - Via4 4)"
+ exact_overlap mim2cc/m4
+
+#endif (MIM)
+
+#----------------------------
+# End DRC style
+#----------------------------
+
+end
+
+#----------------------------
+# LEF format definitions
+#----------------------------
+
+lef
+
+ routing li li1 LI1 LI li
+
+ routing m1 met1 MET1 m1
+ routing m2 met2 MET2 m2
+ routing m3 met3 MET3 m3
+#ifdef METAL5
+ routing m4 met4 MET4 m4
+ routing m5 met5 MET5 m5
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ routing mrdl met6 MET6 m6 MRDL METRDL
+#endif
+
+ cut lic mcon MCON Mcon
+ cut m2c via via1 VIA VIA1 cont2 via12
+ cut m3c via2 VIA2 cont3 via23
+#ifdef METAL5
+ cut via3 via3 VIA3 cont4 via34
+ cut via4 via4 VIA4 cont5 via45
+#endif (METAL5)
+
+ obs obsli li1
+ obs obsm1 met1
+ obs obsm2 met2
+ obs obsm3 met3
+
+#ifdef METAL5
+ obs obsm4 met4
+ obs obsm5 met5
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ obs obsmrdl met6
+#endif
+
+ obs obslic mcon
+
+end
+
+#-----------------------------------------------------
+# Device and Parasitic extraction
+#-----------------------------------------------------
+
+
+extract
+ style ngspice variants (lvs),(sim),(si)
+ cscale 1
+ # NOTE: SkyWater SPICE libraries use .option scale 1E6 so all
+ # dimensions must be in units of microns in the extract file.
+ # Use extract style "ngspice(si)" to override this and produce
+ # a file with SI units for length/area.
+
+ variants (lvs),(sim)
+ lambda 1E6
+ variants (si)
+ lambda 1.0
+ variants *
+
+ units microns
+ step 7
+ sidehalo 2
+
+ # NOTE: MiM cap layers have been purposely put out of order,
+ # may want to reconsider.
+
+ planeorder dwell 0
+ planeorder well 1
+ planeorder active 2
+ planeorder locali 3
+ planeorder metal1 4
+ planeorder metal2 5
+ planeorder metal3 6
+#ifdef METAL5
+ planeorder metal4 7
+ planeorder metal5 8
+#ifdef REDISTRIBUTION
+ planeorder metali 9
+ planeorder block 10
+ planeorder comment 11
+ planeorder cap1 12
+ planeorder cap2 13
+#else (!REDISTRIBUTION)
+ planeorder block 9
+ planeorder comment 10
+ planeorder cap1 11
+ planeorder cap2 12
+#endif (!REDISTRIBUTION)
+#else (!METAL5)
+#ifdef REDISTRIBUTION
+ planeorder metali 7
+ planeorder block 8
+ planeorder comment 9
+ planeorder cap1 10
+ planeorder cap2 11
+#else (!REDISTRIBUTION)
+ planeorder block 7
+ planeorder comment 8
+ planeorder cap1 9
+ planeorder cap2 10
+#endif (!REDISTRIBUTION)
+#endif (!METAL5)
+
+ height dnwell -0.1 0.1
+ height nwell,pwell 0.0 0.2062
+ height alldiff 0.2062 0.12
+ height allpoly 0.3262 0.18
+ height alldiffcont 0.3262 0.61
+ height pc 0.5062 0.43
+ height allli 0.9361 0.10
+ height lic 1.0361 0.34
+ height allm1 1.3761 0.36
+ height v1 1.7361 0.27
+ height allm2 2.0061 0.36
+ height v2 2.3661 0.42
+ height allm3 2.7861 0.845
+#ifdef METAL5
+ height v3 3.6311 0.39
+ height allm4 4.0211 0.845
+ height v4 4.8661 0.505
+ height allm5 5.3711 1.26
+ height mimcap 2.4661 0.2
+ height mimcap2 3.7311 0.2
+ height mimcc 2.6661 0.12
+ height mim2cc 3.9311 0.09
+#ifdef REDISTRIBUTION
+ height mrdlc 6.6311 5.2523
+ height mrdl 11.8834 4.0
+#endif (!REDISTRIBUTION)
+#endif (!METAL5)
+
+ # Antenna check parameters
+ # Note that checks w/diode diffusion are not modeled
+ model partial
+ antenna poly sidewall 50 none
+ antenna allcont surface 3 none
+ antenna li sidewall 75 0 450
+ antenna lic surface 3 0 18
+ antenna m1,m2,m3 sidewall 400 2600 400
+ antenna v1 surface 3 0 18
+ antenna v2 surface 6 0 36
+#ifdef METAL5
+ antenna m4,m5 sidewall 400 2600 400
+ antenna v3,v4 surface 6 0 36
+#endif (METAL5)
+
+ tiedown alldiffnonfet
+
+ substrate *ppdiff,*mvppdiff,space/w,pwell well $SUB -dnwell
+
+# Layer resistance: Use document xp018-PDS-v4_2_1.pdf
+
+# Resistances are in milliohms per square
+# Optional 3rd argument is the corner adjustment fraction
+# Device values come from trtc.cor (typical corner)
+ resist (dnwell)/dwell 2200000
+ resist (pwell)/well 3050000
+ resist (nwell)/well 1700000
+ resist (rpw)/well 3050000 0.5
+ resist (*ndiff,nsd)/active 120000
+ resist (*pdiff,*psd)/active 197000
+ resist (*mvndiff,mvnsd)/active 114000
+ resist (*mvpdiff,*mvpsd)/active 191000
+
+ resist ndiffres/active 120000 0.5
+ resist pdiffres/active 197000 0.5
+ resist mvndiffres/active 114000 0.5
+ resist mvpdiffres/active 191000 0.5
+ resist mrp1/active 48200 0.5
+ resist xhrpoly/active 319800 0.5
+ resist uhrpoly/active 2000000 0.5
+
+ resist (allpolynonres)/active 48200
+ resist rmp/active 48200
+
+ resist (allli)/locali 12200
+ resist (allm1)/metal1 125
+ resist (allm2)/metal2 125
+ resist (allm3)/metal3 47
+#ifdef METAL5
+ resist (allm4)/metal4 47
+ resist (allm5)/metal5 29
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ resist mrdl/metali 5
+#endif (REDISTRIBUTION)
+
+ contact ndc,nsc 15000
+ contact pdc,psc 15000
+ contact mvndc,mvnsc 15000
+ contact mvpdc,mvpsc 15000
+ contact pc 15000
+ contact lic 152000
+ contact m2c 4500
+ contact m3c 3410
+#ifdef METAL5
+#ifdef MIM
+ contact mimcc 4500
+ contact mim2cc 3410
+#endif (MIM)
+ contact via3 3410
+ contact via4 380
+#endif (METAL5)
+#ifdef REDISTRIBUTION
+ contact mrdlc 6
+#endif (REDISTRIBUTION)
+
+#-------------------------------------------------------------------------
+# Parasitic capacitance values: Use document (...)
+#-------------------------------------------------------------------------
+# This uses the new "default" definitions that determine the intervening
+# planes from the planeorder stack, take care of the reflexive sideoverlap
+# definitions, and generally clean up the section and make it more readable.
+#
+# Also uses "units microns" statement, so all parasitic capacitance values
+# are taken directly from the source document PDS_035_03, in units of
+# aF/um^2 for area caps and aF/um for perimeter and sidewall caps.
+#-------------------------------------------------------------------------
+# Remember that device capacitances to substrate are taken care of by the
+# models. Thus, active and poly definitions ignore all "fet" types.
+# fet types are excluded when computing parasitic capacitance to
+# active from layers above them because poly is a shield; fet types are
+# included for parasitics from layers above to poly. Resistor types
+# should be removed from all parasitic capacitance calculations, or else
+# they just create floating caps. Technically, the capacitance probably
+# should be split between the two terminals. Unsure of the correct model.
+#-------------------------------------------------------------------------
+
+#n-well
+# NOTE: This value not found in PEX files
+defaultareacap nwell well 120
+
+#n-active
+# Rely on device models to capture *ndiff area cap
+# Do not extract parasitics from resistors
+# defaultareacap allnactivenonfet active 790
+# defaultperimeter allnactivenonfet active 280
+
+#p-active
+# Rely on device models to capture *pdiff area cap
+# Do not extract parasitics from resistors
+# defaultareacap allpactivenonfet active 810
+# defaultperimeter allpactivenonfet active 300
+
+#poly
+# Do not extract parasitics from resistors
+# defaultsidewall allpolynonfet active 22
+# defaultareacap allpolynonfet active 105
+# defaultperimeter allpolynonfet active 57
+
+ defaultsidewall *poly active 63
+ defaultareacap *poly active nwell,obswell,pwell well 63
+ defaultperimeter *poly active nwell,obswell,pwell well 16
+
+#locali
+ defaultsidewall allm1 metal1 113
+ defaultareacap allm1 metal1 nwell,obswell,pwell well 37
+ defaultperimeter allm1 metal1 nwell,obswell,pwell well 8
+ defaultoverlap allm1 metal1 nwell well 37
+
+#locali->diff
+ defaultoverlap allm1 metal1 allactivenonfet active 36
+ defaultsideoverlap allm1 metal1 allactivenonfet active 9
+
+#locali->poly
+ defaultoverlap allm1 metal1 allpolynonres active 46
+ defaultsideoverlap allm1 metal1 allpolynonres active 10
+
+#metal1
+ defaultsidewall allm1 metal1 113
+ defaultareacap allm1 metal1 nwell,obswell,pwell well 17
+ defaultperimeter allm1 metal1 nwell,obswell,pwell well 8
+ defaultoverlap allm1 metal1 nwell well 26
+
+#metal1->locali
+ defaultoverlap allm1 metal1 allactivenonfet active 36
+ defaultsideoverlap allm1 metal1 allactivenonfet active 9
+
+#metal1->diff
+ defaultoverlap allm1 metal1 allactivenonfet active 36
+ defaultsideoverlap allm1 metal1 allactivenonfet active 9
+
+#metal1->poly
+ defaultoverlap allm1 metal1 allpolynonres active 46
+ defaultsideoverlap allm1 metal1 allpolynonres active 10
+
+#metal2
+ defaultsidewall allm2 metal2 101
+ defaultareacap allm2 metal2 nwell,obswell,pwell well 12
+ defaultperimeter allm2 metal2 nwell,obswell,pwell well 6
+ defaultoverlap allm2 metal2 nwell well 13
+
+#metal2->diff
+ defaultoverlap allm2 metal2 allactivenonfet active 14
+ defaultsideoverlap allm2 metal2 allactivenonfet active 7
+
+#metal2->poly
+ defaultoverlap allm2 metal2 allpolynonres active 16
+ defaultsideoverlap allm2 metal2 allpolynonres active 7
+
+#metal2->metal1
+ defaultoverlap allm2 metal2 allm1 metal1 39
+ defaultsideoverlap allm2 metal2 allm1 metal1 10
+
+#metal3
+ defaultsidewall allm3 metal3 102
+ defaultoverlap allm3 metal3 nwell well 8
+ defaultareacap allm3 metal3 nwell,obswell,pwell well 8
+ defaultperimeter allm3 metal3 nwell,obswell,pwell well 5
+
+#metal3->diff
+ defaultoverlap allm3 metal3 allactive active 9
+ defaultsideoverlap allm3 metal3 allactive active 6
+
+#metal3->poly
+ defaultoverlap allm3 metal3 allpolynonres active 10
+ defaultsideoverlap allm3 metal3 allpolynonres active 6
+
+#metal3->metal1
+ defaultoverlap allm3 metal3 allm1 metal1 15
+ defaultsideoverlap allm3 metal3 allm1 metal1 7
+
+#metal3->metal2
+ defaultoverlap allm3 metal3 allm2 metal2 39
+ defaultsideoverlap allm3 metal3 allm2 metal2 10
+
+#ifdef METAL5
+#metal4
+ defaultsidewall allm4 metal4 102
+# defaultareacap alltopm metal4 well 6
+ areacap allm4/m4 8
+ defaultoverlap allm4 metal4 nwell well 8
+ defaultperimeter allm4 metal4 well 5
+
+#metal4->diff
+ defaultoverlap allm4 metal4 allactivenonfet active 7
+ defaultsideoverlap allm4 metal4 allactivenonfet active 7
+
+#metal4->poly
+ defaultoverlap allm4 metal4 allpolynonres active 7
+ defaultsideoverlap allm4 metal4 allpolynonres active 5
+
+#metal4->metal1
+ defaultoverlap allm4 metal4 allm1 metal1 9
+ defaultsideoverlap allm4 metal4 allm1 metal1 6
+
+#metal4->metal2
+ defaultoverlap allm4 metal4 allm2 metal2 15
+ defaultsideoverlap allm4 metal4 allm2 metal2 7
+
+#metal4->metal3
+ defaultoverlap allm4 metal4 allm3 metal3 39
+ defaultsideoverlap allm4 metal4 allm3 metal3 10
+
+#metal5
+ defaultsidewall allm5 metal5 103
+# defaultareacap allm5 metal5 well 6
+ areacap allm5/m5 6
+ defaultoverlap allm5 metal5 nwell well 6
+ defaultperimeter allm5 metal5 well 5
+
+#metal5->diff
+ defaultoverlap allm5 metal5 allactivenonfet active 5
+ defaultsideoverlap allm5 metal5 allactivenonfet active 5
+
+#metal5->poly
+ defaultoverlap allm5 metal5 allpolynonres active 5
+ defaultsideoverlap allm5 metal5 allpolynonres active 5
+
+#metal5->metal1
+ defaultoverlap allm5 metal5 allm1 metal1 7
+ defaultsideoverlap allm5 metal5 allm1 metal1 5
+
+#metal5->metal2
+ defaultoverlap allm5 metal5 allm2 metal2 9
+ defaultsideoverlap allm5 metal5 allm2 metal2 6
+
+#metal5->metal3
+ defaultoverlap allm5 metal5 allm3 metal3 15
+ defaultsideoverlap allm5 metal5 allm3 metal3 7
+
+#metal5->metal4
+ defaultoverlap allm5 metal5 allm4 metal4 39
+ defaultsideoverlap allm5 metal5 allm4 metal4 10
+#endif (METAL5)
+
+# Devices: Use document (...)
+
+variants (sim)
+
+ device msubcircuit pshort pfet,scpfet *pdiff,pdiffres *pdiff,pdiffres nwell error l=l w=w
+ device msubcircuit plowvt pfetlvt *pdiff,pdiffres *pdiff,pdiffres nwell error l=l w=w
+ device msubcircuit phighvt pfethvt *pdiff,pdiffres *pdiff,pdiffres nwell error l=l w=w
+
+ device msubcircuit nshort nfet,scnfet *ndiff,ndiffres *ndiff,ndiffres pwell,space/w error l=l w=w
+ device msubcircuit nlowvt nfetlvt *ndiff,ndiffres *ndiff,ndiffres pwell,space/w error l=l w=w
+ device msubcircuit sonos_e nsonos *ndiff,ndiffres *ndiff,ndiffres pwell,space/w error l=l w=w
+ device subcircuit xcnwvc varactor *nndiff nwell error l=l w=w
+ device subcircuit xcnwvc2 varhvt *nndiff nwell error l=l w=w
+ device subcircuit xchvnwc mvvaractor *mvnndiff nwell error l=l w=w
+
+ device msubcircuit phv mvpfet *mvpdiff,mvpdiffres *mvpdiff,mvpdiffres nwell error l=l w=w
+ device msubcircuit nhv mvnfet *mvndiff,mvndiffres *mvndiff,mvndiffres pwell,space/w error l=l w=w
+ device msubcircuit nhvnative mvnnfet *mvndiff,mvndiffres *mvndiff,mvndiffres pwell,space/w error l=l w=w
+
+ device rsubcircuit short rmp *poly space/w,pwell,nwell error l=l w=w
+ device rsubcircuit short rli1 *li,coreli space/w,pwell,nwell error l=l w=w
+ device rsubcircuit short rmetal1 *metal1 space/w,pwell,nwell error l=l w=w
+ device rsubcircuit short rmetal2 *metal2 space/w,pwell,nwell error l=l w=w
+ device rsubcircuit short rmetal3 *metal3 space/w,pwell,nwell error l=l w=w
+#ifdef METAL5
+ device rsubcircuit short rm4 *m4 space/w,pwell,nwell error l=l w=w
+ device rsubcircuit short rm5 *m5 space/w,pwell,nwell error l=l w=w
+#endif (METAL5)
+
+ device rsubcircuit xhrpoly xhrpoly xpc pwell,space/w error l=l w=w
+ device rsubcircuit uhrpoly uhrpoly xpc pwell,space/w error l=l w=w
+ device rsubcircuit mrp1 mrp1 *poly pwell,space/w error l=l w=w
+
+ device rsubcircuit mrdn ndiffres *ndiff pwell,space/w error l=l w=w
+ device rsubcircuit mrdp pdiffres *pdiff nwell error l=l w=w
+ device rsubcircuit xpwres rpw pwell dnwell error l=l w=w
+
+ device rsubcircuit mrdn_hv mvndiffres *mvndiff pwell,space/w error l=l w=w
+ device rsubcircuit mrdp_hv mvpdiffres *mvpdiff nwell error l=l w=w
+
+ device subcircuit pdiode *pdiode nwell a=a p=p
+ device msubcircuit ndiode *ndiode pwell,space/w a=a p=p
+ device subcircuit pdiode_h *mvpdiode nwell a=a p=p
+ device msubcircuit ndiode_h *mvndiode pwell,space/w a=a p=p
+
+ # These are parasitic devices
+ device msubcircuit ndiode_lvt *ndiodelvt pwell,space/w a=a p=p
+ device subcircuit pdiode_lvt *pdiodelvt nwell a=a p=p
+ device subcircuit pdiode_hvt *pdiodehvt nwell a=a p=p
+ device msubcircuit ndiode_native *nndiode pwell,space/w a=a p=p
+
+#ifdef MIM
+ device subcircuit xcmimc1 *mimcap m3 nwell,pwell,space/w error a=a p=p s=subs
+ device subcircuit xcmimc2 *mimcap2 m4,mimcc/m4 nwell,pwell,space/w error a=a p=p s=subs
+#endif (MIM)
+
+ variants (lvs),(si)
+
+ device mosfet pshort scpfet,pfet pdiff,pdiffres,pdc nwell
+ device mosfet plowvt pfetlvt pdiff,pdiffres,pdc nwell
+ device mosfet phighvt pfethvt pdiff,pdiffres,pdc nwell
+ device mosfet nshort scnfet,nfet ndiff,ndiffres,ndc pwell,space/w
+ device mosfet nlowvt nfetlvt ndiff,ndiffres,ndc pwell,space/w
+ device mosfet sonos_e nsonos ndiff,ndiffres,ndc pwell,space/w
+ device mosfet phv mvpfet mvpdiff,mvpdiffres,mvpdc nwell
+ device mosfet nhv mvnfet mvndiff,mvndiffres,mvndc pwell,space/w
+ device mosfet nhvnative mvnnfet *mvndiff,mvndiffres pwell,space/w
+
+ # These devices always extract as subcircuits
+ device subcircuit xcnwvc varactor *nndiff nwell error l=l w=w
+ device subcircuit xcnwvc2 varhvt *nndiff nwell error l=l w=w
+ device subcircuit xchvnwc mvvaractor *mvnndiff nwell error l=l w=w
+
+ device resistor short rmp *poly
+ device resistor short rli1 *li,coreli
+ device resistor short rmetal1 *metal1
+ device resistor short rmetal2 *metal2
+ device resistor short rmetal3 *metal3
+#ifdef METAL5
+ device resistor short rm4 *m4
+ device resistor short rm5 *m5
+#endif (METAL5)
+
+ device resistor xhrpoly xhrpoly xpc
+ device resistor uhrpoly uhrpoly xpc
+ device resistor mrp1 mrp1 *poly
+ device resistor mrdn ndiffres *ndiff
+ device resistor mrdp pdiffres *pdiff
+ device resistor mrdn_hv mvndiffres *mvndiff
+ device resistor mrdp_hv mvpdiffres *mvpdiff
+ device resistor xpwres rpw pwell
+
+ device pdiode pdiode *pdiode nwell a=a p=p
+ device ndiode ndiode *ndiode pwell,space/w a=a p=p
+ device pdiode pdiode_h *mvpdiode nwell a=a p=p
+ device ndiode ndiode_h *mvndiode pwell,space/w a=a p=p
+
+ # These are parasitic devices
+ device ndiode ndiode_lvt *ndiodelvt pwell,space/w a=a p=p
+ device pdiode pdiode_lvt *pdiodelvt nwell a=a p=p
+ device pdiode pdiode_hvt *pdiodehvt nwell a=a p=p
+ device ndiode ndiode_native *nndiode pwell,space/w a=a p=p
+
+ device subcircuit pdiode_h *mvpdiode nwell a=a p=p
+ device msubcircuit ndiode_h *mvndiode pwell,space/w a=a p=p
+
+
+#ifdef MIM
+ device capacitor xcmimc1 *mimcap *m3 1
+ device capacitor xcmimc2 *mimcap2 *m4 1
+#endif (MIM)
+
+end
+
+#-----------------------------------------------------
+# Wiring tool definitions
+#-----------------------------------------------------
+
+wiring
+ # All wiring values are in nanometers
+ scalefactor 10
+
+ contact lic 170 li 0 0 m1 30 60
+ contact v1 260 m1 0 30 m2 0 30
+ contact v2 280 m2 0 45 m3 25 0
+#ifdef METAL5
+ contact v3 320 m3 0 30 m4 0 5
+ contact v4 1180 m4 0 m5 120
+#endif (METAL5)
+
+ contact pc 170 poly 50 80 li 0 80
+ contact pdc 170 pdiff 40 60 li 0 80
+ contact ndc 170 ndiff 40 60 li 0 80
+ contact psc 170 psd 40 60 li 0 80
+ contact nsc 170 nsd 40 60 li 0 80
+
+end
+
+#-----------------------------------------------------
+# Plain old router. . .
+#-----------------------------------------------------
+
+router
+end
+
+#------------------------------------------------------------
+# Plowing (restored in magic 8.2, need to fill this section)
+#------------------------------------------------------------
+
+plowing
+end
+
+#-----------------------------------------------------------------
+# No special plot layers defined (use default PNM color choices)
+#-----------------------------------------------------------------
+
+plot
+ style pnm
+ default
+ draw fillblock no_color_at_all
+ draw nwell cwell
+end
+
diff --git a/sky130/sky130_fd_sc_hd_config.tcl b/sky130/sky130_fd_sc_hd_config.tcl
new file mode 100644
index 0000000..4d9393a
--- /dev/null
+++ b/sky130/sky130_fd_sc_hd_config.tcl
@@ -0,0 +1,41 @@
+set current_folder [file dirname [file normalize [info script]]]
+# Technology lib
+
+set ::env(LIB_SYNTH) "$::env(PDK_ROOT)/$::env(PDK)/libs.ref/lib/$::env(PDK_VARIANT)/sky130_fd_sc_hd_tt_1.80v_25C.lib"
+set ::env(LIB_MAX) "$::env(PDK_ROOT)/$::env(PDK)/libs.ref/lib/$::env(PDK_VARIANT)/sky130_fd_sc_hd_ff_1.95v_-40C.lib"
+set ::env(LIB_MIN) "$::env(PDK_ROOT)$::env(PDK)/libs.ref/lib/$::env(PDK_VARIANT)/sky130_fd_sc_hd_ss_1.60v_100C.lib"
+
+
+set ::env(LIB_TYPICAL) $::env(LIB_SYNTH)
+
+# welltap and endcap cells
+set ::env(FP_WELLTAP_CELL) "sky130_fd_sc_hd_tapvpwrvgnd_1"
+set ::env(FP_ENDCAP_CELL) "sky130_fd_sc_hd_decap_3"
+
+# defaults (can be overridden by designs):
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd_inv_8"
+#capacitance : 0.017653;
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+# update these
+set ::env(SYNTH_CAP_LOAD) "17.65" ; # femtofarad _inv_8 pin A cap
+set ::env(SYNTH_MIN_BUF_PORT) "sky130_fd_sc_hd_buf_2 A X"
+set ::env(SYNTH_TIEHI_PORT) "sky130_fd_sc_hd_conb_1 HI"
+set ::env(SYNTH_TIELO_PORT) "sky130_fd_sc_hd_conb_1 LO"
+
+# cts defaults
+set ::env(CTS_ROOT_BUFFER) sky130_fd_sc_hd_clkbuf_16
+set ::env(CELL_CLK_PORT) CLK
+
+# Placement defaults
+set ::env(PL_LIB) $::env(LIB_TYPICAL)
+
+# Fillcell insertion
+set ::env(FILL_CELL) "sky130_fd_sc_hd_decap_ sky130_fd_sc_hd_fill_"
+
+set ::env(CELL_PAD) 2
+set ::env(CELL_PAD_EXECLUDE) "$::env(PDK_VARIANT)_tap* $::env(PDK_VARIANT)_decap* $::env(PDK_VARIANT)_fill*"
+
+set ::env(ROOT_CLK_BUFFER) $::env(PDK_VARIANT)_clkbuf_16
+set ::env(CLK_BUFFER) $::env(PDK_VARIANT)_clkbuf_4
+set ::env(CLK_BUFFER_INPUT) A
+set ::env(CLK_BUFFER_OUTPUT) X
diff --git a/sky130/sky130_make_torture.tcl b/sky130/sky130_make_torture.tcl
new file mode 100644
index 0000000..580dc0f
--- /dev/null
+++ b/sky130/sky130_make_torture.tcl
@@ -0,0 +1,313 @@
+#---------------------------------------
+# Torture test generator for EFS8
+# (Specifically for EFS8B)
+# (work in progress)
+#---------------------------------------
+
+namespace path {::tcl::mathop ::tcl::mathfunc}
+
+# Set random seed so that torture test is not random from run to run.
+srand 1234567
+
+# NxN array MOSFET devices
+
+proc mos_array {n devname startx starty {deltax 12700} {deltay 254}} {
+ suspendall
+ box position $startx $starty
+ set i 0
+ for {set x 0} {$x < $n} {incr x} {
+ for {set y 0} {$y < $n} {incr y} {
+
+ set r [int [* [rand] 20]]
+ set w [+ 0.22 [* 0.5 $r]]
+ set r [int [* [rand] 20]]
+ set l [+ 0.18 [* 0.3 $r]]
+ set m [int [+ 1 [* [rand] 8]]]
+ set nf [int [+ 1 [* [rand] 8]]]
+
+ set r [int [* [rand] 8]]
+ set dcov [+ 20 [* 10 $r]]
+ set r [int [* [rand] 8]]
+ set pcov [+ 20 [* 10 $r]]
+ set r [int [* [rand] 8]]
+ set rlcov [+ 20 [* 10 $r]]
+
+ if {[rand] > 0.5} {set pov 1} else {set pov 0}
+ if {[rand] > 0.5} {set dov 1} else {set dov 0}
+ if {[rand] > 0.5} {set tc 1} else {set tc 0}
+ if {[rand] > 0.5} {set bc 1} else {set bc 0}
+ if {[rand] > 0.5} {set fm 1} else {set fm 0}
+ if {[rand] > 0.5} {set gl 1} else {set gl 0}
+ if {[rand] > 0.5} {set gr 1} else {set gr 0}
+ if {[rand] > 0.5} {set gt 1} else {set gt 0}
+ if {[rand] > 0.5} {set gb 1} else {set gb 0}
+
+ magic::gencell sky130::${devname} ${devname}_$i \
+ w $w l $l m $m nf $nf diffcov $dcov polycov $pcov \
+ rlcov $rlcov poverlap $pov doverlap $dov topc $tc \
+ botc $bc full_metal $fm glc $gl grc $gr gbc $gb gtc $gt
+ select cell ${devname}_$i
+ set bh [box height]
+ set bh [+ $bh $deltay]
+ box move n $bh
+ incr i
+ }
+ set bp [box position]
+ set bpx [lindex $bp 0]
+ box position $bpx $starty
+ box move e $deltax
+ }
+ resumeall
+}
+
+# NxN array resistor devices
+
+proc res_array {n devname startx starty {deltax 12700} {deltay 254}} {
+ suspendall
+ box position $startx $starty
+ set i 0
+ for {set x 0} {$x < $n} {incr x} {
+ for {set y 0} {$y < $n} {incr y} {
+
+ set r [int [* [rand] 10]]
+ set w [+ 0.42 [* 0.5 $r]]
+ set r [int [* [rand] 50]]
+ set l [+ 2.10 [* 2.0 $r]]
+ set m [int [+ 1 [* [rand] 2]]]
+ set nx [int [+ 1 [* [rand] 10]]]
+
+ set r [int [* [rand] 8]]
+ set ecov [+ 20 [* 10 $r]]
+
+ if {[rand] > 0.5} {set rov 1} else {set rov 0}
+ if {[rand] > 0.5} {set sn 1} else {set sn 0}
+ if {[rand] > 0.5} {set fm 1} else {set fm 0}
+ if {[rand] > 0.5} {set gl 1} else {set gl 0}
+ if {[rand] > 0.5} {set gr 1} else {set gr 0}
+ if {[rand] > 0.5} {set gt 1} else {set gt 0}
+ if {[rand] > 0.5} {set gb 1} else {set gb 0}
+
+ # Snake geometry does not apply to xhrpoly, uhrpoly, and xpwres, and
+ # roverlap and endcov are prohibited.
+ if {$devname == "xhrpoly" || $devname == "uhrpoly" || $devname == "xpwres"} {
+ magic::gencell sky130::${devname} ${devname}_$i \
+ w $w l $l m $m nx $nx full_metal $fm \
+ glc $gl grc $gr gbc $gb gtc $gt
+ } else {
+ magic::gencell sky130::${devname} ${devname}_$i \
+ w $w l $l m $m nx $nx endcov $ecov roverlap $rov \
+ snake $sn full_metal $fm glc $gl grc $gr gbc $gb gtc $gt
+ }
+ select cell ${devname}_$i
+ set bh [box height]
+ set bh [+ $bh $deltay]
+ box move n $bh
+ incr i
+ }
+ set bp [box position]
+ set bpx [lindex $bp 0]
+ box position $bpx $starty
+ box move e $deltax
+ }
+ resumeall
+}
+
+# NxN array diode devices
+
+proc diode_array {n devname startx starty} {
+ suspendall
+ box position $startx $starty
+ set i 0
+ for {set x 0} {$x < $n} {incr x} {
+ for {set y 0} {$y < $n} {incr y} {
+
+ set r [int [* [rand] 10]]
+ set w [+ 0.42 [* 0.5 $r]]
+ set r [int [* [rand] 10]]
+ set l [+ 0.42 [* 0.5 $r]]
+ set nx [int [+ 1 [* [rand] 4]]]
+ set ny [int [+ 1 [* [rand] 4]]]
+
+ if {[rand] > 0.5} {set dov 1} else {set dov 0}
+ if {[rand] > 0.5} {set el 1} else {set el 0}
+ if {[rand] > 0.5} {set er 1} else {set er 0}
+ if {[rand] > 0.5} {set et 1} else {set et 0}
+ if {[rand] > 0.5} {set eb 1} else {set eb 0}
+ if {[rand] > 0.5} {set fm 1} else {set fm 0}
+ if {[rand] > 0.5} {set gl 1} else {set gl 0}
+ if {[rand] > 0.5} {set gr 1} else {set gr 0}
+ if {[rand] > 0.5} {set gt 1} else {set gt 0}
+ if {[rand] > 0.5} {set gb 1} else {set gb 0}
+
+ magic::gencell sky130::${devname} ${devname}_$i \
+ w $w l $l nx $nx ny $ny doverlap $dov \
+ full_metal $fm elc $el erc $er etc $et \
+ ebc $eb glc $gl grc $gr gbc $gb gtc $gt
+ select cell ${devname}_$i
+ set bh [box height]
+ set bh [+ $bh 254]
+ box move n $bh
+ incr i
+ }
+ set bp [box position]
+ set bpx [lindex $bp 0]
+ box position $bpx $starty
+ box move e 12700
+ }
+ resumeall
+}
+
+# NxN array cap devices
+
+proc cap_array {n devname startx starty {deltax 12700} {deltay 160}} {
+ suspendall
+ box position $startx $starty
+ set i 0
+ for {set x 0} {$x < $n} {incr x} {
+ for {set y 0} {$y < $n} {incr y} {
+
+ set r [int [* [rand] 10]]
+ set w [+ 2.00 [* 1.0 $r]]
+ set r [int [* [rand] 10]]
+ set l [+ 2.00 [* 1.0 $r]]
+ set nx [int [+ 1 [* [rand] 4]]]
+ set ny [int [+ 1 [* [rand] 4]]]
+
+ if {[rand] > 0.5} {set bc 1} else {set bc 0}
+ if {[rand] > 0.5} {set tc 1} else {set tc 0}
+
+ magic::gencell sky130::${devname} ${devname}_$i \
+ w $w l $l nx $nx ny $ny bconnect $bc tconnect $tc
+ select cell ${devname}_$i
+ set bh [box height]
+ set bh [+ $bh $deltay]
+ box move n $bh
+ incr i
+ }
+ set bp [box position]
+ set bpx [lindex $bp 0]
+ box position $bpx $starty
+ box move e $deltax
+ }
+ resumeall
+}
+
+# NxN fixed devices
+
+proc fixed_array {n devname startx starty} {
+ suspendall
+ box position $startx $starty
+ set i 0
+ for {set x 0} {$x < $n} {incr x} {
+ for {set y 0} {$y < $n} {incr y} {
+
+ set nx [int [+ 1 [* [rand] 4]]]
+ set ny [int [+ 1 [* [rand] 4]]]
+
+ # Do not change the deltas---this will cause DRC problems
+ set r 0
+ # set r [int [* [rand] 10]]
+ set deltax [/ $r 10.0]
+ # set r [int [* [rand] 10]]
+ set deltay [/ $r 10.0]
+
+ magic::gencell sky130::${devname} ${devname}_$i \
+ nx $nx ny $ny deltax $deltax deltay $deltay
+ select cell ${devname}_$i
+ set bh [box height]
+ set bh [* $bh [+ $ny 1]]
+ box move n $bh
+ incr i
+ }
+ set bp [box position]
+ set bpx [lindex $bp 0]
+ box position $bpx $starty
+ box move e 20000
+ }
+ resumeall
+}
+
+snap int
+box size 0 0
+
+# Layout:
+# phv
+# mrl1 mrp1 mrdp mrdp_hv
+# nhv pdiode_h
+# ndiode_h
+# pshort nndiode
+# xhrpoly xpwres mrdn mrdn_hv pdiode
+# nshort ndiode
+#
+
+mos_array 6 nshort 0 0
+mos_array 6 pshort 0 75000
+mos_array 6 nhv 0 150000
+mos_array 6 phv 0 225000
+mos_array 6 nlowvt 0 300000
+mos_array 6 sonos_e 0 375000 12700 1650
+mos_array 6 plowvt 0 450000
+mos_array 6 phighvt 0 525000
+mos_array 6 nhvnative 0 600000
+
+res_array 6 xhrpoly 100000 0
+res_array 6 mrl1 100000 180000
+res_array 6 uhrpoly 100000 360000
+
+res_array 6 xpwres 200000 0 13500 1100
+res_array 6 mrp1 200000 200000
+
+res_array 6 mrdn 300000 0
+res_array 6 mrdp 300000 180000
+
+res_array 6 mrdn_hv 400000 0
+res_array 6 mrdp_hv 400000 180000
+
+diode_array 6 ndiode 500000 0
+diode_array 6 pdiode 500000 30000
+diode_array 6 ndiode_h 500000 60000
+diode_array 6 pdiode_h 500000 90000
+
+cap_array 6 xcmimc1 600000 0
+cap_array 6 xcmimc2 600000 70000 18000 650
+
+mos_array 6 xcnwvc 700000 0 15000 254
+mos_array 6 xchvnwc 700000 70000 18000 254
+mos_array 6 xcnwvc2 700000 140000 15000 254
+
+fixed_array 2 sky130_fd_pr_rf_npn_1x1 850000 0
+fixed_array 2 sky130_fd_pr_rf_npn_1x2 850000 30000
+fixed_array 2 sky130_fd_pr_rf_pnp5x 850000 60000
+
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp11p5x11p7_lim5shield 900000 0
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp11p5x11p7_m3_lim5shield 900000 30000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp11p5x11p7_m4shield 900000 60000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym4shield 900000 90000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp4p4x4p6_m3_lim5shield 900000 120000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp6p8x6p1_lim4shield 900000 150000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp6p8x6p1_polym4shield 900000 180000
+fixed_array 2 sky130_fd_pr_rf2_xcmvpp8p6x7p9_m3_lim5shield 900000 210000
+fixed_array 2 sky130_fd_pr_rf2_xcmvppx4_2xnhvnative10x4 900000 240000
+# fixed_array 2 sky130_fd_pr_rf2_xcmvpp11p5x11p7_polym50p4shield 900000 270000
+
+fixed_array 2 sky130_fd_pr_rf_xcmvpp11p5x11p7_m3_lishield 950000 0
+fixed_array 2 sky130_fd_pr_rf_xcmvpp11p5x11p7_m3shield 950000 30000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp2 950000 60000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp2_nwell 950000 90000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp4p4x4p6_m3_lishield 950000 120000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp4p4x4p6_m3shield 950000 150000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp8p6x7p9_m3_lishield 950000 180000
+fixed_array 2 sky130_fd_pr_rf_xcmvpp8p6x7p9_m3shield 950000 210000
+# fixed_array 2 sky130_fd_pr_rf_xcmvpp1p8x1p8_lishield 950000 240000
+# fixed_array 2 sky130_fd_pr_rf_xcmvpp1p8x1p8_m3shield 950000 270000
+
+fixed_array 1 balun 1000000 0
+fixed_array 1 xind4_02 1000000 200000
+fixed_array 1 xind4_011 1250000 0
+
+# Draw a deep nwell region around the sonos transistor block
+box values -5200i 369500i 76800i 427500i
+sky130::deep_nwell_draw
+
+save torture_test_sky130
+gds write torture_test_sky130
diff --git a/sky130/sky130_setup.tcl b/sky130/sky130_setup.tcl
new file mode 100644
index 0000000..af90784
--- /dev/null
+++ b/sky130/sky130_setup.tcl
@@ -0,0 +1,296 @@
+###
+### Source file sky130_setup.tcl
+### Process this file with the preproc.py processor
+###
+#---------------------------------------------------------------
+# Setup file for netgen LVS
+# SkyWater TECHNAME
+#---------------------------------------------------------------
+permute default
+property default
+property parallel none
+
+#---------------------------------------------------------------
+# For the following, get the cell lists from
+# circuit1 and circuit2.
+#---------------------------------------------------------------
+
+set cells1 [cells list -all -circuit1]
+set cells2 [cells list -all -circuit2]
+
+# NOTE: In accordance with the LVS manager GUI, the schematic is
+# always circuit2, so some items like property "par1" only need to
+# be specified for circuit2.
+
+#-------------------------------------------
+# Resistors (except metal)
+#-------------------------------------------
+
+set devices {xpwres mrp1 xhrpoly uhrpoly mrdn mrdp mrdn_hv mrdp_hv}
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ permute "-circuit1 $dev" 1 2
+ property "-circuit1 $dev" series enable
+ property "-circuit1 $dev" series {w critical}
+ property "-circuit1 $dev" series {l add}
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit1 $dev" parallel {value par}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ permute "-circuit2 $dev" 1 2
+ property "-circuit1 $dev" series enable
+ property "-circuit1 $dev" series {w critical}
+ property "-circuit1 $dev" series {l add}
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit1 $dev" parallel {value par}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+}
+
+#-------------------------------------------
+# MRM (metal) resistors
+#-------------------------------------------
+
+set devices {mrl1 mrm1 mrm2 mrm3}
+#ifdef METAL5
+lappend devices mrm4
+lappend devices mrm5
+#endif (METAL5)
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ permute "-circuit1 $dev" 1 2
+ property "-circuit1 $dev" series enable
+ property "-circuit1 $dev" series {w critical}
+ property "-circuit1 $dev" series {l add}
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit1 $dev" parallel {value par}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ permute "-circuit2 $dev" 1 2
+ property "-circuit1 $dev" series enable
+ property "-circuit1 $dev" series {w critical}
+ property "-circuit1 $dev" series {l add}
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit1 $dev" parallel {value par}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+}
+
+#-------------------------------------------
+# (MOS) transistors
+#-------------------------------------------
+
+set devices {nshort nlowvt sonos_e nhvnative nhv pshort plowvt phighvt phv}
+lappend devices xcnwvc
+lappend devices xcnwvc2
+lappend devices xchvnwc
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ permute "-circuit1 $dev" 1 3
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit1 $dev" tolerance {w 0.01} {l 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 NRD NRS
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ permute "-circuit2 $dev" 1 3
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {l critical}
+ property "-circuit1 $dev" parallel {w add}
+ property "-circuit2 $dev" tolerance {w 0.01} {l 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 NRD NRS
+ }
+}
+
+#-------------------------------------------
+# diodes
+#-------------------------------------------
+
+set devices {ndiode ndiode_lvt pdiode pdiode_lvt pdiode_hvt ndiode_h pdiode_h}
+lappend devices ndiode_native
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {area add}
+ property "-circuit1 $dev" parallel {value add}
+ property "-circuit1 $dev" tolerance {area 0.02}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 peri
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ property "-circuit2 $dev" parallel enable
+ property "-circuit1 $dev" parallel {area add}
+ property "-circuit1 $dev" parallel {value add}
+ property "-circuit2 $dev" tolerance {area 0.02}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 peri
+ }
+}
+
+#-------------------------------------------
+# capacitors
+# MiM capacitors
+#-------------------------------------------
+
+set devices {xcmimc1 xcmimc2}
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {area add}
+ property "-circuit1 $dev" parallel {value add}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ property "-circuit1 $dev" parallel enable
+ property "-circuit1 $dev" parallel {area add}
+ property "-circuit1 $dev" parallel {value add}
+ property "-circuit1 $dev" tolerance {l 0.01} {w 0.01}
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1 pm
+ }
+}
+
+#-------------------------------------------
+# Fixed-layout devices
+# bipolar transistors,
+# VPP capacitors
+#-------------------------------------------
+
+set devices {sky130rf_npn_1x1 sky130rf_npn_1x2 sky130rf_pnp5x}
+#ifdef METAL5
+lappend devices balun xint4_011 xind4_02
+lappend devices sky130rf2_xcmvpp11p5x11p7_lim5shield
+lappend devices sky130rf2_xcmvpp11p5x11p7_m3_lim5shield
+lappend devices sky130rf2_xcmvpp11p5x11p7_m4shield
+lappend devices sky130rf2_xcmvpp11p5x11p7_polym4shield
+lappend devices sky130rf2_xcmvpp11p5x11p7_polym50p4shield
+lappend devices sky130rf2_xcmvpp4p4x4p6_m3_lim5shield
+lappend devices sky130rf2_xcmvpp6p8x6p1_lim4shield
+lappend devices sky130rf2_xcmvpp6p8x6p1_polym4shield
+#endif (METAL5)
+lappend devices sky130rf2_xcmvpp8p6x7p9_m3_lim5shield
+lappend devices sky130rf2_xcmvppx4_2xnhvnative10x4
+lappend devices sky130rf_xcmvpp11p5x11p7_m3_lishield
+lappend devices sky130rf_xcmvpp11p5x11p7_m3shield
+lappend devices sky130rf_xcmvpp1p8x1p8_lishield
+lappend devices sky130rf_xcmvpp1p8x1p8_m3shield
+lappend devices sky130rf_xcmvpp2
+lappend devices sky130rf_xcmvpp2_nwell
+lappend devices sky130rf_xcmvpp4p4x4p6_m3_lishield
+lappend devices sky130rf_xcmvpp4p4x4p6_m3shield
+lappend devices sky130rf_xcmvpp8p6x7p9_m3_lishield
+lappend devices sky130rf_xcmvpp8p6x7p9_m3shield
+
+foreach dev $devices {
+ if {[lsearch $cells1 $dev] >= 0} {
+ property "-circuit1 $dev" parallel enable
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1
+ }
+ if {[lsearch $cells2 $dev] >= 0} {
+ property "-circuit2 $dev" parallel enable
+ # Ignore these properties
+ property "-circuit2 $dev" delete par1
+ }
+}
+
+#---------------------------------------------------------------
+# Digital cells (ignore decap, fill, and tap cells)
+# Make a separate list for each supported library
+#---------------------------------------------------------------
+# e.g., ignore class "-circuit2 sky130_fc_sc_hd_decap_3"
+#---------------------------------------------------------------
+
+foreach cell $cells1 {
+ if {[regexp "sky130_fc_sc_hd_decap_\[0-9\]+" $cell match]} {
+ ignore class "-circuit1 $cell"
+ }
+ if {[regexp "sky130_fc_sc_hd_fill_\[0-9\]+" $cell match]} {
+ ignore class "-circuit1 $cell"
+ }
+}
+foreach cell $cells2 {
+ if {[regexp "sky130_fc_sc_hd_decap_\[0-9\]+" $cell match]} {
+ ignore class "-circuit2 $cell"
+ }
+ if {[regexp "sky130_fc_sc_hd_fill_\[0-9\]+" $cell match]} {
+ ignore class "-circuit2 $cell"
+ }
+}
+
+#---------------------------------------------------------------
+# Handle cells captured from Electric
+#
+# Find cells of the form "<library>__<cellname>" in the netlist
+# from Electric where the extracted layout netlist has only
+# "<cellname>". Cross-check by ensuring that the full name
+# "<library>__<cellname>" does not exist in both cells, and that
+# the truncated name "<cellname>" does not exist in both cells.
+#---------------------------------------------------------------
+# e.g., hydra_spi_controller__hydra_spi_controller
+#---------------------------------------------------------------
+foreach cell $cells1 {
+ if {[regexp "(.+)__(.+)" $cell match library cellname]} {
+ if {([lsearch $cells2 $cell] < 0) && \
+ ([lsearch $cells2 $cellname] >= 0) && \
+ ([lsearch $cells1 $cellname] < 0)} {
+ equate classes "-circuit1 $cell" "-circuit2 $cellname"
+ puts stdout "Matching pins of $cell in circuit 1 and $cellname in circuit 2"
+ equate pins "-circuit1 $cell" "-circuit2 $cellname"
+ }
+ }
+}
+
+foreach cell $cells2 {
+ if {[regexp "(.+)__(.+)" $cell match library cellname]} {
+ if {([lsearch $cells1 $cell] < 0) && \
+ ([lsearch $cells1 $cellname] >= 0) && \
+ ([lsearch $cells2 $cellname] < 0)} {
+ equate classes "-circuit1 $cellname" "-circuit2 $cell"
+ puts stdout "Matching pins of $cellname in circuit 1 and $cell in circuit 2"
+ equate pins "-circuit1 $cellname" "-circuit2 $cell"
+ }
+ }
+}
+
+# Match pins on black-box cells if LVS is called with "-blackbox"
+if {[model blackbox]} {
+ foreach cell $cells1 {
+ if {[model "-circuit1 $cell"] == "blackbox"} {
+ if {[lsearch $cells2 $cell] >= 0} {
+ puts stdout "Matching pins of $cell in circuits 1 and 2"
+ equate pins "-circuit1 $cell" "-circuit2 $cell"
+ }
+ }
+ }
+}
+
+#---------------------------------------------------------------
diff --git a/sky130/sky130gds.tech b/sky130/sky130gds.tech
new file mode 100644
index 0000000..8beebdc
--- /dev/null
+++ b/sky130/sky130gds.tech
@@ -0,0 +1,689 @@
+tech
+ format 32
+ TECHNAME-GDS
+end
+
+version
+ version REVISION
+ description "SkyWater S8: Vendor GDS layers"
+end
+
+planes
+ p1
+ p2
+ p3
+ p4
+ p5
+ p6
+ p7
+ p8
+ p9
+ p10
+ p11
+ p12
+ p13
+ p14
+ p15
+ p16
+ p17
+ p18
+ p19
+ p20
+ p21
+ p22
+ p23
+ p24
+ p25
+ p26
+ p27
+ p28
+ p29
+ p30
+ p31
+ p32
+ p33
+ p34
+ p35
+ p36
+ p37
+ p38
+ p39
+ p40
+ p41
+ p42
+end
+
+types
+ p1 NWELL,l1
+ p1 NWELLT,l60
+ p1 NWELLP,l62
+ p2 DNWELL,l2
+ p3 DIFF,l3
+ p3 TAP,l4
+ p4 LVTN,l5
+ p4 HVTP,l6
+ p5 HVI,l7
+ p6 TUNM,l8
+ p7 POLY,l9
+ p7 POLYP,l63
+ p7 POLYT,l70
+ p8 NPC,l10
+ p9 PSDM,l11
+ p9 NSDM,l12
+ p10 LICON1,l13
+ p11 LI1,l14
+ p11 LI1T,l15
+ p11 LI1P,l16
+ p12 MCON,l17
+ p12 MET1,l18
+ p12 MET1T,l19
+ p12 MET1P,l20
+ p13 VIA1,l21
+ p13 MET2,l22
+ p13 MET2T,l23
+ p13 MET2P,l24
+ p14 VIA2,l25
+ p14 MET3,l26
+ p14 MET3T,l27
+ p14 MET3P,l28
+ p15 VIA3,l29
+ p15 MET4,l30
+ p15 MET4T,l31
+ p15 MET4P,l32
+ p16 VIA4,l33
+ p16 MET5,l34
+ p16 MET5T,l35
+ p16 MET5P,l36
+ p17 PAD,l37
+ p17 PADT,l38
+ p17 PADP,l39
+ p18 AREAID,l40
+ p19 TEXT,l41
+ p20 HVTR,l42
+ p21 NCM,l43
+ p22 RPM,l44
+ p23 NSM,l45
+ p24 RDL,l46
+ p25 VHVI,l47
+ p26 LDNTM,l48
+ p26 HVNTM,l49
+ p27 PMM,l50
+ p28 PNP,l51
+ p29 CAP,l52
+ p30 IND,l53
+ p31 PWRES,l54
+ p32 POLYRES,l55
+ p33 DIFFRES,l56
+ p34 DIODE,l57
+ p35 POLYM,l58
+ p36 COREID,l59
+ p37 PWELLT,l61
+ p37 PWELLP,l64
+ p38 CFOMDROP,l65
+ p39 CLI1MADD,l66
+ p40 CNTMADD,l67
+ p41 CP1MADD,l68
+ p42 BOUND,l69
+end
+
+contact
+end
+
+styles
+ styletype mos
+ l1 nwell
+ l2 cwell
+ l3 ndiffusion
+ l4 pdiffusion
+ l5 implant1
+ l6 implant2
+ l7 implant3
+ l8 subcircuit
+ l9 polysilicon
+ l10 implant4
+ l11 pdop_stripes
+ l12 ndop_stripes
+ l13 obsmetal1 contact_X'es
+ l14 metal1
+ l15 metal1
+ l16 metal1
+ l17 metal1 metal2 via1
+ l18 metal2
+ l19 metal2
+ l20 metal2
+ l21 metal2 metal3 via2
+ l22 metal3
+ l23 metal3
+ l24 metal3
+ l25 metal3 metal4 via3
+ l26 metal4
+ l27 metal4
+ l28 metal4
+ l29 metal4 metal5 via4
+ l30 metal5
+ l31 metal5
+ l32 metal5
+ l33 metal5 metal6 via5
+ l34 metal6
+ l35 metal6
+ l36 metal6
+ l37 overglass
+ l38 overglass
+ l39 overglass
+ l40 subcircuit
+ l41 comment
+ l42 implant1
+ l43 mim_top
+ l44 mim_bottom
+ l45 ntransistor_stripes
+ l46 metal7
+ l47 electrode
+ l48 nwell_field_implant
+ l49 hvndiff_mask
+ l50 poly_light
+ l51 mvpdiff
+ l52 mvndiff
+ l53 hvpdiff
+ l54 cwellnsc
+ l55 poly_resist poly_resist_stripes
+ l56 ptransistor_stripes
+ l57 hvpdiff_mask
+ l58 poly_resist
+ l59 subcircuit
+ l60 nwell
+ l61 pwell
+ l62 nwell
+ l63 polysilicon
+ l64 pwell
+ l65 implant1
+ l66 implant2
+ l67 implant3
+ l68 implant4
+ l69 subcircuit
+ l70 polysilicon
+end
+
+compose
+ paint MCON MET1 MCON
+ paint VIA1 MET2 VIA1
+ paint VIA2 MET3 VIA2
+ paint VIA3 MET4 VIA3
+ paint VIA4 MET5 VIA4
+end
+
+connect
+end
+
+cifoutput
+style gdsii
+ scalefactor 50 nanometers
+ options calma-permissive-labels
+ layer NWELL NWELL,NWELLT,NWELLP
+ calma 64 20
+
+ layer NWELLT
+ labels NWELLT noport
+ calma 64 16
+
+ layer NWELLP
+ labels NWELLP port
+ calma 64 5
+
+ layer DNWELL DNWELL
+ labels DNWELL
+ calma 64 18
+
+ layer DIFF DIFF
+ labels DIFF
+ calma 65 20
+
+ layer TAP TAP
+ labels TAP
+ calma 65 44
+
+ layer POLY POLY,POLYP,POLYT
+ calma 66 20
+
+ layer POLYT
+ labels POLYT noport
+ calma 66 16
+
+ layer POLYP
+ labels POLYP port
+ calma 66 5
+
+ layer LVTN LVTN
+ labels LVTN
+ calma 125 44
+
+ layer HVTP HVTP
+ labels HVTP
+ calma 78 44
+
+ layer HVI HVI
+ labels HVI
+ calma 75 20
+
+ layer TUNM TUNM
+ labels TUNM
+ calma 80 20
+
+ layer NPC NPC
+ labels NPC
+ calma 95 20
+
+ layer PSDM PSDM
+ labels PSDM
+ calma 94 20
+
+ layer NSDM NSDM
+ labels NSDM
+ calma 93 44
+
+ layer LICON1 LICON1
+ labels LICON1
+ calma 66 44
+
+ # Note: LICON1 not on LI1 plane, may not be coincident with LI1.
+ layer LI1 LI1,LI1T,LI1P
+ calma 67 20
+
+ layer LI1T
+ labels LI1T noport
+ calma 67 16
+
+ layer LI1P
+ labels LI1P port
+ calma 67 5
+
+ layer MET1 MET1,MET1T,MET1P,MCON
+ calma 68 20
+
+ layer MET1T
+ labels MET1T noport
+ calma 68 16
+
+ layer MET1P
+ labels MET1P port
+ calma 68 5
+
+ layer MCON MCON
+ labels MCON
+ calma 67 44
+
+ layer MET2 MET2,MET2T,MET2P,VIA1
+ calma 69 20
+
+ layer MET2T
+ labels MET2T noport
+ calma 69 16
+
+ layer MET2P
+ labels MET2P port
+ calma 69 5
+
+ layer VIA1 VIA1
+ labels VIA1
+ calma 68 44
+
+ layer MET3 MET3,MET3T,MET3P,VIA2
+ calma 70 20
+
+ layer MET3T
+ labels MET3T noport
+ calma 70 16
+
+ layer MET3P
+ labels MET3P port
+ calma 70 5
+
+ layer VIA2 VIA2
+ labels VIA2
+ calma 69 44
+
+ layer MET4 MET4,MET4T,MET4P,VIA3
+ calma 71 20
+
+ layer MET4T
+ labels MET4T noport
+ calma 71 16
+
+ layer MET4P
+ labels MET4P port
+ calma 71 5
+
+ layer VIA3 VIA3
+ labels VIA3
+ calma 70 44
+
+ layer MET5 MET5,MET5T,MET5P,VIA4
+ calma 72 20
+
+ layer MET5T
+ labels MET5T noport
+ calma 72 16
+
+ layer MET5P
+ labels MET5P port
+ calma 72 5
+
+ layer VIA4 VIA4
+ labels VIA4
+ calma 71 44
+
+ layer PAD PAD,PADT,PADP
+ calma 76 20
+
+ layer PADT
+ labels PADT noport
+ calma 76 16
+
+ layer PADP
+ labels PADP port
+ calma 76 5
+
+ layer AREAID AREAID
+ labels AREAID
+ calma 81 4
+
+ layer TEXT TEXT
+ labels TEXT
+ calma 83 44
+
+ layer HVTR HVTR
+ labels HVTR
+ calma 18 20
+
+ layer NCM NCM
+ labels NCM
+ calma 92 44
+
+ layer RPM RPM
+ labels RPM
+ calma 86 20
+
+ layer NSM NSM
+ labels NSM
+ calma 61 20
+
+ layer RDL RDL
+ labels RDL
+ calma 74 20
+
+ layer VHVI VHVI
+ labels VHVI
+ calma 74 21
+
+ layer LDNTM LDNTM
+ labels LDNTM
+ calma 11 44
+
+ layer HVNTM HVNTM
+ labels HVNTM
+ calma 125 20
+
+ layer PMM PMM
+ labels PMM
+ calma 85 44
+
+ layer PNP PNP
+ labels PNP
+ calma 82 44
+
+ layer CAP CAP
+ labels CAP
+ calma 82 64
+
+ layer IND IND
+ labels IND
+ calma 82 24
+
+ layer PWRES PWRES
+ labels PWRES
+ calma 64 13
+
+ layer POLYRES POLYRES
+ labels POLYRES
+ calma 66 13
+
+ layer DIFFRES DIFFRES
+ labels DIFFRES
+ calma 65 13
+
+ layer DIODE DIODE
+ labels DIODE
+ calma 81 23
+
+ layer POLYM POLYM
+ labels POLYM
+ calma 66 83
+
+ layer COREID COREID
+ labels COREID
+ calma 81 2
+
+ layer PWELLT PWELLT
+ labels PWELLT noport
+ calma 122 16
+
+ layer PWELLP PWELLP
+ labels PWELLP port
+ calma 64 59
+
+ layer CFOMDROP CFOMDROP
+ labels CFOMDROP
+ calma 22 22
+
+ layer CLI1MADD CLI1MADD
+ labels CLI1MADD
+ calma 115 43
+
+ layer CNTMADD CNTMADD
+ labels CNTMADD
+ calma 22 21
+
+ layer CP1MADD CP1MADD
+ labels CP1MADD
+ calma 33 43
+
+ layer BOUND BOUND
+ labels BOUND
+ calma 235 4
+end
+
+cifinput
+style ProgName
+ scalefactor 50 nanometers
+ layer l1 NWELL
+ layer l2 DNWELL
+ layer l3 DIFF
+ layer l4 TAP
+ layer l5 LVTN
+ layer l6 HVTP
+ layer l7 HVI
+ layer l8 TUNM
+ layer l9 POLY
+ layer l10 NPC
+ layer l11 PSDM
+ layer l12 NSDM
+ layer l13 LICON1
+ layer l14 LI1
+ layer l15 LI1T
+ layer l16 LI1P
+ layer l17 MCON
+ layer l18 MET1
+ layer l19 MET1T
+ layer l20 MET1P
+ layer l21 VIA1
+ layer l22 MET2
+ layer l23 MET2T
+ layer l24 MET2P
+ layer l25 VIA2
+ layer l26 MET3
+ layer l27 MET3T
+ layer l28 MET3P
+ layer l29 VIA3
+ layer l30 MET4
+ layer l31 MET4T
+ layer l32 MET4P
+ layer l33 VIA4
+ layer l34 MET5
+ layer l35 MET5T
+ layer l36 MET5P
+ layer l37 PAD
+ layer l38 PADT
+ layer l39 PADP
+ layer l40 AREAID
+ layer l41 TEXT
+ layer l42 HVTR
+ layer l43 NCM
+ layer l44 RPM
+ layer l45 NSM
+ layer l46 RDL
+ layer l47 VHVI
+ layer l48 LDNTM
+ layer l49 HVNTM
+ layer l50 PMM
+ layer l51 PNP
+ layer l52 CAP
+ layer l53 IND
+ layer l54 PWRES
+ layer l55 POLYRES
+ layer l56 DIFFRES
+ layer l57 DIODE
+ layer l58 POLYM
+ layer l59 COREID
+ layer l60 NWELLT
+ layer l61 PWELLT
+ layer l62 NWELLP
+ layer l63 POLYP
+ layer l64 PWELLP
+ layer l65 CFOMDROP
+ layer l66 CLI1MADD
+ layer l67 CNTMADD
+ layer l68 CP1MADD
+ layer l69 BOUND
+ layer l70 POLYT
+ calma NWELL 64 20
+ calma DNWELL 64 18
+ calma DIFF 65 20
+ calma TAP 65 44
+ calma LVTN 125 44
+ calma HVTP 78 44
+ calma HVI 75 20
+ calma TUNM 80 20
+ calma POLY 66 20
+ calma NPC 95 20
+ calma PSDM 94 20
+ calma NSDM 93 44
+ calma LICON1 66 44
+ calma LI1 67 20
+ calma LI1T 67 16
+ calma LI1P 67 5
+ calma MCON 67 44
+ calma MET1 68 20
+ calma MET1T 68 16
+ calma MET1P 68 5
+ calma VIA1 68 44
+ calma MET2 69 20
+ calma MET2T 69 16
+ calma MET2P 69 5
+ calma VIA2 69 44
+ calma MET3 70 20
+ calma MET3T 70 16
+ calma MET3P 70 5
+ calma VIA3 70 44
+ calma MET4 71 20
+ calma MET4T 71 16
+ calma MET4P 71 5
+ calma VIA4 71 44
+ calma MET5 72 20
+ calma MET5T 72 16
+ calma MET5P 72 5
+ calma PAD 76 20
+ calma PADT 76 16
+ calma PADP 76 5
+ calma AREAID 81 4
+ calma TEXT 83 44
+ calma HVTR 18 20
+ calma NCM 92 44
+ calma RPM 86 20
+ calma NSM 61 20
+ calma RDL 74 20
+ calma VHVI 74 21
+ calma LDNTM 11 44
+ calma HVNTM 125 20
+ calma PMM 85 44
+ calma PNP 82 44
+ calma CAP 82 64
+ calma IND 82 24
+ calma PWRES 64 13
+ calma POLYRES 66 13
+ calma DIFFRES 65 13
+ calma DIODE 81 23
+ calma POLYM 66 83
+ calma COREID 81 2
+ calma NWELLT 64 16
+ calma PWELLT 122 16
+ calma NWELLP 64 5
+ calma POLYP 66 5
+ calma PWELLP 64 59
+ calma CFOMDROP 22 22
+ calma CLI1MADD 115 43
+ calma CNTMADD 22 21
+ calma CP1MADD 33 43
+ calma BOUND 235 4
+ calma POLYT 66 16
+end
+
+mzrouter
+end
+
+drc
+end
+
+extract
+style default
+ planeorder p1 0
+ planeorder p2 1
+ planeorder p3 2
+ planeorder p4 3
+ planeorder p5 4
+ planeorder p6 5
+ planeorder p7 6
+ planeorder p8 7
+ planeorder p9 8
+ planeorder p10 9
+ planeorder p11 10
+ planeorder p12 11
+ planeorder p13 12
+ planeorder p14 13
+ planeorder p15 14
+ planeorder p16 15
+ planeorder p17 16
+ planeorder p18 17
+ planeorder p19 18
+ planeorder p20 19
+ planeorder p21 20
+ planeorder p22 21
+ planeorder p23 22
+ planeorder p24 23
+ planeorder p25 24
+ planeorder p26 25
+ planeorder p27 26
+ planeorder p28 27
+ planeorder p29 28
+ planeorder p30 29
+ planeorder p31 30
+ planeorder p32 31
+ planeorder p33 32
+ planeorder p34 33
+ planeorder p35 34
+ planeorder p36 35
+ planeorder p37 36
+ planeorder p38 37
+ planeorder p39 38
+ planeorder p40 39
+ planeorder p41 40
+ planeorder p42 41
+end
diff --git a/sky130/sky130osu.sh b/sky130/sky130osu.sh
new file mode 100644
index 0000000..4afd9bd
--- /dev/null
+++ b/sky130/sky130osu.sh
@@ -0,0 +1,93 @@
+#!/bin/tcsh
+#---------------------------------------------------------------
+# Shell script setting up all variables used by the qflow scripts
+# for this project
+#---------------------------------------------------------------
+
+# The LEF file containing standard cell macros
+
+#ifdef EF_FORMAT
+set leffile=STAGING_PATH/TECHNAME/libs.ref/lef/sky130_osu130/sky130_osu130.lef
+#else (!EF_FORMAT)
+set leffile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/lef/sky130_osu130.lef
+#endif (!EF_FORMAT)
+
+# The SPICE netlist containing subcell definitions for all the standard cells
+#ifdef EF_FORMAT
+set spicefile=STAGING_PATH/TECHNAME/libs.ref/spice/sky130_osu130/sky130_osu130.spice
+#else (!EF_FORMAT)
+set spicefile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/spice/sky130_osu130.spice
+#endif (!EF_FORMAT)
+
+# The liberty format file containing standard cell timing and function information
+#ifdef EF_FORMAT
+set libertyfile=STAGING_PATH/TECHNAME/libs.ref/lib/sky130_osu130/sky130_osu130.lib
+#else (!EF_FORMAT)
+set libertyfile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/lib/sky130_osu130.lib
+#endif (!EF_FORMAT)
+
+# If there is another LEF file containing technology information
+# that is separate from the file containing standard cell macros,
+# set this. Otherwise, leave it defined as an empty string.
+
+#ifdef METAL5
+#ifdef EF_FORMAT
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/techLEF/sky130_osu130/sky130_osu130_tech.lef
+#else (!EF_FORMAT)
+set techleffile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/techLEF/sky130_osu130_tech.lef
+#endif (!EF_FORMAT)
+#else
+# NOTE: There is no technology LEF file for the 3-metal stack!
+#endif
+
+# All cells below should be the lowest output drive strength value,
+# if the standard cell set has multiple cells with different drive
+# strengths. Comment out any cells that do not exist.
+
+set bufcell=BUFX2 ;# Minimum drive strength buffer cell
+set bufpin_in=A ;# Name of input port to buffer cell
+set bufpin_out=Y ;# Name of output port to buffer cell
+set clkbufcell=BUFX2 ;# Minimum drive strength buffer cell
+set clkbufpin_in=A ;# Name of input port to buffer cell
+set clkbufpin_out=Y ;# Name of output port to buffer cell
+
+set fillcell=FILL ;# Spacer (filler) cell (prefix, if more than one)
+set decapcell="" ;# Decap (filler) cell (prefix, if more than one)
+set antennacell="" ;# Antenna (filler) cell (prefix, if more than one)
+set antennapin_in="" ;# Antenna cell input connection
+set bodytiecell="" ;# Body tie (filler) cell (prefix, if more than one)
+
+# yosys tries to eliminate use of these; depends on source .v
+set tiehi="" ;# Cell to connect to power, if one exists
+set tiehipin_out="" ;# Output pin name of tiehi cell, if it exists
+set tielo="" ;# Cell to connect to ground, if one exists
+set tielopin_out="" ;# Output pin name of tielo cell, if it exists
+
+set gndnet="vdd" ;# Name used for ground pins in standard cells
+set vddnet="vss" ;# Name used for power pins in standard cells
+
+set separator="" ;# Separator between gate names and drive strengths
+set techfile=STAGING_PATH/TECHNAME/MAGIC_CURRENT/TECHNAME.tech ;# magic techfile
+set magicrc=STAGING_PATH/TECHNAME/MAGIC_CURRENT/TECHNAME.magicrc ;# magic startup script
+set magic_display="XR" ;# magic display, defeat display query and OGL preference
+set netgen_setup=STAGING_PATH/TECHNAME/libs.tech/netgen/TECHNAME_setup.tcl ;# netgen setup file for LVS
+#ifdef EF_FORMAT
+set gdsfile=STAGING_PATH/TECHNAME/libs.ref/gds/sky130_osu130/sky130_osu130.gds ;# GDS database of standard cells
+set verilogfile=STAGING_PATH/TECHNAME/libs.ref/verilog/sky130_osu130/sky130_osu130.v ;# Verilog models of standard cells
+#else (!EF_FORMAT)
+set gdsfile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/gds/sky130_osu130.gds ;# GDS database of standard cells
+set verilogfile=STAGING_PATH/TECHNAME/libs.ref/sky130_osu130/verilog/sky130_osu130.v ;# Verilog models of standard cells
+#endif (!EF_FORMAT)
+
+# Set a conditional default in the project_vars.sh file for this process
+set postproc_options=""
+#ifdef METAL5
+# Normally one does not want to use the top metal for signal routing
+set route_layers = 5
+#else
+set route_layers = 3
+#endif
+set fill_ratios="100,0,0,0"
+set fanout_options="-l 100 -c 10"
+set addspacers_options="-stripe 1.6 40.0 PG"
+set xspice_options="-io_time=250p -time=50p -idelay=20p -odelay=50p -cload=250f"