diff --git a/.github/scripts/install_dependencies.sh b/.github/scripts/install_dependencies.sh
index 71933e09138..351ec7d56a7 100755
--- a/.github/scripts/install_dependencies.sh
+++ b/.github/scripts/install_dependencies.sh
@@ -10,6 +10,7 @@ sudo apt install -y \
binutils \
binutils-gold \
build-essential \
+ capnproto \
cmake \
ctags \
curl \
@@ -20,6 +21,7 @@ sudo apt install -y \
git \
gperf \
libcairo2-dev \
+ libcapnp-dev \
libgtk-3-dev \
libevent-dev \
libfontconfig1-dev \
@@ -54,3 +56,9 @@ sudo apt install -y \
# libtbb-dev
pip install -r requirements.txt
+
+git clone https://github.com/capnproto/capnproto-java.git $GITHUB_WORKSPACE/env/capnproto-java
+pushd $GITHUB_WORKSPACE/env/capnproto-java
+make
+sudo make install
+popd
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 40179ed4552..46c077ddf24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,6 +40,7 @@ option(VTR_ENABLE_CAPNPROTO "Enable capnproto binary serialization support in VP
#Allow the user to enable/disable VPR analytic placement
#VPR option --enable_analytic_placer is also required for Analytic Placement
option(VPR_ANALYTIC_PLACE "Enable analytic placement in VPR." ON)
+option(VPR_ENABLE_INTERCHANGE "Enable FPGA interchange." ON)
option(WITH_BLIFEXPLORER "Enable build with blifexplorer" OFF)
@@ -121,6 +122,11 @@ endif()
# Build type flags
#
+set(EXTRA_FLAGS "")
+if(VPR_ENABLE_INTERCHANGE)
+ set(EXTRA_FLAGS "-lz")
+endif()
+
if(NOT MSVC)
# for GCC and Clang
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3")
@@ -295,7 +301,7 @@ endif()
# Set final flags
#
separate_arguments(
- ADDITIONAL_FLAGS UNIX_COMMAND "${SANITIZE_FLAGS} ${PROFILING_FLAGS} ${COVERAGE_FLAGS} ${LOGGING_FLAGS} ${COLORED_COMPILE}"
+ ADDITIONAL_FLAGS UNIX_COMMAND "${SANITIZE_FLAGS} ${PROFILING_FLAGS} ${COVERAGE_FLAGS} ${LOGGING_FLAGS} ${COLORED_COMPILE} ${EXTRA_FLAGS}"
)
separate_arguments(
WARN_FLAGS UNIX_COMMAND "${WARN_FLAGS}"
@@ -366,7 +372,6 @@ if (VPR_USE_EZGL STREQUAL "auto")
endif()
endif()
-
#Add the various sub-projects
if(${WITH_ABC})
add_subdirectory(abc)
diff --git a/dev/subtree_config.xml b/dev/subtree_config.xml
index 19875e23c0d..b25af6b85d3 100644
--- a/dev/subtree_config.xml
+++ b/dev/subtree_config.xml
@@ -1,42 +1,47 @@
-
-
-
-
-
-
-
-
+
diff --git a/libs/EXTERNAL/CMakeLists.txt b/libs/EXTERNAL/CMakeLists.txt
index 548cc45551f..a0d0842ac82 100644
--- a/libs/EXTERNAL/CMakeLists.txt
+++ b/libs/EXTERNAL/CMakeLists.txt
@@ -8,7 +8,7 @@ add_subdirectory(libsdcparse)
add_subdirectory(libblifparse)
add_subdirectory(libtatum)
-#VPR_USE_EZGL is initialized in the root CMakeLists.
+#VPR_USE_EZGL is initialized in the root CMakeLists.
#compile libezgl only if the user asks for or has its dependencies installed.
if(VPR_USE_EZGL STREQUAL "on")
add_subdirectory(libezgl)
diff --git a/libs/EXTERNAL/libinterchange/.github/workflows/ci.yml b/libs/EXTERNAL/libinterchange/.github/workflows/ci.yml
new file mode 100644
index 00000000000..2187914723d
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/.github/workflows/ci.yml
@@ -0,0 +1,42 @@
+# Copyright (C) 2017-2021 The SymbiFlow Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+name: CI tests
+on: [push, pull_request]
+jobs:
+ Check-schema:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ submodules: recursive
+
+ - uses: SymbiFlow/actions/checks@main
+
+ - name: Install
+ run: |
+ sudo apt-get install capnproto libcapnp-dev
+ git clone https://github.com/capnproto/capnproto-java.git $GITHUB_WORKSPACE/env/capnproto-java
+ cd $GITHUB_WORKSPACE/env/capnproto-java
+ make
+ sudo make install
+ - name: Build schemas
+ run: |
+ mkdir build
+ capnp compile -Iinterchange -oc++:build interchange/References.capnp
+ capnp compile -Iinterchange -oc++:build interchange/LogicalNetlist.capnp
+ capnp compile -Iinterchange -oc++:build interchange/PhysicalNetlist.capnp
+ capnp compile -Iinterchange -oc++:build interchange/DeviceResources.capnp
diff --git a/libs/EXTERNAL/libinterchange/.gitignore b/libs/EXTERNAL/libinterchange/.gitignore
new file mode 100644
index 00000000000..96935f26b38
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/.gitignore
@@ -0,0 +1,120 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+env/
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# Emacs temporary files
+*~
diff --git a/libs/EXTERNAL/libinterchange/.readthedocs.yml b/libs/EXTERNAL/libinterchange/.readthedocs.yml
new file mode 100644
index 00000000000..80f0f323048
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/.readthedocs.yml
@@ -0,0 +1,32 @@
+# Copyright (C) 2017-2021 The SymbiFlow Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ configuration: docs/conf.py
+
+formats:
+ - htmlzip
+
+conda:
+ environment: docs/environment.yml
diff --git a/libs/EXTERNAL/libinterchange/LICENSE b/libs/EXTERNAL/libinterchange/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/libs/EXTERNAL/libinterchange/README.md b/libs/EXTERNAL/libinterchange/README.md
new file mode 100644
index 00000000000..063ba44f6ba
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/README.md
@@ -0,0 +1,16 @@
+# FPGA interchange schema definitions
+
+This repository contains the capnp schema for the FPGA interchange.
+
+## Repositories that implement tools around the FPGA interchange
+
+[RapidWright](https://github.com/Xilinx/RapidWright/):
+ - Provides support for 7-series, UltraScale and UltraScale+ parts
+ - Generate device database for parts
+ - Can convert DCPs to logical and physical FPGA interchange files.
+ - Can convert logical and physical FPGA interchange files to DCPs
+
+[python-fpga-interchange](https://github.com/SymbiFlow/python-fpga-interchange):
+ - Implements textual format conversions for FPGA interchange files.
+ - Provides (partial) generator for nextpnr to generate a nextpnr architecture
+ for a FPGA interchange device database.
diff --git a/libs/EXTERNAL/libinterchange/cmake/cxx_static/CMakeLists.txt b/libs/EXTERNAL/libinterchange/cmake/cxx_static/CMakeLists.txt
new file mode 100644
index 00000000000..196c328824f
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/cmake/cxx_static/CMakeLists.txt
@@ -0,0 +1,48 @@
+find_package(CapnProto REQUIRED)
+set(PROTOS LogicalNetlist.capnp PhysicalNetlist.capnp DeviceResources.capnp References.capnp)
+
+set(INTERCHANGE_SCHEMA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../interchange)
+
+find_program(WGET wget REQUIRED)
+
+set(JAVA_SCHEMA ${CMAKE_CURRENT_BINARY_DIR}/schema/capnp/java.capnp)
+add_custom_command(
+ OUTPUT ${JAVA_SCHEMA}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/schema/capnp/
+ COMMAND ${WGET}
+ https://raw.githubusercontent.com/capnproto/capnproto-java/master/compiler/src/main/schema/capnp/java.capnp
+ -O ${JAVA_SCHEMA}
+ )
+add_custom_target(
+ get_java_capnp_schema
+ DEPENDS ${JAVA_SCHEMA})
+
+set(CAPNPC_IMPORT_DIRS)
+list(APPEND CAPNPC_IMPORT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/schema)
+
+set(CAPNPC_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/../../interchange")
+
+add_custom_command(
+ OUTPUT ${CAPNPC_OUTPUT_DIR}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CAPNPC_OUTPUT_DIR}
+ )
+add_custom_target(
+ fpga_interchange_capnp_output_directory
+ DEPENDS ${CAPNPC_OUTPUT_DIR})
+
+set(CAPNPC_SRC_PREFIX ${INTERCHANGE_SCHEMA_DIR})
+set(CAPNP_SRCS)
+set(CAPNP_HDRS)
+foreach (proto ${PROTOS})
+ capnp_generate_cpp(CAPNP_SRC CAPNP_HDR ${INTERCHANGE_SCHEMA_DIR}/${proto})
+ list(APPEND CAPNP_HDRS ${CAPNP_HDR})
+ list(APPEND CAPNP_SRCS ${CAPNP_SRC})
+endforeach()
+add_library(fpga_interchange_capnp STATIC ${CAPNP_SRCS})
+add_dependencies(fpga_interchange_capnp
+ get_java_capnp_schema
+ fpga_interchange_capnp_output_directory)
+target_link_libraries(fpga_interchange_capnp PRIVATE CapnProto::capnp)
+
+get_filename_component(FPGA_INTERCHANGE_CAPNP_INCLUDE_DIR "${CAPNPC_OUTPUT_DIR}" ABSOLUTE)
+target_include_directories(fpga_interchange_capnp INTERFACE ${FPGA_INTERCHANGE_CAPNP_INCLUDE_DIR})
diff --git a/libs/EXTERNAL/libinterchange/docs/Makefile b/libs/EXTERNAL/libinterchange/docs/Makefile
new file mode 100644
index 00000000000..681c4eafc43
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/Makefile
@@ -0,0 +1,74 @@
+# Copyright (C) 2017-2021 The SymbiFlow Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Minimal makefile for Sphinx documentation
+
+
+SHELL = /bin/bash
+MAKEDIR := $(dir $(lastword $(MAKEFILE_LIST)))
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = [ -e env/bin/activate ] && source env/bin/activate; sphinx-build
+SPHINXAUTOBUILD = [ -e env/bin/activate ] && source env/bin/activate; sphinx-autobuild
+SPHINXPROJ = SymbiFlowFIF
+SOURCEDIR = .
+BUILDDIR = _build
+OSFLAG =
+UNAME_S := $(shell uname -s)
+ifneq (, $(findstring Linux, $(UNAME_S)))
+ OSFLAG := Linux
+endif
+ifeq ($(UNAME_S), Darwin)
+ OSFLAG := MacOSX
+endif
+ifneq (, $(findstring Cygwin, $(UNAME_S)))
+ OSFLAG := Linux
+endif
+ifneq (, $(findstring MINGW, $(UNAME_S)))
+ OSFLAG := Linux
+endif
+
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+livehtml:
+ @$(SPHINXAUTOBUILD) -b html --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
+
+.PHONY: help livehtml Makefile
+
+
+env/Miniconda3-latest-$(OSFLAG)-x86_64.sh:
+ mkdir env
+ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-$(OSFLAG)-x86_64.sh -O env/Miniconda3-latest-$(OSFLAG)-x86_64.sh
+ chmod a+x env/Miniconda3-latest-$(OSFLAG)-x86_64.sh
+
+env:
+ rm -rf env
+ make env/Miniconda3-latest-$(OSFLAG)-x86_64.sh
+ ./env/Miniconda3-latest-$(OSFLAG)-x86_64.sh -p $(PWD)/env -b -f
+ source env/bin/activate; conda config --system --add envs_dirs $(PWD)/env/envs
+ source env/bin/activate; conda config --system --add pkgs_dirs $(PWD)/env/pkgs
+ source env/bin/activate; conda env update --name base --file ./environment.yml
+
+.PHONY: env
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%:
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/libs/EXTERNAL/libinterchange/docs/_static/.keepme b/libs/EXTERNAL/libinterchange/docs/_static/.keepme
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libs/EXTERNAL/libinterchange/docs/bel_and_site_design.md b/libs/EXTERNAL/libinterchange/docs/bel_and_site_design.md
new file mode 100644
index 00000000000..266ec0ea940
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/bel_and_site_design.md
@@ -0,0 +1,258 @@
+# Cell, BEL and Site Design
+
+One of the key concepts within the FPGA interchange device resources is the
+relationship between the cell library and the device BEL and site definitions.
+A well designed cell library and a flexible but concise BEL and site
+definition is important for exposing the hardware in an efficient way that
+enables a place and route tool to succeed.
+
+Good design is hard to capture, but this document will talk about some of the
+considerations.
+
+### Assumptions about cell placement and driver BEL pins
+
+One important note is that BELs represent a placable location for a cell, and
+only one cell should be placable at a given BEL. This means that the cell
+library design and BEL design strongly affects what is expressable by the
+place and route tool. There will be some examples highlighted below that
+expand on how this is important and relevant when discussing concrete
+examples.
+
+## Granularity of the cell library
+
+It is important to divide the place and route problem and the synthesis
+problem, at least as defined for the purpose of the FPGA interchange. The
+synthesis tool operates on the **cell library**, which should be designed to
+expose logic elements at a useful level of granularity.
+
+As a concrete example, a LUT4 element is technically just two LUT3 elements,
+connected by a mux (e.g. MUXF4), a LUT3 element is just two LUT2 elements,
+connected by a mux (e.g. MUXF3), etc. If the outputs of those interior muxes
+are not accessible to the place and route tool, then exposing those interior
+function muxes as cells in the cell library is not as useful.
+
+Cell definitions should be granular enough that the synthesis can map to
+them, but not so granular that the place and route tool will be making few if
+any choices. If there is only one legal placement of the cell, it's value is
+relatively low.
+
+## Drawing site boundaries
+
+When designing an FPGA interchange device resource for a new fabric, one
+important consideration is where to draw the site boundary. The primary goal
+of lumping BELs within a site is to capture some local congestion due to
+fanout limitations. Interior static routing muxes and output muxes may
+accommodate significantly fewer signals than the possible number of BELs that
+drive them. In this case, it is important to draw the site boundary large
+enough to capture these cases so as to enable the local congestion to be
+resolved during either packing for clustered approaches, or during placement
+during unclustered approaches. In either case, local congestion that is
+strongly placement dependant must be resolved prior to general routing,
+unless a fused placement and routing algorithm is used.
+
+### FF control sets routing
+
+A common case worth exploring is FF control sets, e.g. SR type signals and CE
+type signals. In most fabric SLICE types, the SR and CE control signals are
+shared among multiple rows of the SLICE. This is a common example of local
+site congestion, and the site boundary should typically encompass all BELs
+that share this kind of local routing for all the reasons discussed above.
+
+Another consideration with control signals is the presence of control signal
+constraints that cannot be expressed as local routing congestion. For
+example, if a set of BELs share whether the SR control line is a set or reset
+(or async set or async reset), it is common to expand the site boundary to
+cover the BELs that share these implicit configurations. The constraint
+system in the device resources is designed to handle this kind of non-routing
+driven configuration.
+
+## Drawing BEL boundaries
+
+BEL definitions require creating a boundary around primitive elements of
+the fabric. The choice of where to place that boundary has a strong influence
+on the design of the cell library in the FPGA interchange.
+
+In general, the smaller the BEL boundary, the more complexity is exposed to
+the place and route tool. In some cases exposing this complexity is
+important, because it enables some goal. For example, leaving static routing
+muxes outside of BELs enables a place and route tool to have greater
+flexibility when resolving site congestion. But as a counter point, if only
+a handful of static mux configurations are useful and those choices can be
+made at synthesis time, then lumping those muxes into synthesis reduces the
+complexity required in the place and route tool.
+
+The most common case where the static routing muxes are typically lumped into
+the BEL is BRAM's and FIFO's address and routing configuration. At synthesis
+time, a choice is made about the address and data widths, which are encoded as
+parameters on the cell. The place and route tool does not typically make
+meaningful choices on the configuration of those static routing muxes, but
+they do exist in the hardware.
+
+The most common case where the static routing muxes are almost never lumped
+into the BEL is SLICE-type situations. The remainder of this document will
+show examples of why the BEL boundary should typically exclude the static
+routing muxes, and leave the choice to the place and route tooling.
+
+## Static routing muxes and bitstream formats
+
+Something to keep in mind when drawing BEL boundaries to include or exclude
+static routing muxes is the degree of configurability present in the
+underlying bitstream. Some static routing muxes share configuration bits in
+the bitstream, and so expressing them as two seperate static routing muxes
+potentially gives the place and route tool flexibility than the underlying
+fabric cannot express. This will result in physical netlists that cannot be
+converted to bitstream.
+
+In some cases this can be handled through tight coupling of the cell and
+BEL library. The idea is to limit cell port to BEL pin mappings that avoid
+illegal static routing mux configurations. This approach has its limits.
+In general, considering how the bitstream expresses static routing muxes must
+be accounted for when drawing BEL boundaries.
+
+### Stratix II and Stratix 10 ALM
+
+![Stratix II](stratix2_slice.png-026_rotate.png)
+
+![Stratix 10](stratix10_slice.png-11.png)
+
+Consider both Stratix II and Stratix 10 logic sites. The first thing to note
+is that the architectures at this level are actually mostly the same. Though
+it isn't immediately apparent, both designs are structured around 4 4-LUT
+elements.
+
+Take note that of the following structure:
+
+![Stratix II fractured LUT4](frac_lut4.png)
+
+This is actually just two LUT4 elements, where the top select line is
+independent.
+
+See the following two figures:
+
+![Stratix II fractured LUT4 Top](frac_lut4_a.png)
+![Stratix II fractured LUT4 Bottom](frac_lut4_b.png)
+
+In Stratix 10, the LUT4 element is still present, but the top select line
+fracturing was removed.
+
+So now consider the output paths from the the 4 LUT4 elements in the Stratix
+II site. Some of the LUT4 outputs route directly to the carry element, so it
+will be important for the place and route tool be able to place a LUT4 or
+smaller to access that direct connection. But if the output is not used in
+the carry element, then it can only be accessed in Stratix II via the MUXF5
+(blue below) and MUXF6 (red below) elements.
+
+![Stratix II Highlight MUXF5 and MUXF6](highlight_muxf5_muxf6.png)
+
+So given the Stratix II site layout, the following BELs will be required:
+
+ - 4 LUT4 BELs that connect to the carry
+ - 2 LUT6 BELs that connect to the output FF or output MUX.
+
+The two LUT6 BELs are shown below:
+
+![Stratix II Top LUT6](highlight_top_lut6.png)
+![Stratix II Top LUT6](highlight_bottom_lut6.png)
+
+Drawing a smaller BEL boundary has little value, because a LUT5 element would
+still always require routing through the MUXF6 element.
+
+Now consider the Stratix 10 output arrangement. The LUT4 elements direct to
+the carry element is the same, so those BELs would be identical. The Stratix
+10 site now has an output tap directly on the top LUT5, similiar to the Xilinx
+Versal LUT6 / LUT5 fracture setup. See diagram below. LUT5 element is shown
+in blue, and LUT6 element is shown in red.
+
+![Stratix 10 2 LUT5](stratix10_highlight_lut5.png)
+![Stratix 10 LUT6](stratix10_highlight_lut6.png)
+
+So given the Stratix 10 site layout, the following BELs will be required:
+
+ - 4 LUT4 BELs that connect to the carry
+ - 2 LUT5 BELs that connect to the output FF or output MUX
+ - 1 LUT6 BELs that connect to the output FF or output MUX
+
+### Versal ACAP
+
+The Versal ACAP LUT structure is fairly similiar to the Stratix 10 combitorial
+elements.
+
+![Versal ACAP LUTs](versal_luts.png)
+
+Unlike the Stratix 10 ALM, it appears only 1 of the LUT4's connects to the
+carry element (the prop signal). The O6 output also has a dedicate
+connection to the carry. See image below:
+
+![Versal SLICE row](versal_row.png)
+
+The Versal LUT structure likely should be decomposed into 4 BELs, shown in
+the next figures:
+
+![Versal ACAP LUT4](versal_lut4.png)
+![Versal ACAP two LUT5](versal_lut5.png)
+![Versal ACAP LUT6](versal_lut6.png)
+
+So given the Versal site layout, the following BELs will be required (per SLICE row):
+
+ - 1 LUT4 BELs that connect to the carry
+ - 2 LUT5 BELs that connect to the output FF or output MUX
+ - 1 LUT6 BELs that connect to the output FF or output MUX
+
+#### Implication of a wider BEL definition
+
+Consider the Versal structure, but instead of drawing four BELs per row, only have two
+BELs per row. One BEL has the `O5_1` and `prop` output BEL pins and the
+other BEL has the `O6` and `O5_2` BEL pin. In this configuration, if the cell
+library does not expose a cell that maps to both the `O5_1` and `prop` output
+BEL pins, then it will not be possible to map LUTs that leverage both output
+BEL pins.
+
+In theory, the cell port to BEL pin map could map the output pin of a LUT4
+element to both the `prop` and `O5_1` output BEL pins, but then there will be
+two output BEL pins driving the net connected to the cell port. Having
+multiple BEL pins driving one net is not legal, except for the global logic 0
+and 1.
+
+
+### Quicklogic EOS S3 logic cell
+
+The Quicklogic EOS S3 logic cell has an interesting LUT design because there
+is not LUT element specifically. Instead, the fabric exposes a 8x3 mux, with
+inverters at each of the mux inputs, see figure below:
+
+![Quicklogic EOS S3 logic cell](eos_slice.png)
+
+The way to approach this fabric is to first draw BEL boundaries around the 4x2
+mux and 8x3 mux present in the fabric:
+
+![Quicklogic MUX4x2](eos_slice_mux4x2.png)
+![Quicklogic MUX8x3](eos_slice_mux8x3.png)
+
+The cell library should have
+3 MUX cell types:
+ - 4-input 1-output 2-select MUX4x2 (maps to MUX4x2 BEL and MUX8x3 BEL)
+ - 8-input 1-output 3-select MUX8x3 (maps to MUX8x3 BEL)
+ - A macro cell that is 2x (4-input 1-output 2-select MUX4x2) 2xMUX4x2 (maps to MUX4x2 *and* MUX8x3 BEL)
+
+A fourth most general cell type is possible, which is to add a cell that also
+has a cell port that maps to `TBS`, instead of tying `TBS` high as the
+2xMUX4x2 cell would do. It is unclear how useful such a cell would be.
+However given the BEL boundaries, adding such a cell would be easy after the
+fact.
+
+In all of the cells above, all inputs to the muxes have statically
+configured inverters.
+
+So the question becomes, how to model LUT cells in this fabric? The LUT cells
+should be the regular LUT1, LUT2 and LUT3 cells. The LUT1 and LUT2 can map to
+either the MUX4x2 or MUX8x3 BEL. The LUT3 can map to only the MUX8x3 BEL.
+The question is only what is the cell port to BEL pin map?
+
+The solution is when mapping a LUT cell, to tie all of the MUX BEL pins to VCC
+(or GND, whatever the default is) before the inverter. The place and route
+tool can treat the BEL as a regular LUT, and only the bitstream generation
+step will need to be aware that the inversion control is being used to
+encode the LUT equation.
+
+This configuration allows most (if not all) of the logic to be available
+to the place and route tool, without exposing unneeded complexity.
diff --git a/libs/EXTERNAL/libinterchange/docs/conf.py b/libs/EXTERNAL/libinterchange/docs/conf.py
new file mode 100644
index 00000000000..dff3816eab6
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/conf.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2017-2021 The SymbiFlow Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# SymbiFlow Interchange-schema documentation build configuration file,
+# created by sphinx-quickstart on Mon Feb 5 11:04:37 2018.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import re
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.autosummary',
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.imgmath',
+ 'sphinx.ext.napoleon',
+ 'sphinx.ext.todo',
+ 'sphinx_markdown_tables',
+ 'recommonmark',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+source_suffix = ['.rst', '.md']
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'SymbiFlow FPGA Interchange Format'
+copyright = u'2021, SymbiFlow Team'
+author = u'SymbiFlow Team'
+
+# Enable github links when not on readthedocs
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+if not on_rtd:
+ html_context = {
+ "display_github": True, # Integrate GitHub
+ "github_user": "symbiflow", # Username
+ "github_repo": "fpga-interchange-schema", # Repo name
+ "github_version": "master", # Version
+ "conf_py_path": "/docs/",
+ }
+else:
+ docs_dir = os.path.abspath(os.path.dirname(__file__))
+ print("Docs dir is:", docs_dir)
+ import subprocess
+ subprocess.call('git fetch origin --unshallow', cwd=docs_dir, shell=True)
+ subprocess.check_call('git fetch origin --tags', cwd=docs_dir, shell=True)
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The full version, including alpha/beta/rc tags.
+release = re.sub('^v', '', os.popen('git describe').read().strip())
+# The short X.Y version.
+version = release
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'env', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'default'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_symbiflow_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+html_theme_options = {
+ 'repo_name': 'SymbiFlow/fpga-interchange-schema',
+ 'github_url': 'https://github.com/SymbiFlow/fpga-interchange-schema',
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# This is required for the alabaster theme
+# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
+html_sidebars = {
+ '**': [
+ 'relations.html', # needs 'show_related': True theme option to display
+ 'searchbox.html',
+ ]
+}
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'fpga-interchange-schema'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (
+ master_doc,
+ 'fpga-interchange-schema.tex',
+ u'SymbiFlow FPGA Interchange Format Documentation',
+ u'SymbiFlow Team',
+ 'manual',
+ ),
+]
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (
+ master_doc,
+ 'fpga-interchange-schema',
+ u'SymbiFlow FPGA Interchange Format Documentation',
+ [author],
+ 1,
+ ),
+]
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (
+ master_doc,
+ 'SymbiFlowFIFM',
+ u'SymbiFlow FPGA Interchange Format Documentation',
+ author,
+ 'SymbiFlowFIF',
+ 'One line description of project.',
+ 'Miscellaneous',
+ ),
+]
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'https://docs.python.org/': None}
+
+
+def setup(app):
+ pass
diff --git a/libs/EXTERNAL/libinterchange/docs/device_resources.md b/libs/EXTERNAL/libinterchange/docs/device_resources.md
new file mode 100644
index 00000000000..9793098bd58
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/device_resources.md
@@ -0,0 +1,374 @@
+# Device Resources
+
+The device resources schema is intended to be a complete description of an
+island-based FPGA design. It is made of many components, but the core
+description of the device is shown below.
+
+```
+┌─────────────────┐
+│ Device │
+│ ┌─────────────┐ │
+│ │ Tile │ │
+│ │ ┌─────────┐ │ │
+│ │ │ Site │ │ │
+│ │ │ ┌─────┐ │ │ │
+│ │ │ │ BEL │ │ │ │
+│ │ │ └─────┘ │ │ │
+│ │ │ │ │ │
+│ │ └─────────┘ │ │
+│ │ │ │
+│ └─────────────┘ │
+│ │
+└─────────────────┘
+```
+
+That is:
+ - A device contains tiles
+ - Tiles contains sites
+ - Sites contains BELs
+
+The schema contains the required information to answer questions such as:
+ - Where are tiles located?
+ - How are sites connected to the routing graph?
+ - How are BELs connected to the boundary of the site?
+ - How can cells be placed at BELs?
+
+## Terminology
+
+- Device - A set of tiles and package pins.
+- Tiles - An instance of a tile type which contains wires and sites
+- Package pin - A boundry between the "interior" of the device and what is "outside" the package. Generally corresponds to a pin on a package, e.g. pin 1 on SOP-8 or A1 on CSG324.
+- Wire - Also known as a "tile wire" . A wire is a piece of conductive material totally contained within a tile. Wires can be part of nodes. Wires can connect to PIPs or site pins.
+- Node - A node is a set of 1 or more wires that are connected. Nodes can span multiple tiles. Nodes connect to PIPs or site pins via the wires that are part of the node.
+- PIP - PIP is an abbreviation for programable interconnect point. A PIP provides a connection between two wires. PIPs can be unidirectional or bidirectional. Unidirectional PIPs always connect wire0 to wire1. Bidirectional PIPs can connect wire0 to wire1 or wire1 to wire0.
+- Site - A collection of site pins, site wires and BELs.
+- Site pin - The connection between a site and a wire. Site pins may connect to 0 or more site port BELs.
+- Site wire - A piece of conductive material that connects to at most 1 output BEL pin and 0 or more input or inout BEL pins.
+- BEL - BEL is an abbreviation of basic logic element. A BEL can be one of 3 types, site port, logic, routing. A BEL contains 1 or more BEL pins.
+- BEL pin - A connection between a BEL and a site wire.
+- Logic BEL - A placable logic element. May be subject to 0 or more placement constraints.
+- Site port BEL - A site port BEL represents a connection to a site pin contained within the parent tile of the site. See [Site port BEL](#site_port_bel).
+- Routing BEL - A routing BEL connects at most 1 input BEL pin to the output BEL pin. See [Routing BEL](#routing_bel).
+- Site PIP - A pair of input and output BEL pins belonging to a BEL that represents a logically connection.
+- Cell - A logical element of a design that contains some number of cell ports and some number of cell instances, and some number of nets.
+- Cell port - The boundary between the interior of a cell and the containing cell (if any).
+- Cell instance - A instance of a cell. The cell ports of may be connected to nets within the parent cell.
+- Net - A set of logically connected cell ports.
+
+## The place and route problem
+
+The device resources schema is intended to provide a description for a tool
+solving the place and route problem. The definition of the problem used by
+this schema is described below:
+
+There exists exactly 1 **cell instance** (the **top** instance) that contains 1 or
+more leaf **cell instances** that must be placed at **BELs**, such that no
+**constraints** are violated and the **nets** between the **cell instances** are
+**routable**. **Routable** means that **site wires**, **site PIPs**, **nodes**, **PIPs**
+can be assigned to at most 1 **net** such that each **net driver BEL pin** can
+reach each every **net sink BEL pin** on the **net**.
+
+The device resource format describes how **cell instances** can be legally
+placed at **BELs** and how **cell pins** relate to **BEL pins**. When a
+**cell instance** is placed at a **BEL**, it may be subject to 0 or more
+**constraints**.
+
+**Nets** are divided into 3 categories. A **signal** net represents a signal
+that is not either the constant logical 0 or constant logical 1 net.
+The constant logical 0 and constant logical 1 nets are special because they
+can have multiple drivers in the device description. Routing resources that
+are always part of the constant logical 0 or constant logical 1 net are
+explicitly defined in the device resources schema. The constant logical 0 net
+is listed in the schema as the "gnd" type. The constant logical 1 net is
+listed in the schema as the "vcc" type.
+
+### Rules for routing
+
+Fully routed signal nets always begin at a output/inout BEL pin, and always
+end at an input/inout BEL pin. If a net enters a site, that net **must** end
+at an input/inout BEL pin. It is not legal for a net to enter and leave a
+site. If such a path is required, a pseudo PIP should be added to the schema.
+
+## Site example
+
+The following is an example site for a SLICE for a non-existent device.
+
+```
+ ▲
+ CO│ │
+ ┌──────────────────────────┼─────────────────────────────────────┼──────┐
+ │ │ │ │
+ B0│ I0┌───────┐ │ BLUT ┌───────┐ ▼ CLK │
+─────┼────►│ │ ┌────────o─────────────────┬────►│ │ ┌────┐ │
+ B1│ I1│ │O │ │ │XOR │ │D D│ │Q │ FFOUT
+─────┼────►│ BLUT3 ├───┤ │ ┌────────┬──o────►│ FFMUX ├──►│ FF ├───┼───►
+ B2│ I2│ │ │ │ │ │ |ALUT │ │ │ │ │
+─────┼────►│ │ │ │ │ ┌──┬──o──o────►│ │ └────┘ │
+ │ └───────┘ │ ┌───┴───┐ │ │ │ │ │ └───────┘ │
+ │ │ SI│ │ │ │ │ │ │ │
+ │ └───►│ ├─┘ │ │ │ │ │
+ │ DX│ CARRY │ O │ │ │ │ │
+ │ ┌───►│ │ │ │ │ │ │
+ A0│ I0┌───────┐ │ └───┬───┘ │ │ │ │ ┌────────┐ │
+─────┼────►│ │ │ │ │ │ │ │ BLUT │ │ │
+ A1│ I1│ │O │ │ │ │ │ └─────►│ │OUT │ OUT
+─────┼────►│ ALUT3 ├───┴────────o────────┘ │ │ XOR │ OUTMUX ├──────────┼────►
+ B2│ I2│ │ │ │ └────────►│ │ │
+─────┼────►│ │ │ │ ALUT │ │ │
+ │ └───────┘ │ └───────────►└────────┘ │
+ │ │ │
+ │ │ │
+ └──────────────────────────┼────────────────────────────────────────────┘
+ CI│
+ │
+```
+
+In the above example, there are 17 BELs:
+
+| BEL Name | Category | # Input | # Output |
+|----------|-----------|---------|----------|
+| ALUT3 | Logic | 3 | 1 |
+| BLUT3 | Logic | 3 | 1 |
+| CARRY | Logic | 3 | 2 |
+| FF | Logic | 2 | 1 |
+| FFMUX | Routing | 3 | 1 |
+| OUTMUX | Routing | 3 | 1 |
+| A0 | Site port | 0 | 1 |
+| A1 | Site port | 0 | 1 |
+| A2 | Site port | 0 | 1 |
+| B0 | Site port | 0 | 1 |
+| B1 | Site port | 0 | 1 |
+| B2 | Site port | 0 | 1 |
+| CI | Site port | 0 | 1 |
+| CLK | Site port | 0 | 1 |
+| CO | Site port | 1 | 0 |
+| FFOUT | Site port | 1 | 0 |
+| OUT | Site port | 1 | 0 |
+
+Each site port BEL has a site pin, so the site pins are:
+
+| Site Pin Name | Direction |
+|---------------|-----------|
+| A0 | In |
+| A1 | In |
+| A2 | In |
+| B0 | In |
+| B1 | In |
+| B2 | In |
+| CI | In |
+| CLK | In |
+| CO | Out |
+| FFOUT | Out |
+| OUT | Out |
+
+The BEL BLUT3 has 4 BEL pins:
+
+| BEL pin name | Direction |
+|--------------|-----------|
+| I0 | In |
+| I1 | In |
+| I2 | In |
+| O | Out |
+
+The BEL A0 has 1 BEL pin:
+
+| BEL pin name | Direction |
+|--------------|-----------|
+| A0 | Out |
+
+The BEL OUTMUX has 4 BEL pins:
+
+| BEL pin name | Direction |
+|--------------|-----------|
+| BLUT | In |
+| XOR | In |
+| ALUT | In |
+| OUT | Out |
+
+
+There are 12 site PIPs:
+
+| BEL name | In pin | Out pin |
+|----------|--------|---------|
+| BLUT3 | I0 | O |
+| BLUT3 | I1 | O |
+| BLUT3 | I2 | O |
+| ALUT3 | I0 | O |
+| ALUT3 | I1 | O |
+| ALUT3 | I2 | O |
+| FFMUX | ALUT | D |
+| FFMUX | XOR | D |
+| FFMUX | BLUT | D |
+| OUTMUX | ALUT | OUT |
+| OUTMUX | XOR | OUT |
+| OUTMUX | BLUT | OUT |
+
+
+The site wire BLUT3\_O has 4 BEL pins:
+
+| BEL Name | Pin |
+|----------|------|
+| BLUT3 | O |
+| CARRY | SI |
+| FFMUX | BLUT |
+| OUTMUX | BLUT |
+
+The site wire B0 has 2 BEL pins:
+
+| BEL Name | Pin |
+|----------|-----|
+| B0 | B0 |
+| BLUT3 | I0 |
+
+## Details
+
+### Net routing summary
+
+Each net start at the driver output/inout BEL pin. The BEL pin will be
+connected to exactly 1 site wire. If the net sink can be reached within the
+site, then the net can use site PIPs to reach a site wire connected to the
+input/inout BEL pin.
+
+If the net sink is in another site, then the net must first reach a site port
+input BEL pin using site PIPs to reach the site wire connected to the site
+port. From there the net leaves the site via the site port and is now on the
+first node via the site pin matching the site port.
+
+From there the net must use PIPs to expand to new nodes until arriving at a
+node attached to valid site pin for the sink. This would be a site pin that
+is part of the same site that the sink BEL is part of, and that the site port
+wire can reach the sink BEL pin (via 0 or more site PIPs). The site can be
+entered via the site port corresponding to the site pin. The first site wire
+in the site will be the site wire attached to the output BEL pin of the site
+port. From there site routing continues per above.
+
+![Wire and nodes](https://symbiflow.readthedocs.io/projects/arch-defs/en/latest/_images/rrgraph-wire.svg)
+
+### Use of site PIPs
+
+It is important to note that site PIPs can only be used to access placed cells
+inside that site. Site PIPs cannot be used as general route-thrus, to route
+from site input to output. General route-thrus across entire sites should use
+tile pseudo PIPs as described below - even if a site pin is being validly used
+for one sink pin of a net that is located inside the site; site PIPs cannot
+also be used to leave the site again to reach other sinks.
+
+LUT route-thrus, for example, might require both site PIPs and tile pseudo
+PIPs. The site PIP would be used to route through the LUT in order to access
+an associated flipflop input inside the site. The tile PIP would be used to
+route across the entire site as part of the general, inter-tile, routing
+problem.
+
+A diagram illustrating the legal and illegal uses is shown below.
+
+![Site PIP usage](site_pip_usage.svg)
+
+### Tile Types and site types
+
+To reduce data duplication in the device schema, both tiles and sites have a
+type. Most of the definition of the tile and site is in the type rather than
+repeated at each instance. This does cause some more complicated
+indirection, so the following section provides some additional explanation
+here.
+
+#### Sites, site types and alternative site types
+
+The most complicated relationship in the schema is likely the relationship
+between sites, site types and alternative site types.
+
+Most of the site type description is independent of the tile / tile type that
+the site type is within. See the "SiteType" struct definition for
+the independent portion of the schema. The important exception is the
+relationship between wires and site pins.
+
+Each site within a tile has a "primary site type", which is found in the
+"SiteTypeInTileType" struct definition, contained in the "TileType" struct.
+The site within the tile will specify which "SiteTypeInTileType" to use for
+that particular site.
+
+The primary site type contains a list of "alternative" site types that may be
+used ("altSiteTypes" in "SiteType"). The primary site type must always
+contains the complete list of site pins used in any of the alternative site
+types.
+
+The site pins to wire relationship is always done via the primary site type.
+When an alternative site type is used, the site pins of that alternative site
+type must be first be mapped to a site pin of the primary site type.
+
+The "SiteTypeInTileType" defines the relationship between the primary site
+type and the wires. It also defines the relationship from the alternative
+site type to the primary site type.
+
+It first defines the primary site type ("primaryType"). It defines a map
+between the site pins in the primary site type and wires in the tile type that
+contains the site ("primaryPinsToTileWires"). Last it defines
+the map between the alternative site pin and the primary site pin
+("altPinsToPrimaryPins").
+
+Important: When solving the place and route problem, only the primary or one
+of the alternative site types can be used at a time for a particular site.
+
+### Routing BEL
+
+A routing BEL represents statically configurable site routing by connecting a
+site wire connected to one of the input BEL pins to the output BEL pin of
+the BEL. Routing BELs must have 1 output BEL pin.
+
+#### Inverting routing BELs
+
+Some routing BELs can invert signals that pass through them. Defined the
+"inverting" field in the "BEL" struct with the BEL pins that invert and do
+not invert.
+
+### Site port BEL
+
+A site port BEL represents a connection to a site pin contained within the
+parent tile of the site. Site port BELs have exactly 1 BEL pin. The BEL name
+and pin name should be the same. The name of the BEL should match the name of
+the site pin that the site port connects too. The direction of the BEL pin
+should be the opposite of the site pin direction.
+
+Examples:
+
+An input site pin "I0" would have a site port BEL named "I0" with 1 BEL
+output pin named "I0".
+
+## Additional topics
+
+The device resources schema also covers some important data required for
+handling common cases found in island based FPGAs.
+
+### Signal inversions
+
+It is fairly common for fabrics to contain site local signal inverters.
+Depending on the architecture, the place and route tool may be expected to
+leverage inverters or may even require it. The device resources schemas
+provides a description for how cells express inversion and how to use site
+local inverters to implement the requested inversion.
+
+### LUT definitions
+
+LUTs are common to every island-based FPGA, and many place and route tasks
+depend on having knowledge of how the LUTs are arranged. The LUT definition
+section of the device resources defines where LUTs exist as BELs and what
+cells can be placed at those BELs. This is important is at least two place
+and route tasks. The first is that LUTs can be trivially turned into site pips
+from the input of the LUT to the output of the LUT, subject to **constraints**
+and LUT equation sharing. The second is that LUTs can be trivially turned
+into constant sources from the output pin.
+
+### Parameters
+
+Some parameters attached to cell instances may be relevant for the place and
+route problem. A common example is LUT equation sharing, which can happen on
+fracturable LUTs. See the schema for details.
+
+### Pseudo PIPs
+
+It may be important within a device to represent PIPs that "route-thru"
+one or more BELs. This can be modelled as placing a cell in a particular
+configuration at a BEL, subject to the normal cell placement rules. The
+"PseudoCell" struct defines what resources are used by using PIPs.
+
+All pseudo PIPs must define at least 1 pseudo cell. Pseudo cells should
+include the site port BEL that the pseudo PIP used to enter the site.
diff --git a/libs/EXTERNAL/libinterchange/docs/environment.yml b/libs/EXTERNAL/libinterchange/docs/environment.yml
new file mode 100644
index 00000000000..490164c1596
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/environment.yml
@@ -0,0 +1,32 @@
+# Copyright (C) 2017-2021 The SymbiFlow Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+name: fpga-interchange-schema-docs
+channels:
+- SymbiFlow
+- conda-forge
+- defaults
+dependencies:
+- python=3.7
+- pip
+# ReadTheDoc dependencies
+- mock
+- pillow
+- sphinx
+- sphinx_rtd_theme
+# Packages installed from PyPI
+- pip:
+ - -r requirements.txt
diff --git a/libs/EXTERNAL/libinterchange/docs/eos_slice.png b/libs/EXTERNAL/libinterchange/docs/eos_slice.png
new file mode 100644
index 00000000000..cbe8fd26df2
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/eos_slice.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/eos_slice.png-057.png b/libs/EXTERNAL/libinterchange/docs/eos_slice.png-057.png
new file mode 100644
index 00000000000..d0597ca5c0d
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/eos_slice.png-057.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/eos_slice_mux4x2.png b/libs/EXTERNAL/libinterchange/docs/eos_slice_mux4x2.png
new file mode 100644
index 00000000000..90d49f9ff02
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/eos_slice_mux4x2.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/eos_slice_mux8x3.png b/libs/EXTERNAL/libinterchange/docs/eos_slice_mux8x3.png
new file mode 100644
index 00000000000..4ee6a2be13b
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/eos_slice_mux8x3.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/frac_lut4.png b/libs/EXTERNAL/libinterchange/docs/frac_lut4.png
new file mode 100644
index 00000000000..8ae555d0321
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/frac_lut4.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/frac_lut4_a.png b/libs/EXTERNAL/libinterchange/docs/frac_lut4_a.png
new file mode 100644
index 00000000000..9f700437785
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/frac_lut4_a.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/frac_lut4_b.png b/libs/EXTERNAL/libinterchange/docs/frac_lut4_b.png
new file mode 100644
index 00000000000..49747814cdf
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/frac_lut4_b.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/highlight_bottom_lut6.png b/libs/EXTERNAL/libinterchange/docs/highlight_bottom_lut6.png
new file mode 100644
index 00000000000..2f823400b92
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/highlight_bottom_lut6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/highlight_muxf5.png b/libs/EXTERNAL/libinterchange/docs/highlight_muxf5.png
new file mode 100644
index 00000000000..94f0228d506
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/highlight_muxf5.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/highlight_muxf5_muxf6.png b/libs/EXTERNAL/libinterchange/docs/highlight_muxf5_muxf6.png
new file mode 100644
index 00000000000..551268517d0
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/highlight_muxf5_muxf6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/highlight_top_lut6.png b/libs/EXTERNAL/libinterchange/docs/highlight_top_lut6.png
new file mode 100644
index 00000000000..a78a1c22b6a
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/highlight_top_lut6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/index.rst b/libs/EXTERNAL/libinterchange/docs/index.rst
new file mode 100644
index 00000000000..d8dc21edf8c
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/index.rst
@@ -0,0 +1,18 @@
+Welcome to FPGA Interchange documentation!
+==========================================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ device_resources
+ bel_and_site_design
+ pseudo_cells
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/libs/EXTERNAL/libinterchange/docs/pseudo_cells.md b/libs/EXTERNAL/libinterchange/docs/pseudo_cells.md
new file mode 100644
index 00000000000..65b55d9d44b
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/pseudo_cells.md
@@ -0,0 +1,37 @@
+# Pseudo Cells
+
+Pseudo PIPs and site pseudo PIPs are edges in the device graph that route
+through other sites and/or BELs. Pseudo cells are the expression of what
+routing resources are "blocked" by the use of a pseudo PIP.
+
+The device database currently expresses pseudo PIPs as using BEL pins within
+the site that the pseudo PIP is attached too. Both input and output BEL pins
+are included in the pseudo cell definition, but only output BEL pins "block"
+the site wire.
+
+### Example
+
+In the case of a Xilinx 7-series `CLBLL`'s `CLBLL_LL_A1` to `CLBLL_LL_A`
+pseudo PIP, this PIP connects a signal from an input site port to an output
+site port. Each site wire that is consumed has **both** a output BEL pin
+(from the site wire source) and a input BEL pin (connected to either a logic
+BEL, e.g. `A6LUT` or routing BEL, e.g. `AUSED` or output site port BEL, e.g.
+`A`).
+
+In the case of a `CLBLL`'s `CLBLL_LL_A` to `CLBLL_LL_AMUX` pseudo PIP, this
+PIP connects a signal from an output site port to an output site port. In
+this case, it is assumed and required that some of the site wires are already
+bound to the relevant net (by virtue of the wire `CLBLL_LL_A` already being
+part of the net). In this case, the first BEL pin will be an input BEL pin
+(specifically `AOUTMUX/O6`) that indicates that a site PIP is used as part of
+the pseudo PIP. However in this case, this edge does **not** block the site
+wire, instead it only requires it. The following output BEL pin (specifically
+ `AOUTMUX/OUT`) blocks the site wire `AMUX`.
+
+### Future enhancements
+
+Pseudo cells right now only have BEL pins used by the pseudo PIP. This
+ignores the fact that some BEL's when route through may have constraint
+implications. For example, routing through a LUT BEL requires that it be in
+LUT mode. If that BEL is in either a SRL or LUT-RAM mode, the LUT route
+through may not operate properly.
diff --git a/libs/EXTERNAL/libinterchange/docs/requirements.txt b/libs/EXTERNAL/libinterchange/docs/requirements.txt
new file mode 100644
index 00000000000..b83d25184be
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/requirements.txt
@@ -0,0 +1,10 @@
+git+https://github.com/SymbiFlow/sphinx_symbiflow_theme.git#egg=sphinx_symbiflow_theme
+
+docutils
+sphinx
+sphinx-autobuild
+
+breathe
+recommonmark
+sphinx-markdown-tables
+sphinxcontrib-napoleon
diff --git a/libs/EXTERNAL/libinterchange/docs/site_pip_usage.svg b/libs/EXTERNAL/libinterchange/docs/site_pip_usage.svg
new file mode 100644
index 00000000000..ebf5721486c
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/docs/site_pip_usage.svg
@@ -0,0 +1,178 @@
+
+
+
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut5.png b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut5.png
new file mode 100644
index 00000000000..ae621a6498f
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut5.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut6.png b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut6.png
new file mode 100644
index 00000000000..c14aab13d8e
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_lut6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_muxf5_muxf6.png b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_muxf5_muxf6.png
new file mode 100644
index 00000000000..3addc520931
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix10_highlight_muxf5_muxf6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix10_slice.png-11.png b/libs/EXTERNAL/libinterchange/docs/stratix10_slice.png-11.png
new file mode 100644
index 00000000000..a84aa6ae27b
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix10_slice.png-11.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026.png b/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026.png
new file mode 100644
index 00000000000..c1efec6f4b6
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026_rotate.png b/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026_rotate.png
new file mode 100644
index 00000000000..6021abd3cb9
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/stratix2_slice.png-026_rotate.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_lut4.png b/libs/EXTERNAL/libinterchange/docs/versal_lut4.png
new file mode 100644
index 00000000000..47c958a0372
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_lut4.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_lut5.png b/libs/EXTERNAL/libinterchange/docs/versal_lut5.png
new file mode 100644
index 00000000000..edf197743dd
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_lut5.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_lut6.png b/libs/EXTERNAL/libinterchange/docs/versal_lut6.png
new file mode 100644
index 00000000000..31c907ab18b
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_lut6.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_luts.png b/libs/EXTERNAL/libinterchange/docs/versal_luts.png
new file mode 100644
index 00000000000..94d36e7691a
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_luts.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_row.png b/libs/EXTERNAL/libinterchange/docs/versal_row.png
new file mode 100644
index 00000000000..9af681c9d1d
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_row.png differ
diff --git a/libs/EXTERNAL/libinterchange/docs/versal_slice.png-12.png b/libs/EXTERNAL/libinterchange/docs/versal_slice.png-12.png
new file mode 100644
index 00000000000..84eb163321f
Binary files /dev/null and b/libs/EXTERNAL/libinterchange/docs/versal_slice.png-12.png differ
diff --git a/libs/EXTERNAL/libinterchange/interchange/DeviceResources.capnp b/libs/EXTERNAL/libinterchange/interchange/DeviceResources.capnp
new file mode 100644
index 00000000000..09c8d438555
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/interchange/DeviceResources.capnp
@@ -0,0 +1,915 @@
+# Copyright 2020-2021 Xilinx, Inc. and Google, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+@0x9d262c6ba6512325;
+using Java = import "/capnp/java.capnp";
+using Ref = import "References.capnp";
+using Dir = import "LogicalNetlist.capnp";
+$Java.package("com.xilinx.rapidwright.interchange");
+$Java.outerClassname("DeviceResources");
+
+using Cxx = import "/capnp/c++.capnp";
+$Cxx.namespace("DeviceResources");
+
+struct HashSet {
+ type @0 : Ref.ImplementationType = enumerator;
+ hide @1 : Bool = true;
+}
+annotation hashSet(*) :HashSet;
+
+struct StringRef {
+ type @0 :Ref.ReferenceType = rootValue;
+ field @1 :Text = "strList";
+}
+annotation stringRef(*) :StringRef;
+using StringIdx = UInt32;
+
+struct SiteTypeRef {
+ type @0 :Ref.ReferenceType = root;
+ field @1 :Text = "siteTypeList";
+}
+annotation siteTypeRef(*) :SiteTypeRef;
+using SiteTypeIdx = UInt32;
+
+struct BELPinRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "belPins";
+ depth @2 :Int32 = 1;
+}
+annotation belPinRef(*) :BELPinRef;
+using BELPinIdx = UInt32;
+
+struct WireRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "wires";
+ depth @2 :Int32 = 1;
+}
+annotation wireRef(*) :WireRef;
+using WireIdx = UInt32;
+
+struct WireTypeRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "wireTypes";
+ depth @2 :Int32 = 1;
+}
+annotation wireTypeRef(*) :WireTypeRef;
+using WireTypeIdx = UInt32;
+
+using WireIDInTileType = UInt32; # ID in Tile Type
+using SitePinIdx = UInt32;
+
+struct TileTypeRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "tileTypeList";
+ depth @2 :Int32 = 1;
+}
+annotation tileTypeRef(*) :TileTypeRef;
+using TileTypeIdx = UInt32;
+
+using TileTypeSiteTypeIdx = UInt32;
+using TileTypeSubTileIdx = UInt16;
+
+struct PIPTimingRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "pipTimingList";
+ depth @2 :Int32 = 1;
+
+}
+annotation pipTimingRef(*) :PIPTimingRef;
+using PipTimingIdx = UInt32;
+
+struct NodeTimingRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "nodeTimingList";
+ depth @2 :Int32 = 1;
+
+}
+annotation nodeTimingRef(*) :NodeTimingRef;
+using NodeTimingIdx = UInt32;
+
+struct Device {
+
+ name @0 : Text;
+ strList @1 : List(Text) $hashSet();
+ siteTypeList @2 : List(SiteType);
+ tileTypeList @3 : List(TileType);
+ tileList @4 : List(Tile);
+ wires @5 : List(Wire);
+ nodes @6 : List(Node);
+ # Netlist libraries of Unisim primitives and macros
+ # The library containing primitives should be called "primitives", and
+ # the library containing macros called "macros".
+ primLibs @7 : Dir.Netlist;
+ exceptionMap @8 : List(PrimToMacroExpansion); # Prims to macros expand w/same name, except these
+ cellBelMap @9 : List(CellBelMapping);
+ cellInversions @10 : List(CellInversion);
+ packages @11 : List(Package);
+ constants @12 : Constants;
+ constraints @13 : Constraints;
+ lutDefinitions @14 : LutDefinitions;
+ parameterDefs @15 : ParameterDefinitions;
+ wireTypes @16 : List(WireType);
+ pipTimings @17 : List(PIPTiming);
+ nodeTimings @18 : List(NodeTiming);
+
+ #######################################
+ # Placement definition objects
+ #######################################
+ struct SiteType {
+ name @0 : StringIdx $stringRef();
+ belPins @1 : List(BELPin); # All BEL Pins in site type
+ pins @2 : List(SitePin);
+ lastInput @3 : UInt32; # Index of the last input pin
+ bels @4 : List(BEL);
+ sitePIPs @5 : List(SitePIP);
+ siteWires @6 : List(SiteWire);
+ altSiteTypes @7 : List(SiteTypeIdx);
+ }
+
+ # Maps site pins from alternative site types to the parent primary site pins
+ struct ParentPins {
+ # pins[0] is the mapping of the siteTypeList[altSiteType].pins[0] to the
+ # primary site pin index.
+ #
+ # To determine the tile wire for a alternative site type, first get the
+ # site pin index for primary site, then use primaryPinsToTileWires.
+ pins @0 : List(SitePinIdx);
+ }
+
+ struct SiteTypeInTileType {
+ primaryType @0 : SiteTypeIdx $siteTypeRef();
+
+ # primaryPinsToTileWires[0] is the tile wire that matches
+ # siteTypeList[primaryType].pins[0], etc.
+ primaryPinsToTileWires @1 : List(StringIdx) $stringRef();
+
+ # altPinsToPrimaryPins[0] is the mapping for
+ # siteTypeList[primaryType].altSiteTypes[0], etc.
+ altPinsToPrimaryPins @2 : List(ParentPins);
+ }
+
+ struct TileType {
+ name @0 : StringIdx $stringRef();
+ siteTypes @1 : List(SiteTypeInTileType);
+ wires @2 : List(StringIdx) $stringRef();
+ pips @3 : List(PIP);
+ constants @4 : List(WireConstantSources);
+ }
+
+ #######################################
+ # Placement instance objects
+ #######################################
+ struct BELInverter {
+ nonInvertingPin @0 : BELPinIdx $belPinRef(depth = 2);
+ invertingPin @1 : BELPinIdx $belPinRef(depth = 2);
+ }
+
+ struct BEL {
+ name @0 : StringIdx $stringRef();
+ type @1 : StringIdx $stringRef();
+ pins @2 : List(BELPinIdx) $belPinRef();
+ category @3 : BELCategory; # This would be BELClass/class, but conflicts with Java language
+ union {
+ nonInverting @4 : Void;
+ inverting @5 : BELInverter;
+ }
+ }
+
+ enum BELCategory {
+ logic @0;
+ routing @1;
+ sitePort @2;
+ }
+
+ struct Site {
+ name @0 : StringIdx $stringRef();
+ type @1 : TileTypeSiteTypeIdx; # Index into TileType.siteTypes
+ }
+
+ struct Tile {
+ name @0 : StringIdx $stringRef();
+ type @1 : TileTypeIdx $tileTypeRef();
+ sites @2 : List(Site);
+ row @3 : UInt16;
+ col @4 : UInt16;
+
+ # Field ordinal 5 was deleted.
+ deleted @5 : UInt32;
+
+ # Sub-tiles enable PIPs inside a tile to use different FASM prefices
+ # This is needed for the Nexus, where there can be multiple tiles from a
+ # bitstream perspective at the same (row, col) grid location. PIP.subTile
+ # indexes into this list to get a prefix for FASM purposes.
+ # If sub-tiles are not used; then this list is empty and an implicit
+ # sub-tile index 0 has the same prefix as the tile name.
+ subTilesPrefices @6 : List(StringIdx) $stringRef();
+ }
+
+ ######################################
+ # Intra-site routing resources
+ ######################################
+ struct BELPin {
+ name @0 : StringIdx $stringRef();
+ dir @1 : Dir.Netlist.Direction;
+ bel @2 : StringIdx $stringRef();
+ }
+
+ struct SiteWire {
+ name @0 : StringIdx $stringRef();
+ pins @1 : List(BELPinIdx) $belPinRef();
+ }
+
+ struct SitePIP {
+ inpin @0 : BELPinIdx $belPinRef();
+ outpin @1 : BELPinIdx $belPinRef();
+ # Interconnect delay
+ delay @2 : CornerModel;
+ }
+
+ struct SitePin {
+ name @0 : StringIdx $stringRef();
+ dir @1 : Dir.Netlist.Direction;
+ belpin @2 : BELPinIdx $belPinRef();
+ model : union {
+ noModel @5 : Void;
+ resistance @3 : CornerModel;
+ capacitance @4 : CornerModel;
+ }
+ delay @6 : CornerModel;
+ }
+
+ ######################################
+ # Inter-site routing resources
+ ######################################
+
+ struct Wire {
+ tile @0 : StringIdx $stringRef();
+ wire @1 : StringIdx $stringRef();
+ type @2 : WireTypeIdx $wireTypeRef();
+ }
+
+ enum WireCategory {
+ # general interconnect, usually with many uphill and downhill pips and spanning multiple tiles
+ general @0;
+ # pin/local wires, carry chains, dedicated paths, everything else
+ special @1;
+ # the global clock network
+ global @2;
+ }
+
+ # This is used to distinguish between different types of wires, in order to provide extra hints
+ # during routing, such as the category of wires. It is also intended to be able to describe
+ # complex routing requirements, such as global routing which requires a series of different types
+ # of wires to be used in succession
+ struct WireType {
+ name @0 : StringIdx $stringRef();
+ category @1 : WireCategory;
+ }
+
+ struct Node {
+ wires @0 : List(WireIdx) $wireRef();
+ nodeTiming @1 : NodeTimingIdx $nodeTimingRef();
+ }
+
+ struct PIP {
+ wire0 @0 : WireIDInTileType;
+ wire1 @1 : WireIDInTileType;
+ directional @2 : Bool;
+ buffered20 @3 : Bool;
+ buffered21 @4 : Bool;
+ union {
+ conventional @5 : Void;
+ pseudoCells @6 : List(PseudoCell);
+ }
+ subTile @7 : TileTypeSubTileIdx; # Index into Tile.subTilesPrefices
+ timing @8 : PipTimingIdx $pipTimingRef();
+ }
+
+ struct PseudoCell {
+ bel @0 : StringIdx $stringRef();
+ pins @1 : List(StringIdx) $stringRef();
+ }
+
+ struct WireConstantSources {
+ wires @0 : List(WireIDInTileType);
+ constant @1 : ConstantType;
+ }
+
+ # Table lookup map, for string parameters
+ struct ParameterMapEntry {
+ # If the primitive parameter matches 'from', then the macro
+ # instance parameter will be set to 'to'.
+ from @0 : StringIdx $stringRef();
+ to @1 : StringIdx $stringRef();
+ }
+
+ # This describes how we map a parameter from primitive to its
+ # macro expansion.
+ struct ParameterMapRule {
+ # Name of the parameter in its parent primitive
+ primParam @0 : StringIdx $stringRef();
+ # Name of the cell instance to set the derived parameter on
+ instName @1 : StringIdx $stringRef();
+ # Name of the parameter on the cell instance to set
+ instParam @2 : StringIdx $stringRef();
+ # How to derive the new parameter value
+ union {
+ # Copy the value directly across with no transform applied
+ copyValue @3 : Void;
+ # Apply an arbitrary mapping of bits while deriving the new value.
+ # Bit i of the derived value will be taken from bit bitSlice[i] of the
+ # parent primitive parameter. This way bit ranges; every Nth bit and
+ # permutation can all be represented.
+ bitSlice @4 : List(UInt32);
+ # Use a table lookup to derive a new value for a string parameter.
+ tableLookup @5 : List(ParameterMapEntry);
+ }
+ }
+
+ ######################################
+ # Macro expansion exception map for
+ # primitives that don't expand to a
+ # macro of the same name. This is also
+ # used for conditional matches on
+ # parameter values and parameter
+ # transforms from primitive to
+ # expansion.
+ ######################################
+ struct PrimToMacroExpansion {
+ primName @0 : StringIdx $stringRef();
+ macroName @1 : StringIdx $stringRef();
+ # Optionally, primitive to macro expansions can be conditional on a
+ # parameter match. For example, I/O buffer expansions might be
+ # different between true and pseudo differential IO types. The
+ # expansion is used if **any** of the parameters specified match.
+ union {
+ always @2 : Void;
+ parameters @3 : List(Dir.Netlist.PropertyMap.Entry);
+ }
+ # These rules are used to map parameters from the primitive to the
+ # constituent cell instances for the macro. For example; a LUTRAM
+ # primitive might have its init value split up to the init values
+ # of its constituent LUTs.
+ paramMapping @4 : List(ParameterMapRule);
+ }
+
+ # Cell <-> BEL and Cell pin <-> BEL Pin mapping
+ struct CellBelMapping {
+ cell @0 : StringIdx $stringRef();
+ commonPins @1 : List(CommonCellBelPinMaps);
+ parameterPins @2 : List(ParameterCellBelPinMaps);
+ pinsDelay @3 : List(PinsDelay);
+ }
+
+ # Map one cell pin to one BEL pin.
+ # Note: There may be more than one BEL pin mapped to one cell pin.
+ # If cellPin is "GND" then the BEL pin is tied to ground, and if cellPin
+ # is "VCC" then the BEL pin is tied to Vcc. This is used where BEL pins
+ # must be tied to a constant, but there is no corresponding cell pin.
+ struct CellBelPinEntry {
+ cellPin @0 : StringIdx $stringRef();
+ belPin @1 : StringIdx $stringRef();
+ }
+
+ # Specifies BELs located in a specific site type.
+ struct SiteTypeBelEntry {
+ siteType @0 : StringIdx $stringRef();
+ bels @1 : List(StringIdx) $stringRef();
+ }
+
+ # This is the portion of Cell <-> BEL pin mapping that is common across all
+ # parameter settings for a specific site type and BELs within that site
+ # type.
+ struct CommonCellBelPinMaps {
+ siteTypes @0 : List(SiteTypeBelEntry);
+ pins @1 : List(CellBelPinEntry);
+ }
+
+ # This is the portion of the Cell <-> BEL pin mapping that is parameter
+ # specific.
+ struct ParameterSiteTypeBelEntry {
+ bel @0 : StringIdx $stringRef();
+ siteType @1 : StringIdx $stringRef();
+ parameter @2 : Dir.Netlist.PropertyMap.Entry;
+ }
+
+ struct ParameterCellBelPinMaps {
+ parametersSiteTypes @0 : List(ParameterSiteTypeBelEntry);
+ pins @1 : List(CellBelPinEntry);
+ }
+
+ struct Package {
+ struct PackagePin {
+ packagePin @0 : StringIdx $stringRef();
+ site : union {
+ noSite @1 : Void;
+ site @2 : StringIdx $stringRef();
+ }
+ bel : union {
+ noBel @3 : Void;
+ bel @4 : StringIdx $stringRef();
+ }
+ }
+
+ struct Grade {
+ name @0 : StringIdx $stringRef();
+ speedGrade @1 : StringIdx $stringRef();
+ temperatureGrade @2 : StringIdx $stringRef();
+ }
+
+ name @0 : StringIdx $stringRef();
+ packagePins @1 : List(PackagePin);
+ grades @2 : List(Grade);
+ }
+
+ # Constants
+ enum ConstantType {
+ # Routing a VCC or GND are equal cost.
+ noPreference @0;
+ # Routing a GND has the best cost.
+ gnd @1;
+ # Routing a VCC has the best cost.
+ vcc @2;
+ }
+
+ struct Constants {
+ struct SitePinConstantExceptions {
+ siteType @0 : StringIdx $stringRef();
+ sitePin @1 : StringIdx $stringRef();
+ bestConstant @2 : ConstantType;
+ }
+
+ struct SiteConstantSource {
+ siteType @0 : StringIdx $stringRef();
+ bel @1 : StringIdx $stringRef();
+ belPin @2 : StringIdx $stringRef();
+ constant @3 : ConstantType;
+ }
+
+ struct NodeConstantSource {
+ tile @0 : StringIdx $stringRef();
+ wire @1 : StringIdx $stringRef();
+ constant @2 : ConstantType;
+ }
+
+ # These structures are used to define default constant values for unused
+ # or missing cell pins. For each cell type, we have a list of pins and
+ # what to do with those pins (which will be to tie it to 0 or 1 in most
+ # cases).
+ enum CellPinValue {
+ # leave floating
+ float @0;
+ # connect to ground
+ gnd @1;
+ # connect to vcc
+ vcc @2;
+ }
+
+ struct DefaultCellConnection {
+ # What is the name of this cell pin?
+ name @0 : StringIdx $stringRef();
+ # The default constant value for the pin if missing or disconnected
+ value @1 : CellPinValue;
+ }
+
+ struct DefaultCellConnections {
+ # The type of the cell we're providing a list of defaults for
+ cellType @0 : StringIdx $stringRef();
+ # The list of default cell pin values
+ pins @1 : List(DefaultCellConnection);
+ }
+
+ # When either constant signal can be routed to an input site pin, which
+ # constant should be used by default?
+ #
+ # For example, if a site pin has a local inverter and a cell requires a
+ # constant signal, then either a gnd or vcc could be routed to the site.
+ # The inverter can be used to select which ever constant is needed,
+ # regardless of what constant the cell requires. In some fabrics, routing
+ # a VCC or routing a GND is significantly easier than the other.
+ defaultBestConstant @0 : ConstantType;
+
+ # If there are exceptions to the default best constant, then this list
+ # specifies which site pins use a different constant.
+ bestConstantExceptions @1 : List(SitePinConstantExceptions);
+
+ # List of constants that can be found within the routing graph without
+ # consuming a BEL.
+ #
+ # Tools can always generate a constant source from a LUT BEL type.
+ siteSources @2 : List(SiteConstantSource);
+
+ # Most tied nodes are handled under TileType.constants, however in some
+ # exceptional cases, the tying is inconsistent between tile types.
+ # nodeSources should be used to explicitly list nodes that fall into this
+ # case.
+ nodeSources @3 : List(NodeConstantSource);
+
+ # Name of GND and VCC cells and their pins that are tied to GND/VCC.
+ gndCellType @4 : StringIdx $stringRef();
+ gndCellPin @5 : StringIdx $stringRef();
+
+ vccCellType @6 : StringIdx $stringRef();
+ vccCellPin @7 : StringIdx $stringRef();
+
+ # If the format requires a specific gnd/vcc net name, what name should be
+ # used?
+ gndNetName : union {
+ anyName @8 : Void;
+ name @9 : StringIdx $stringRef();
+ }
+
+ vccNetName : union {
+ anyName @10 : Void;
+ name @11 : StringIdx $stringRef();
+ }
+
+ # How to treat missing/disconnected cell pins
+ defaultCellConns @12 : List(DefaultCellConnections);
+ }
+
+ ######################################
+ # Inverting pins description
+ #
+ # This block describes local site wire
+ # inverters, site routing BELs, and
+ # parameters.
+ ######################################
+ struct CellPinInversionParameter {
+ union {
+ # This inverter cannot be controlled by parameter, only via tool merging
+ # of INV cells or other means.
+ invOnly @0 : Void;
+ # This inverter can be controlled by a parameter.
+ # What parameter value configures this setting?
+ parameter @1 : Dir.Netlist.PropertyMap.Entry;
+ }
+ }
+
+ struct CellPinInversion {
+ # Which cell pin supports a local site inverter?
+ cellPin @0 : StringIdx $stringRef();
+
+ # What parameters are used for the non-inverting case, and how to route
+ # through the inversion routing bels (if any).
+ notInverting @1 : CellPinInversionParameter;
+
+ # What parameters are used for the inverting case, and how to route
+ # through the inversion routing bels (if any).
+ inverting @2 : CellPinInversionParameter;
+ }
+
+ struct CellInversion {
+ # Which cell is being described?
+ cell @0 : StringIdx $stringRef();
+
+ # Which cell have site local inverters?
+ cellPins @1 : List(CellPinInversion);
+ }
+
+ ######################################
+ # Timing modeling
+ #
+ # This section defines the timing model represantation
+ # for the interchange schema.
+ #
+ # Even though there is no strict standard to define how many
+ # corner models need to be defined for a given architecture,
+ # a timing delay model usually includes a "fast" and a
+ # "slow" corner process, each with three delay measures:
+ # - minimum
+ # - typical
+ # - maximum
+ #
+ # The idea is to have a static definition of the corner models
+ # so to standardize the interchange format to use at maximum
+ # two process corner models (fast and slow), with the respective
+ # delay measures. If an architecture does not include one or two
+ # (but not all of three) delay measures, the timing model is still valid.
+ #
+ # There are three main location where timing delays must be defined:
+ # - BEL/Cell pins
+ # - Wires
+ # - PIPs
+ #
+ # * BEL/Cell pins:
+ # These delays can be sequential (associated to a clock pin) or combinatorial
+ # (associated to an input/output pair).
+ # At minimum there are four types of pin delays that need to be considered:
+ # - comb : input to output delay
+ # - setup : associated to the input and a clock pin
+ # - hold : associated to the input and a clock pin
+ # - clock2q : associated to the clock and the output pin
+ #
+ # * Wires:
+ # These delays are associated to wires, or better nodes which are collection
+ # of electrically connected wires.
+ # They are described following the RC (Resistance/Capacitance) modeling.
+ #
+ # * PIPs:
+ # These are delays corresponding to the connections between two wires.
+ #
+ ######################################
+
+ # BEL/Cell pins delays
+ struct PinsDelay {
+ firstPin @0 : PinDelay;
+ secondPin @1 : PinDelay;
+ cornerModel @2 : CornerModel;
+ pinsDelayType @3 : PinsDelayType;
+ site @4 : SiteTypeIdx $siteTypeRef();
+ }
+
+ struct PinDelay {
+ pin @0 : BELPinIdx $belPinRef();
+ union {
+ noClock @1 : Void;
+ clockEdge @2 : ClockEdge;
+ }
+ }
+
+ enum ClockEdge {
+ rise @0;
+ fall @1;
+ }
+
+ enum PinsDelayType {
+ comb @0;
+ setup @1;
+ hold @2;
+ clk2q @3;
+ }
+
+ # Wire (nodes) delays
+ struct NodeTiming {
+ capacitance @0 : CornerModel;
+ resistance @1 : CornerModel;
+ }
+
+ # PIP (switches) delays
+ struct PIPTiming {
+ inputCapacitance @0 : CornerModel;
+ internalCapacitance @1 : CornerModel;
+ internalDelay @2 : CornerModel;
+ outputResistance @3 : CornerModel;
+ outputCapacitance @4 : CornerModel;
+ }
+
+ struct CornerModel {
+ slow : union {
+ noSlow @0 : Void;
+ slow @1 : CornerModelValues;
+ }
+
+ fast : union {
+ noFast @2 : Void;
+ fast @3 : CornerModelValues;
+ }
+ }
+
+ struct CornerModelValues {
+ min : union {
+ noMin @0 : Void;
+ min @1 : Float32;
+ }
+
+ typ : union {
+ noTyp @2 : Void;
+ typ @3 : Float32;
+ }
+
+ max : union {
+ noMax @4 : Void;
+ max @5 : Float32;
+ }
+ }
+
+ ######################################
+ # Placement constraints
+ #
+ # This section defines constraints required for valid placement above and
+ # beyond routing constraints.
+ #
+ # This section has three sections:
+ # - Tags
+ # - Routed tags
+ # - Cell constraints
+ #
+ # The tags sections defines a list of tags that take one of an exclusive set
+ # of states. Tags are attached to an object within the FPGA fabric.
+ # Currently tags can only be attached to either a site type or tile type.
+ # All instances of that site type or tile type will have it's own unique
+ # instance of the tag. In order for the constraints to be considered "met",
+ # each tag instance must be constrained to either 0 or 1 states. In the
+ # event that a tag instance is constrained to 0 states, then that tag
+ # instance value will be the "default" state.
+ #
+ # Routed tags are required to express instances where a cell constraint
+ # relates through a site routing mux to a tag. Routed tags route from a tag
+ # or routed tag to either another routed tag or a cell constraint.
+ #
+ # Cell constraints are the list of constraints that are applied (or removed)
+ # when a cell is placed (or unplaced). The format of the cell constraint
+ # can be read as:
+ # - When a cell of a specific type is (cell/cells field)
+ # - Is placed at (siteTypes and bel field)
+ # - Apply the following constraints (implies/requires field).
+ #
+ # In the case where a cell constraint references a routed tag, then the
+ # constraint also applies to the upstream tag or routed tag.
+ ######################################
+ struct Constraints {
+ struct State {
+ state @0 :Text;
+ description @1 :Text;
+ }
+
+ struct Tag {
+ tag @0 :Text;
+ description @1 :Text;
+ default @2 :Text;
+ union {
+ siteTypes @3 :List(Text);
+ tileTypes @4 :List(Text);
+ }
+ states @5 :List(State);
+ }
+
+ struct RoutedTagPin {
+ pin @0 :Text;
+ tag @1 :Text;
+ }
+
+ struct RoutedTag {
+ routedTag @0 :Text;
+ routingBel @1 :Text;
+ belPins @2 :List(RoutedTagPin);
+ }
+
+ struct RoutedTagPort {
+ tag @0 :Text;
+ port @1 :Text;
+ }
+
+ struct TagPair {
+ union {
+ tag @0 :Text;
+ routedTag @1 :RoutedTagPort;
+ }
+ state @2 :Text;
+ }
+
+ struct TagStates {
+ union {
+ tag @0 :Text;
+ routedTag @1 :RoutedTagPort;
+ }
+ states @2 :List(Text);
+ }
+
+ struct BELLocation {
+ union {
+ anyBel @0 :Void;
+ name @1 :Text;
+ bels @2 :List(Text);
+ }
+ }
+
+ struct ConstraintLocation {
+ siteTypes @0 :List(Text);
+ bel @1 :BELLocation;
+ union {
+ implies @2 :List(TagPair);
+ requires @3 :List(TagStates);
+ }
+ }
+
+ struct CellConstraint {
+ union {
+ cell @0 :Text;
+ cells @1 :List(Text);
+ }
+ locations @2 :List(ConstraintLocation);
+ }
+
+ tags @0 :List(Tag);
+ routedTags @1 :List(RoutedTag);
+ cellConstraints @2 :List(CellConstraint);
+ }
+
+ ######################################
+ # LUT definitions
+ ######################################
+ struct LutDefinitions {
+ struct LutCell {
+ # What cell type is this?
+ cell @0 : Text;
+
+ # What pins are part of the LUT equations?
+ # Pins are listed in LSB first order.
+ inputPins @1 : List(Text);
+
+ # How is the LUT equation stored?
+ equation : union {
+ # Equation is stored as an INIT style parameter.
+ # For a LUT2, INIT is 4 bits.
+ # INIT[0] is output when all pins are 0.
+ # INIT[1] is output when first pin is 1 and all other pins are 0.
+ # INIT[2] is output when second pin is 1 and all other pins are 0.
+ # INIT[3] is output when both pins are 1.
+ initParam @2 : Text;
+ invalid @3 : Void;
+ }
+ }
+
+ struct LutBel {
+ # Name of the BEL that is part of this element
+ name @0 : Text;
+ # What pins are part of this BEL?
+ # Pins are listed in LSB first order.
+ inputPins @1 : List(Text);
+ # What is the output pin of this LUT?
+ outputPin @2 : Text;
+ # What bits within the LutElement does this BEL use?
+ # Bits must be consecutive.
+ lowBit @3 : Int8;
+ highBit @4 : Int8;
+ }
+
+ # Each LUT element in the site should have a width.
+ struct LutElement {
+ width @0 : Int8;
+ # If 2 or more BELs share the same underlying equation shortage,
+ # how are the BELs related?
+ bels @1 : List(LutBel);
+ }
+
+ # How are LUT BELs laid out in a site?
+ struct LutElements {
+ site @0 : Text;
+ luts @1 : List(LutElement);
+ }
+
+ # Which cells are LUT equations?
+ lutCells @0 : List(LutCell);
+
+ # Which sites have LUT BELs?
+ lutElements @1 : List(LutElements);
+ }
+
+ enum ParameterFormat {
+ string @0;
+ # TRUE/FALSE/1/0
+ boolean @1;
+ # 0/1/256
+ integer @2;
+ # 0.0
+ floatingPoint @3;
+ # 1'b0
+ verilogBinary @4;
+ # 8'hF
+ verilogHex @5;
+ # 0b10
+ cBinary @6;
+ # 0xF
+ cHex @7;
+ }
+
+ struct ParameterDefinition {
+ # What is the name of this parameter?
+ name @0 : StringIdx;
+
+ # When a parameter is stored as a string, what presentation should it use?
+ #
+ # If the default is stored as a string, it must be in this presentation.
+ # If a logical netlist stores this parameter as a string, it must be in
+ # this presentation.
+ format @1 : ParameterFormat;
+
+ # Default parameter value
+ #
+ # Note: key should also be set for ease of copy into
+ # LogicalNetlist.
+ default @2 : Dir.Netlist.PropertyMap.Entry;
+ }
+
+ struct CellParameterDefinition {
+ cellType @0 : StringIdx;
+ parameters @1 : List(ParameterDefinition);
+ }
+
+ struct ParameterDefinitions {
+ cells @0 : List(CellParameterDefinition);
+ }
+}
diff --git a/libs/EXTERNAL/libinterchange/interchange/LogicalNetlist.capnp b/libs/EXTERNAL/libinterchange/interchange/LogicalNetlist.capnp
new file mode 100644
index 00000000000..eba0feb2b43
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/interchange/LogicalNetlist.capnp
@@ -0,0 +1,170 @@
+# Copyright 2020-2021 Xilinx, Inc. and Google, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+@0xcb2ccd67aa912967;
+using Java = import "/capnp/java.capnp";
+using Ref = import "References.capnp";
+$Java.package("com.xilinx.rapidwright.interchange");
+$Java.outerClassname("LogicalNetlist");
+
+using Cxx = import "/capnp/c++.capnp";
+$Cxx.namespace("LogicalNetlist");
+
+struct HashSet {
+ type @0 : Ref.ImplementationType = enumerator;
+ hide @1 : Bool = true;
+}
+annotation hashSet(*) :HashSet;
+
+struct StringRef {
+ type @0 :Ref.ReferenceType = rootValue;
+ field @1 :Text = "strList";
+}
+annotation stringRef(*) :StringRef;
+using StringIdx = UInt32;
+
+struct PortRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "portList";
+ depth @2 :Int32 = 1;
+}
+annotation portRef(*) :PortRef;
+using PortIdx = UInt32;
+
+struct CellRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "cellDecls";
+ depth @2 :Int32 = 1;
+}
+annotation cellRef(*) :CellRef;
+using CellIdx = UInt32;
+
+struct InstRef {
+ type @0 :Ref.ReferenceType = parent;
+ field @1 :Text = "instList";
+ depth @2 :Int32 = 1;
+}
+annotation instRef(*) :InstRef;
+using InstIdx = UInt32;
+
+struct Netlist {
+
+ name @0 : Text;
+ propMap @1 : PropertyMap;
+ strList @2 : List(Text) $hashSet();
+ portList @3 : List(Port);
+ cellDecls @4 : List(CellDeclaration);
+ topInst @5 : CellInstance;
+ instList @6 : List(CellInstance);
+ cellList @7 : List(Cell);
+
+ struct CellDeclaration {
+ name @0 : StringIdx $stringRef();
+ propMap @1 : PropertyMap;
+ view @2 : StringIdx $stringRef();
+ lib @3 : StringIdx $stringRef();
+ ports @4 : List(PortIdx) $portRef();
+ }
+
+ struct CellInstance {
+ name @0 : StringIdx $stringRef();
+ propMap @1 : PropertyMap;
+ view @2 : StringIdx $stringRef();
+ cell @3 : CellIdx $cellRef();
+ }
+
+ struct Cell {
+ index @0 : CellIdx $cellRef();
+ insts @1 : List(InstIdx) $instRef();
+ nets @2 : List(Net);
+ }
+
+ struct Net {
+ name @0 : StringIdx $stringRef();
+ propMap @1 : PropertyMap;
+ portInsts @2 : List(PortInstance);
+ }
+
+ struct Port {
+ name @0 : StringIdx $stringRef();
+ dir @1 : Direction;
+ propMap @2 : PropertyMap;
+ union {
+ bit @3 : Void;
+ bus @4 : Bus;
+ }
+ }
+
+ enum Direction {
+ input @0;
+ output @1;
+ inout @2;
+ }
+
+ struct Bus {
+ busStart @0 : UInt32;
+ busEnd @1 : UInt32;
+ }
+
+ struct PortInstance {
+ port @0 : PortIdx $portRef(depth = 3);
+ busIdx : union {
+ singleBit @1 : Void; # Single bit
+ idx @2 : UInt32; # Index within bussed port
+ }
+ union {
+ extPort @3 : Void;
+ inst @4 : InstIdx $instRef(depth = 3);
+ }
+ }
+
+ # Arbitrary length bitstring, encoded into array of uint8.
+ #
+ # width is the width of the bitstring in number of bits.
+ # Data is required to ceil(width/8) elements long.
+ # Bits are stored in LSB order. Example.
+ #
+ # If bits is a bool vector-like, then:
+ #
+ # bits[0] is storage in the LSB of data[0].
+ # bits[8] is storage in the LSB of data[1].
+ #
+ # e.g. bit[0] === (data[0] & (1 << 0)) != 0
+ # e.g. bit[1] === (data[0] & (1 << 1)) != 0
+ # e.g. bit[7] === (data[0] & (1 << 7)) != 0
+ # e.g. bit[8] === (data[1] & (1 << 0)) != 0
+ #
+ struct Bitstring {
+ width @0 : UInt32;
+ data @1 : List(UInt8);
+ }
+
+ struct PropertyMap {
+ entries @0 : List(Entry);
+ struct Entry {
+ key @0 : StringIdx $stringRef();
+ # Some tools may require a particular presentation. textValue is the
+ # most general, and should always be accepted.
+ #
+ # See DeviceResources.ParameterDefinition for potential string
+ # presentations.
+ union {
+ textValue @1 : StringIdx $stringRef();
+ intValue @2 : Int32;
+ boolValue @3 : Bool;
+ bitstringValue @4 : Bitstring;
+ }
+ }
+ }
+}
diff --git a/libs/EXTERNAL/libinterchange/interchange/PhysicalNetlist.capnp b/libs/EXTERNAL/libinterchange/interchange/PhysicalNetlist.capnp
new file mode 100644
index 00000000000..1ac268f09f2
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/interchange/PhysicalNetlist.capnp
@@ -0,0 +1,164 @@
+# Copyright 2020-2021 Xilinx, Inc. and Google, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+@0xcb2ccd67aa912968;
+using Java = import "/capnp/java.capnp";
+$Java.package("com.xilinx.rapidwright.interchange");
+$Java.outerClassname("PhysicalNetlist");
+
+using Cxx = import "/capnp/c++.capnp";
+$Cxx.namespace("PhysicalNetlist");
+
+using Ref = import "References.capnp";
+
+struct StringRef {
+ type @0 :Ref.ReferenceType = rootValue;
+ field @1 :Text = "strList";
+}
+annotation stringRef(*) :StringRef;
+using StringIdx = UInt32;
+
+struct HashSet {
+ type @0 : Ref.ImplementationType = enumerator;
+ hide @1 : Bool = true;
+}
+annotation hashSet(*) :HashSet;
+
+struct PhysNetlist {
+
+ part @0 : Text;
+ placements @1 : List(CellPlacement);
+ physNets @2 : List(PhysNet);
+ physCells @3 : List(PhysCell);
+ strList @4 : List(Text) $hashSet();
+ siteInsts @5 : List(SiteInstance);
+ properties @6 : List(Property);
+ nullNet @7 : PhysNet;
+
+ struct PinMapping {
+ cellPin @0 : StringIdx $stringRef();
+ bel @1 : StringIdx $stringRef();
+ belPin @2 : StringIdx $stringRef();
+ isFixed @3 : Bool;
+ union {
+ multi @4 : Void;
+ otherCell @5 : MultiCellPinMapping;
+ }
+ }
+
+ struct MultiCellPinMapping {
+ multiCell @0 : StringIdx $stringRef();
+ multiType @1 : StringIdx $stringRef();
+ }
+
+ struct CellPlacement {
+ cellName @0 : StringIdx $stringRef();
+ type @1 : StringIdx $stringRef();
+ site @2 : StringIdx $stringRef();
+ bel @3 : StringIdx $stringRef();
+ pinMap @4 : List(PinMapping);
+ otherBels @5 : List(StringIdx) $stringRef();
+ isBelFixed @6 : Bool;
+ isSiteFixed @7 : Bool;
+ altSiteType @8 : StringIdx $stringRef();
+ }
+
+ struct PhysCell {
+ cellName @0 : StringIdx $stringRef();
+ physType @1 : PhysCellType;
+ }
+
+ enum PhysCellType {
+ locked @0;
+ port @1;
+ gnd @2;
+ vcc @3;
+ }
+
+ struct PhysNet {
+ name @0 : StringIdx $stringRef();
+ sources @1 : List(RouteBranch);
+ stubs @2 : List(RouteBranch);
+ type @3 : NetType = signal;
+ }
+
+ enum NetType {
+ signal @0;
+ gnd @1;
+ vcc @2;
+ }
+
+
+ struct RouteBranch {
+ routeSegment : union {
+ belPin @0 : PhysBelPin;
+ sitePin @1 : PhysSitePin;
+ pip @2 : PhysPIP;
+ sitePIP @3 : PhysSitePIP;
+ }
+ branches @4 : List(RouteBranch);
+ }
+
+ struct PhysBel {
+ site @0 : StringIdx $stringRef();
+ bel @1 : StringIdx $stringRef();
+ }
+
+ struct PhysBelPin {
+ site @0 : StringIdx $stringRef();
+ bel @1 : StringIdx $stringRef();
+ pin @2 : StringIdx $stringRef();
+ }
+
+ struct PhysSitePin {
+ site @0 : StringIdx $stringRef();
+ pin @1 : StringIdx $stringRef();
+ }
+
+ struct PhysPIP {
+ tile @0 : StringIdx $stringRef();
+ wire0 @1 : StringIdx $stringRef();
+ wire1 @2 : StringIdx $stringRef();
+ forward @3 : Bool;
+ isFixed @4 : Bool;
+ # In case of a pseudo PIP also the traversed site
+ # needs to be added to the PhysPIP object
+ union {
+ noSite @5: Void;
+ # It is assumed that a pseudo PIP can traverse one
+ # site only
+ site @6: StringIdx $stringRef();
+ }
+ }
+
+ struct PhysSitePIP {
+ site @0 : StringIdx $stringRef();
+ bel @1 : StringIdx $stringRef();
+ pin @2 : StringIdx $stringRef();
+ isFixed @3 : Bool;
+ union {
+ isInverting @4 : Bool;
+ inverts @5 : Void;
+ }
+ }
+
+ struct SiteInstance {
+ site @0 : StringIdx $stringRef();
+ type @1 : StringIdx $stringRef();
+ }
+
+ struct Property {
+ key @0 : StringIdx $stringRef();
+ value @1 : StringIdx $stringRef();
+ }
+}
diff --git a/libs/EXTERNAL/libinterchange/interchange/References.capnp b/libs/EXTERNAL/libinterchange/interchange/References.capnp
new file mode 100644
index 00000000000..8d4a1a9526b
--- /dev/null
+++ b/libs/EXTERNAL/libinterchange/interchange/References.capnp
@@ -0,0 +1,28 @@
+# Copyright 2020-2021 Google, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+@0xa0082c6893796a86;
+using Java = import "/capnp/java.capnp";
+$Java.package("com.xilinx.rapidwright.interchange");
+$Java.outerClassname("References");
+
+enum ReferenceType {
+ root @0;
+ rootValue @1;
+ parent @2;
+}
+
+enum ImplementationType {
+ enumerator @0;
+}
diff --git a/libs/libarchfpga/CMakeLists.txt b/libs/libarchfpga/CMakeLists.txt
index 37a07f0a771..74523097ef9 100644
--- a/libs/libarchfpga/CMakeLists.txt
+++ b/libs/libarchfpga/CMakeLists.txt
@@ -12,16 +12,23 @@ list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
#Create the library
add_library(libarchfpga STATIC
- ${LIB_HEADERS}
- ${LIB_SOURCES})
+ ${LIB_HEADERS}
+ ${LIB_SOURCES}
+)
+
target_include_directories(libarchfpga PUBLIC ${LIB_INCLUDE_DIRS})
+
set_target_properties(libarchfpga PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
#Specify link-time dependancies
target_link_libraries(libarchfpga
libvtrutil
libpugixml
- libpugiutil)
+ libpugiutil
+ libvtrcapnproto
+)
+
+target_compile_definitions(libarchfpga PUBLIC ${INTERCHANGE_SCHEMA_HEADERS})
#Create the test executable
add_executable(read_arch ${EXEC_SOURCES})
diff --git a/libs/libarchfpga/src/physical_types.h b/libs/libarchfpga/src/physical_types.h
index 8b789bfb9d4..4880d5b9989 100644
--- a/libs/libarchfpga/src/physical_types.h
+++ b/libs/libarchfpga/src/physical_types.h
@@ -1732,6 +1732,12 @@ struct t_clock_arch_spec {
std::vector clock_connections_arch;
};
+struct t_lut_cell {
+ std::string name;
+ std::string init_param;
+ std::vector inputs;
+};
+
/* Detailed routing architecture */
struct t_arch {
mutable vtr::string_internment strings;
@@ -1750,11 +1756,23 @@ struct t_arch {
int num_switches;
t_direct_inf* Directs = nullptr;
int num_directs = 0;
+
t_model* models = nullptr;
t_model* model_library = nullptr;
+
t_power_arch* power = nullptr;
t_clock_arch* clocks = nullptr;
+ // Constants
+ std::string gnd_cell;
+ std::string vcc_cell;
+
+ std::string gnd_net = "$__gnd_net";
+ std::string vcc_net = "$__vcc_net";
+
+ // Luts
+ std::vector lut_cells;
+
//The name of the switch used for the input connection block (i.e. to
//connect routing tracks to block pins).
//This should correspond to a switch in Switches
diff --git a/libs/libarchfpga/src/read_common_func.cpp b/libs/libarchfpga/src/read_common_func.cpp
new file mode 100644
index 00000000000..b9436ab7419
--- /dev/null
+++ b/libs/libarchfpga/src/read_common_func.cpp
@@ -0,0 +1,96 @@
+#include
+
+#include "vtr_log.h"
+#include "arch_error.h"
+
+#include "read_common_func.h"
+
+bool check_model_clocks(t_model* model, const char* file, uint32_t line) {
+ //Collect the ports identified as clocks
+ std::set clocks;
+ for (t_model_ports* ports : {model->inputs, model->outputs}) {
+ for (t_model_ports* port = ports; port != nullptr; port = port->next) {
+ if (port->is_clock) {
+ clocks.insert(port->name);
+ }
+ }
+ }
+
+ //Check that any clock references on the ports are to identified clock ports
+ for (t_model_ports* ports : {model->inputs, model->outputs}) {
+ for (t_model_ports* port = ports; port != nullptr; port = port->next) {
+ if (!port->clock.empty() && !clocks.count(port->clock)) {
+ archfpga_throw(file, line,
+ "No matching clock port '%s' on model '%s', required for port '%s'",
+ port->clock.c_str(), model->name, port->name);
+ }
+ }
+ }
+ return true;
+}
+
+bool check_model_combinational_sinks(const t_model* model, const char* file, uint32_t line) {
+ //Outputs should have no combinational sinks
+ for (t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
+ if (port->combinational_sink_ports.size() != 0) {
+ archfpga_throw(file, line,
+ "Model '%s' output port '%s' can not have combinational sink ports",
+ model->name, port->name);
+ }
+ }
+
+ //Record the output ports
+ std::map output_ports;
+ for (t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
+ output_ports.insert({port->name, port});
+ }
+
+ for (t_model_ports* port = model->inputs; port != nullptr; port = port->next) {
+ for (const std::string& sink_port_name : port->combinational_sink_ports) {
+ //Check that the input port combinational sinks are all outputs
+ if (!output_ports.count(sink_port_name)) {
+ archfpga_throw(file, line,
+ "Model '%s' input port '%s' can not be combinationally connected to '%s' (not an output port of the model)",
+ model->name, port->name, sink_port_name.c_str());
+ }
+
+ //Check that any output combinational sinks are not clocks
+ t_model_ports* sink_port = output_ports[sink_port_name];
+ VTR_ASSERT(sink_port);
+ if (sink_port->is_clock) {
+ archfpga_throw(file, line,
+ "Model '%s' output port '%s' can not be both: a clock source (is_clock=\"%d\"),"
+ " and combinationally connected to input port '%s' (acting as a clock buffer).",
+ model->name, sink_port->name, sink_port->is_clock, port->name);
+ }
+ }
+ }
+
+ return true;
+}
+
+void warn_model_missing_timing(const t_model* model, const char* file, uint32_t line) {
+ //Check whether there are missing edges and warn the user
+ std::set comb_connected_outputs;
+ for (t_model_ports* port = model->inputs; port != nullptr; port = port->next) {
+ if (port->clock.empty() //Not sequential
+ && port->combinational_sink_ports.empty() //Doesn't drive any combinational outputs
+ && !port->is_clock //Not an input clock
+ ) {
+ VTR_LOGF_WARN(file, line,
+ "Model '%s' input port '%s' has no timing specification (no clock specified to create a sequential input port, not combinationally connected to any outputs, not a clock input)\n", model->name, port->name);
+ }
+
+ comb_connected_outputs.insert(port->combinational_sink_ports.begin(), port->combinational_sink_ports.end());
+ }
+
+ for (t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
+ if (port->clock.empty() //Not sequential
+ && !comb_connected_outputs.count(port->name) //Not combinationally drivven
+ && !port->is_clock //Not an output clock
+ ) {
+ VTR_LOGF_WARN(file, line,
+ "Model '%s' output port '%s' has no timing specification (no clock specified to create a sequential output port, not combinationally connected to any inputs, not a clock output)\n", model->name, port->name);
+ }
+ }
+}
diff --git a/libs/libarchfpga/src/read_common_func.h b/libs/libarchfpga/src/read_common_func.h
new file mode 100644
index 00000000000..65121ceaa3d
--- /dev/null
+++ b/libs/libarchfpga/src/read_common_func.h
@@ -0,0 +1,19 @@
+#ifndef READ_COMMON_FUNC_H
+#define READ_COMMON_FUNC_H
+
+#include "arch_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* function declarations */
+bool check_model_clocks(t_model*, const char*, uint32_t);
+bool check_model_combinational_sinks(const t_model*, const char*, uint32_t);
+void warn_model_missing_timing(const t_model*, const char*, uint32_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/libarchfpga/src/read_fpga_interchange_arch.cpp b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp
new file mode 100644
index 00000000000..88a9e782df3
--- /dev/null
+++ b/libs/libarchfpga/src/read_fpga_interchange_arch.cpp
@@ -0,0 +1,487 @@
+#include
+#include
+#include
+#include