Merge pull request #1 from antmicro/initial-module-implementation

Initial module implementation
diff --git a/.gitignore/.gitignore b/.gitignore
similarity index 100%
rename from .gitignore/.gitignore
rename to .gitignore
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..d5791ae
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+language: python
+
+matrix:
+  include:
+    - python: 3.5
+      env: TOXENV=py35
+    - python: 3.6
+      env: TOXENV=py36
+    - python: 3.7
+      env: TOXENV=py37
+
+install: pip install tox
+
+script: tox
+
+notifications:
+  email: false
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..db00b77
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,19 @@
+exclude tox.ini
+exclude *.swp
+
+# Include the README
+include *.md
+
+# Include the license file
+include COPYING
+
+include *.txt
+
+recursive-include vtr_xml_utils *.py
+
+# Include the resources files
+recursive-include vtr_xml_utils/resources *.xsl
+recursive-include vtr_xml_utils/resources *.xsd
+
+# Tests
+graft tests
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ab90481
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+lxml
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..8a18954
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,8 @@
+[metadata]
+license_files = COPYING
+
+[bdist_wheel]
+universal=1
+
+[aliases]
+test=pytest
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..da4df12
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,26 @@
+import setuptools
+
+with open("README.md", "r") as fh:
+    long_description = fh.read()
+
+setuptools.setup(
+    name="vtr_xml_utils",
+    version="0.0.1",
+    author="SymbiFlow Authors",
+    author_email="symbiflow@lists.librecores.org",
+    description="A set of Python utilities for working with Verilog to \
+                 Routing XML files",
+    long_description=long_description,
+    long_description_content_type="text/markdown",
+    url="https://github.com/SymbiFlow/vtr-xml-utils",
+    packages=setuptools.find_packages(),
+    install_requires=['lxml'],
+    setup_requires=["pytest-runner"],
+    tests_require=["pytest"],
+    include_package_data=True,
+    classifiers=[
+        "Programming Language :: Python :: 3",
+        "License :: OSI Approved :: ISC License",
+        "Operating System :: OS Independent",
+    ],
+)
diff --git a/tests/convert_and_merge_composable_tests/attribute-cleanup.golden.xml b/tests/convert_and_merge_composable_tests/attribute-cleanup.golden.xml
new file mode 100644
index 0000000..4f0a14d
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/attribute-cleanup.golden.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<xml>
+  <tag b="1" c="123" x="abc"/>
+  <tag c="1" d="123" x="abc"/>
+  <tag>
+    <innertag a1="2" a2="2" b1="abc">Hello</innertag>
+  </tag>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/attribute-cleanup.xml b/tests/convert_and_merge_composable_tests/attribute-cleanup.xml
new file mode 100644
index 0000000..96a33a5
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/attribute-cleanup.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Clean up attributes
+   * Normalize space around attributes on a tag
+   * Sort the attributes by name
+   * Strip xml:base attribute
+  -->
+<xml>
+ <tag b="1"  c="123"  x=' abc' />
+ <tag c="1"  d=" 123 "  x="abc" />
+ <tag>
+  <innertag   a2=" 2 "   b1="abc   "    a1="2">Hello</innertag>
+ </tag>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.golden.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.golden.xml
new file mode 100644
index 0000000..0df25ac
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.golden.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="i0"/>
+    <input name="i1"/>
+    <output name="o"/>
+    <pb_type name="child">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <direct input="COMMON_SLICE.CIN" name="CIN_TO_CARRY0" output="CARRY4_VPR.CIN">
+        <pack_pattern in_port="COMMON_SLICE.CIN" name="CARRYCHAIN" out_port="CARRY4_VPR.CIN"/>
+        <metadata>
+          <meta name="fasm_mux">
+      COMMON_SLICE.CIN = PRECYINIT.CIN
+     </meta>
+        </metadata>
+      </direct>
+      <mux input="COMMON_SLICE.AO5 COMMON_SLICE.AX" name="CARRY_DI0" output="CARRY4_VPR.DI0">
+        <metadata>
+          <meta name="fasm_mux">
+      COMMON_SLICE.AO5 = CARRY4.ACY0
+      COMMON_SLICE.AX = NULL
+     </meta>
+        </metadata>
+        <delay_constant in_port="COMMON_SLICE.AX" max=".105e-9" out_port="CARRY4_VPR.DI0"/>
+      </mux>
+      <mux input="CARRY4_VPR.O3 CARRY4_VPR.CO_FABRIC3 COMMON_SLICE.DO6 COMMON_SLICE.DO5 COMMON_SLICE.DX" name="DFFMUX" output="SLICE_FF.D[3]">
+        <metadata>
+          <meta name="fasm_mux">
+      COMMON_SLICE.DX = DFFMUX.DX
+      COMMON_SLICE.DO5 = DFFMUX.O5
+      COMMON_SLICE.DO6 = DFFMUX.O6
+      CARRY4_VPR.CO_FABRIC3 = DFFMUX.CY
+      CARRY4_VPR.O3 = DFFMUX.XOR
+     </meta>
+        </metadata>
+      </mux>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.xml
new file mode 100644
index 0000000..6590b67
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-existing-fasm-mux.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- Test the special handling around the fasm_mux metadata doesn't destroy
+     existing values.
+     -->
+<xml>
+ <pb_type name="parent">
+  <input name="i0" />
+  <input name="i1" />
+  <output name="o" />
+
+  <pb_type name="child">
+   <input name="i" />
+   <output name="o" />
+  </pb_type>
+
+  <interconnect>
+   <direct name="CIN_TO_CARRY0" input="COMMON_SLICE.CIN" output="CARRY4_VPR.CIN" >
+    <pack_pattern name="CARRYCHAIN"/>
+    <metadata>
+     <meta name="fasm_mux">
+      COMMON_SLICE.CIN = PRECYINIT.CIN
+     </meta>
+    </metadata>
+   </direct>
+   <mux name="DFFMUX"
+    input="CARRY4_VPR.O3 CARRY4_VPR.CO_FABRIC3 COMMON_SLICE.DO6 COMMON_SLICE.DO5 COMMON_SLICE.DX"
+    output="SLICE_FF.D[3]" >
+    <metadata>
+     <meta name="fasm_mux">
+      COMMON_SLICE.DX = DFFMUX.DX
+      COMMON_SLICE.DO5 = DFFMUX.O5
+      COMMON_SLICE.DO6 = DFFMUX.O6
+      CARRY4_VPR.CO_FABRIC3 = DFFMUX.CY
+      CARRY4_VPR.O3 = DFFMUX.XOR
+     </meta>
+    </metadata>
+   </mux>
+   <mux name="CARRY_DI0" input="COMMON_SLICE.AO5 COMMON_SLICE.AX" output="CARRY4_VPR.DI0" >
+    <delay_constant max=".105e-9" in_port="COMMON_SLICE.AX" out_port="CARRY4_VPR.DI0" />
+    <metadata>
+     <meta name="fasm_mux">
+      COMMON_SLICE.AO5 = CARRY4.ACY0
+      COMMON_SLICE.AX = NULL
+     </meta>
+    </metadata>
+   </mux>
+  </interconnect>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.golden.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.golden.xml
new file mode 100644
index 0000000..36509f5
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.golden.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="i0"/>
+    <input name="i1"/>
+    <output name="o"/>
+    <pb_type name="blocka">
+      <input name="i"/>
+      <output name="a"/>
+    </pb_type>
+    <pb_type name="blockb">
+      <input name="i"/>
+      <output name="b"/>
+    </pb_type>
+    <pb_type name="blockc" num_pb="2">
+      <input name="i"/>
+      <output name="c"/>
+    </pb_type>
+    <pb_type name="blocko" num_pb="2">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <mux input="blocka.a blockb.b blockc[0].c blockc[1].c" name="outmux" output="blocko.i">
+        <metadata>
+          <meta name="fasm_mux">
+blocka.a : a1
+blockb.b : b1.l1
+blockc[0].c : c0.l1
+blockc[1].c : c1
+</meta>
+          <meta name="fasm_name">fasm_name</meta>
+        </metadata>
+      </mux>
+      <direct input="blocko.o" name="parent-o" output="parent.o"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.xml
new file mode 100644
index 0000000..4c33420
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux-levels.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!-- Test the special handling around the fasm_mux metadata when using
+     composable interconnects and existing metadata. -->
+<xml>
+ <pb_type name="parent">
+  <input name="i0" />
+  <input name="i1" />
+  <output name="o" />
+
+  <pb_type name="blocka">
+   <input name="i" />
+   <output name="a" />
+  </pb_type>
+  <pb_type name="blockb">
+   <input name="i" />
+   <output name="b" />
+  </pb_type>
+  <pb_type name="blockc" num_pb="2">
+   <input name="i" />
+   <output name="c" />
+  </pb_type>
+  <pb_type name="blocko" num_pb="2">
+   <input name="i" />
+   <output name="o" />
+  </pb_type>
+
+  <interconnect>
+   <mux name="outmux">
+    <port type="input" name="a" from="blocka">
+     <metadata>
+      <meta name="fasm_mux">a1</meta>
+     </metadata>
+    </port>
+    <port type="input" name="b" from="blockb">
+     <metadata>
+      <meta name="fasm_mux">b1.l1</meta>
+     </metadata>
+    </port>
+    <port type="input" name="c" from="blockc[0]">
+     <metadata>
+      <meta name="fasm_mux">c0.l1</meta>
+     </metadata>
+    </port>
+    <port type="input" name="c" from="blockc[1]">
+     <metadata>
+      <meta name="fasm_mux">c1</meta>
+     </metadata>
+    </port>
+    <port type="output" from="blocko" name="i" />
+    <metadata>
+     <meta name="fasm_name">fasm_name</meta>
+    </metadata>
+   </mux>
+   <direct>
+    <port type="input" name="o" from="blocko" />
+    <port type="output" name="o" />
+   </direct>
+  </interconnect>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.golden.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.golden.xml
new file mode 100644
index 0000000..932b881
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.golden.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="i0"/>
+    <input name="i1"/>
+    <output name="o"/>
+    <pb_type name="child">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <mux input="parent.i0 parent.i1" name="mux1" output="child.i">
+        <metadata>
+          <meta name="fasm_mux">
+parent.i0 : a1
+parent.i1 : b1
+</meta>
+          <meta name="fasm_name">fasm_name</meta>
+        </metadata>
+      </mux>
+      <direct input="child.o" name="parent-o" output="parent.o"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.xml
new file mode 100644
index 0000000..741401c
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-fasm-mux.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!-- Test the special handling around the fasm_mux metadata when using
+     composable interconnects. -->
+<xml>
+ <pb_type name="parent">
+  <input name="i0" />
+  <input name="i1" />
+  <output name="o" />
+
+  <pb_type name="child">
+   <input name="i" />
+   <output name="o" />
+  </pb_type>
+
+  <interconnect>
+   <direct>
+    <port type="output" name="o" />
+    <port type="input" from="child" name="o" />
+   </direct>
+   <mux name="mux1">
+    <port type="input" name="i0">
+     <metadata>
+      <meta name="fasm_mux">a1</meta>
+     </metadata>
+    </port>
+    <port type="input" name="i1">
+     <metadata>
+      <meta name="fasm_mux">b1</meta>
+     </metadata>
+    </port>
+    <port type="output" from="child" name="i" />
+    <metadata>
+     <meta name="fasm_name">fasm_name</meta>
+    </metadata>
+   </mux>
+  </interconnect>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.golden.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.golden.xml
new file mode 100644
index 0000000..1c662b7
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.golden.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="ia1"/>
+    <input name="ia2"/>
+    <input name="ia3"/>
+    <output name="o0"/>
+    <output name="o1"/>
+    <pb_type name="childa">
+      <input name="i1"/>
+      <input name="i2"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childb">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <direct input="parent.ia1" name="childa-i1" output="childa.i1">
+        <pack_pattern in_port="parent.ia1" name="A1" out_port="childa.i1"/>
+      </direct>
+      <mux input="parent.ia2 parent.ia3" name="childa-input-i2" output="childa.i2">
+        <pack_pattern in_port="parent.ia2" name="A2" out_port="childa.i2"/>
+        <pack_pattern in_port="parent.ia3" name="A3" out_port="childa.i2"/>
+      </mux>
+      <direct input="childa.o" name="childb-i" output="childb.i"/>
+      <mux input="childa.o childb.o" name="childc-input" output="childc.i"/>
+      <direct input="childa.o" name="parent-o0" output="parent.o0"/>
+      <mux input="childa.o childb.o childc.o" name="output" output="parent.o1"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.xml
new file mode 100644
index 0000000..089159f
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-implicit-parent.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0"?>
+<!--
+  Convert "implicit" parent specification for interconnect tags.
+
+  Convert
+    <interconnect><direct><port type='input' ...><port type='output' ...></direct><YYY../></interconnect>
+  to
+    <interconnect><direct input='...' name='xxx-xxx' output='...'><YYY../></direct></interconnect>
+
+  Convert
+    <interconnect><mux><port type='input' ...><port type='input' ...><port type='output' ...></mux><YYY../></interconnect>
+  to
+    <interconnect><mux input='in1 in2' name='xxx-xxx' output='...'><YYY../></mux></interconnect>
+
+This example below is connected as follows;
+     ┌───────────────────────────────────────────────────────────────────┐
+     │                                                                   │
+     │       ┌────────────┐                                              │
+  ia1│──────>│i1          │                                              │
+     │       │            │                                              │
+     │       │   childa  o│─┬───────────────────────────────────────────>│o0
+  ia2│──>│╲  │            │ │                                            │
+     │   │├─>│i2          │ │                                            │
+  ia3│──>│╱  └────────────┘ │  ┌──────────┐                              │
+     │                      ├─>│i childb o│─┬──>│╲                       │
+     │                      │  └──────────┘ │   ││   ┌──────────┐        │
+     │                      │               │   │├──>│i childc o│──>│╲   │
+     │                      ├──────────────────>││   └──────────┘   ││   │
+     │                      │               │   │╱                  ││   │
+     │                      │               │             ╭────────>│├──>│o1
+     │                      │               ╰─────────────╯         ││   │
+     │                      │                                       ││   │
+     │                      ╰──────────────────────────────────────>│/   │
+     │                                                                   │
+     └───────────────────────────────────────────────────────────────────┘
+  -->
+<xml>
+ <pb_type name="parent">
+  <input name="ia1"/>
+  <input name="ia2"/>
+  <input name="ia3"/>
+  <output name="o0"/>
+  <output name="o1"/>
+  <pb_type name="childa">
+    <input name="i1"/>
+    <input name="i2"/>
+    <output name="o"/>
+  </pb_type>
+  <pb_type name="childb">
+    <input name="i"/>
+    <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+    <input name="i"/>
+    <output name="o"/>
+  </pb_type>
+  <interconnect>
+    <!-- Direct parent -> child -->
+    <direct>
+     <port type="input"                name="ia1" />
+     <port type="output" from="childa" name="i1"  />
+     <pack_pattern name="A1">
+      <port type="input"                name="ia1" />
+      <port type="output" from="childa" name="i1"  />
+     </pack_pattern>
+    </direct>
+    <!-- Mux parent -> child -->
+    <mux name="childa-input-i2">
+     <port type="input"                name="ia2" />
+     <port type="input"                name="ia3" />
+     <port type="output" from="childa" name="i2"  />
+     <pack_pattern name="A2">
+      <port type="input"                name="ia2" />
+      <port type="output" from="childa" name="i2"  />
+     </pack_pattern>
+     <pack_pattern name="A3">
+      <port type="input"                name="ia3" />
+      <port type="output" from="childa" name="i2"  />
+     </pack_pattern>
+    </mux>
+    <!-- Direct parent -> child -->
+    <direct>
+     <port type="input"  from="childa" name="o"   />
+     <port type="output"               name="o0"  />
+    </direct>
+    <!-- Direct child -> child -->
+    <direct>
+     <port type="input"  from="childa" name="o"   />
+     <port type="output" from="childb" name="i"   />
+    </direct>
+    <!-- Mux child -> child -->
+    <mux name="childc-input">
+     <port type="input"  from="childa" name="o"   />
+     <port type="input"  from="childb" name="o"   />
+     <port type="output" from="childc" name="i"   />
+    </mux>
+    <!-- Mux child -> parent -->
+    <mux name="output">
+     <port type="input"  from="childa" name="o"   />
+     <port type="input"  from="childb" name="o"   />
+     <port type="input"  from="childc" name="o"   />
+     <port type="output"               name="o1"  />
+    </mux>
+  </interconnect>
+ </pb_type>
+</xml>
+
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.golden.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.golden.xml
new file mode 100644
index 0000000..5921ecf
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.golden.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="ia1"/>
+    <input name="ia2"/>
+    <input name="ia3"/>
+    <output name="o0"/>
+    <output name="o1"/>
+    <pb_type name="childa">
+      <input name="i1"/>
+      <input name="i2"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childb">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <direct input="parent.ia1" name="childa-i1" output="childa.i1"/>
+      <mux input="parent.ia2 parent.ia3" name="childa-input-i2" output="childa.i2"/>
+      <direct input="childa.o" name="childb-i" output="childb.i"/>
+      <mux input="childa.o childb.o" name="childc-input" output="childc.i"/>
+      <direct input="childa.o" name="parent-o0" output="parent.o0"/>
+      <mux input="childa.o childb.o childc.o" name="output" output="parent.o1"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.xml b/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.xml
new file mode 100644
index 0000000..5d8a28c
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-interconnect-pack_patterns.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--
+  Convert "implicit" parent specification for interconnect tags.
+
+  Convert
+    <interconnect><direct><port type='input' ...><port type='output' ...></direct><YYY../></interconnect>
+  to
+    <interconnect><direct input='...' name='xxx-xxx' output='...'><YYY../></direct></interconnect>
+
+  Convert
+    <interconnect><mux><port type='input' ...><port type='input' ...><port type='output' ...></mux><YYY../></interconnect>
+  to
+    <interconnect><mux input='in1 in2' name='xxx-xxx' output='...'><YYY../></mux></interconnect>
+
+This example below is connected as follows;
+     ┌───────────────────────────────────────────────────────────────────┐
+     │                                                                   │
+     │       ┌────────────┐                                              │
+  ia1│──────>│i1          │                                              │
+     │       │            │                                              │
+     │       │   childa  o│─┬───────────────────────────────────────────>│o0
+  ia2│──>│╲  │            │ │                                            │
+     │   │├─>│i2          │ │                                            │
+  ia3│──>│╱  └────────────┘ │  ┌──────────┐                              │
+     │                      ├─>│i childb o│─┬──>│╲                       │
+     │                      │  └──────────┘ │   ││   ┌──────────┐        │
+     │                      │               │   │├──>│i childc o│──>│╲   │
+     │                      ├──────────────────>││   └──────────┘   ││   │
+     │                      │               │   │╱                  ││   │
+     │                      │               │             ╭────────>│├──>│o1
+     │                      │               ╰─────────────╯         ││   │
+     │                      │                                       ││   │
+     │                      ╰──────────────────────────────────────>│/   │
+     │                                                                   │
+     └───────────────────────────────────────────────────────────────────┘
+  -->
+<xml>
+ <pb_type name="parent">
+  <input name="ia1"/>
+  <input name="ia2"/>
+  <input name="ia3"/>
+  <output name="o0"/>
+  <output name="o1"/>
+  <pb_type name="childa">
+    <input name="i1"/>
+    <input name="i2"/>
+    <output name="o"/>
+  </pb_type>
+  <pb_type name="childb">
+    <input name="i"/>
+    <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+    <input name="i"/>
+    <output name="o"/>
+  </pb_type>
+  <interconnect>
+    <!-- Direct parent -> child -->
+    <direct>
+     <port type="input"                name="ia1" />
+     <port type="output" from="childa" name="i1"  />
+    </direct>
+    <!-- Mux parent -> child -->
+    <mux name="childa-input-i2">
+     <port type="input"                name="ia2" />
+     <port type="input"                name="ia3" />
+     <port type="output" from="childa" name="i2"  />
+    </mux>
+    <!-- Direct parent -> child -->
+    <direct>
+     <port type="input"  from="childa" name="o"   />
+     <port type="output"               name="o0"  />
+    </direct>
+    <!-- Direct child -> child -->
+    <direct>
+     <port type="input"  from="childa" name="o"   />
+     <port type="output" from="childb" name="i"   />
+    </direct>
+    <!-- Mux child -> child -->
+    <mux name="childc-input">
+     <port type="input"  from="childa" name="o"   />
+     <port type="input"  from="childb" name="o"   />
+     <port type="output" from="childc" name="i"   />
+    </mux>
+    <!-- Mux child -> parent -->
+    <mux name="output">
+     <port type="input"  from="childa" name="o"   />
+     <port type="input"  from="childb" name="o"   />
+     <port type="input"  from="childc" name="o"   />
+     <port type="output"               name="o1"  />
+    </mux>
+  </interconnect>
+ </pb_type>
+</xml>
+
diff --git a/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.golden.xml b/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.golden.xml
new file mode 100644
index 0000000..0c90f56
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.golden.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="i" width="2"/>
+    <pinlocations>
+      <loc>
+parent.o
+parent.i[0]
+parent.i[1]
+</loc>
+    </pinlocations>
+    <random>
+      <loc>
+        <port name="o"/>
+      </loc>
+    </random>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.xml b/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.xml
new file mode 100644
index 0000000..e8bc8d2
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-loc-implicit-parent.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+  Convert
+    <loc ...><port ...><port ...></loc>
+  to
+    <loc ...>BLOCK.PORT BLOCK.PORT</loc>
+  -->
+<xml>
+ <pb_type name="parent">
+  <input name="i" width="2" />
+  <pinlocations>
+   <loc>
+    <port name="o" />
+    <port name="i" bit="0" />
+    <port name="i" bit="1" />
+   </loc>
+  </pinlocations>
+  <random>
+   <loc>
+    <port name="o" />
+   </loc>
+  </random>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/composable-pb_type-inner.xml b/tests/convert_and_merge_composable_tests/composable-pb_type-inner.xml
new file mode 100644
index 0000000..6d1d5b5
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-pb_type-inner.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<pb_type name="INNER" other_attribute="r">
+  <blif_model>.subckt random</blif_model>
+  <pb_class>lut</pb_class>
+  <other_tag/>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/composable-pb_type-middle.xml b/tests/convert_and_merge_composable_tests/composable-pb_type-middle.xml
new file mode 100644
index 0000000..d4f1f66
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-pb_type-middle.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<pb_type name="MIDDLE" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <pb_type name="middle_inner" num_pb="1">
+    <xi:include href="composable-pb_type-inner.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/composable-pb_type.golden.xml b/tests/convert_and_merge_composable_tests/composable-pb_type.golden.xml
new file mode 100644
index 0000000..ef10e9d
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-pb_type.golden.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="top" num_pb="1">
+  <pb_type name="middle" num_pb="1">
+    <pb_type blif_model=".subckt random" class="lut" name="middle_inner" num_pb="1">
+      <other_tag/>
+    </pb_type>
+  </pb_type>
+  <pb_type blif_model=".subckt random" class="lut" name="top_inner" num_pb="1">
+    <other_tag/>
+  </pb_type>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/composable-pb_type.xml b/tests/convert_and_merge_composable_tests/composable-pb_type.xml
new file mode 100644
index 0000000..ede3b86
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/composable-pb_type.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" ?>
+<pb_type name="top" num_pb="1" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <pb_type name="top_inner" num_pb="1" >
+    <xi:include href="composable-pb_type-inner.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type name="middle" num_pb="1">
+    <xi:include href="composable-pb_type-middle.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/explicit-port.golden.xml b/tests/convert_and_merge_composable_tests/explicit-port.golden.xml
new file mode 100644
index 0000000..59cdf12
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/explicit-port.golden.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<xml>
+  <port-value-test o="port-name"/>
+  <port-value-test o="port-name[8]"/>
+  <port-value-test o="port-name[8:4]"/>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/explicit-port.xml b/tests/convert_and_merge_composable_tests/explicit-port.xml
new file mode 100644
index 0000000..d078fea
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/explicit-port.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!-- Convert
+   * <port name=XXX>                         to XXX
+   * <port name=XXX bit=Y>                   to XXX[Y]
+   * <port name=XXX bit-msb=M bit-lsb=L>     to XXX[M:L]
+  -->
+<xml>
+  <port-value-test><port name="port-name" /></port-value-test>
+  <port-value-test><port name="port-name" bit="8" /></port-value-test>
+  <port-value-test><port name="port-name" bit-msb="8" bit-lsb="4" /></port-value-test>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/full-test-inner.xml b/tests/convert_and_merge_composable_tests/full-test-inner.xml
new file mode 100644
index 0000000..575ddac
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/full-test-inner.xml
@@ -0,0 +1,16 @@
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="ADDER" num_pb="1">
+  <blif_model>.subckt adder</blif_model>
+  <input name="a" num_pins="1"/>
+  <input name="b" num_pins="1"/>
+  <input name="cin" num_pins="1"/>
+  <output name="cout" num_pins="1"/>
+  <output name="sum" num_pins="1"/>
+  <delay_constant max="300e-12" in_port="a" out_port="cout"/>
+  <delay_constant max="300e-12" in_port="b" out_port="cout"/>
+  <delay_constant max="10e-12" in_port="cin" out_port="cout"/>
+  <delay_constant max="300e-12" in_port="a" out_port="sum"/>
+  <delay_constant max="300e-12" in_port="b" out_port="sum"/>
+  <delay_constant max="300e-12" in_port="cin" out_port="sum"/>
+  <T_setup clock="clk" port="a" value="10e-12"/>
+  <T_clock_to_Q clock="clk" max="10e-12" port="cout"/>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/full-test.golden.xml b/tests/convert_and_merge_composable_tests/full-test.golden.xml
new file mode 100644
index 0000000..dd44989
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/full-test.golden.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="MULTIPLE_INSTANCE" num_pb="1">
+  <input name="a" num_pins="4"/>
+  <input name="b" num_pins="4"/>
+  <input name="c" num_pins="4"/>
+  <input name="cin" num_pins="1"/>
+  <input name="d" num_pins="4"/>
+  <output name="cout" num_pins="1"/>
+  <output name="sum" num_pins="8"/>
+  <pb_type blif_model=".subckt adder" name="comba" num_pb="4">
+    <input name="a" num_pins="1"/>
+    <input name="b" num_pins="1"/>
+    <input name="cin" num_pins="1"/>
+    <output name="cout" num_pins="1"/>
+    <output name="sum" num_pins="1"/>
+    <delay_constant in_port="comba.a" max="300e-12" out_port="comba.cout"/>
+    <delay_constant in_port="comba.b" max="300e-12" out_port="comba.cout"/>
+    <delay_constant in_port="comba.cin" max="10e-12" out_port="comba.cout"/>
+    <delay_constant in_port="comba.a" max="300e-12" out_port="comba.sum"/>
+    <delay_constant in_port="comba.b" max="300e-12" out_port="comba.sum"/>
+    <delay_constant in_port="comba.cin" max="300e-12" out_port="comba.sum"/>
+    <T_setup clock="clk" port="comba.a" value="10e-12"/>
+    <T_clock_to_Q clock="clk" max="10e-12" port="comba.cout"/>
+  </pb_type>
+  <pb_type blif_model=".subckt adder" name="combb" num_pb="4">
+    <input name="a" num_pins="1"/>
+    <input name="b" num_pins="1"/>
+    <input name="cin" num_pins="1"/>
+    <output name="cout" num_pins="1"/>
+    <output name="sum" num_pins="1"/>
+    <delay_constant in_port="combb.a" max="300e-12" out_port="combb.cout"/>
+    <delay_constant in_port="combb.b" max="300e-12" out_port="combb.cout"/>
+    <delay_constant in_port="combb.cin" max="10e-12" out_port="combb.cout"/>
+    <delay_constant in_port="combb.a" max="300e-12" out_port="combb.sum"/>
+    <delay_constant in_port="combb.b" max="300e-12" out_port="combb.sum"/>
+    <delay_constant in_port="combb.cin" max="300e-12" out_port="combb.sum"/>
+    <T_setup clock="clk" port="combb.a" value="10e-12"/>
+    <T_clock_to_Q clock="clk" max="10e-12" port="combb.cout"/>
+  </pb_type>
+  <interconnect>
+    <direct input="combb[3].cout" name="MULTIPLE_INSTANCE-cout" output="MULTIPLE_INSTANCE.cout"/>
+    <direct input="comba[0].sum" name="MULTIPLE_INSTANCE-sum[0]" output="MULTIPLE_INSTANCE.sum[0]"/>
+    <direct input="comba[1].sum" name="MULTIPLE_INSTANCE-sum[1]" output="MULTIPLE_INSTANCE.sum[1]"/>
+    <direct input="comba[2].sum" name="MULTIPLE_INSTANCE-sum[2]" output="MULTIPLE_INSTANCE.sum[2]"/>
+    <direct input="comba[3].sum" name="MULTIPLE_INSTANCE-sum[3]" output="MULTIPLE_INSTANCE.sum[3]"/>
+    <direct input="combb[0].sum" name="MULTIPLE_INSTANCE-sum[4]" output="MULTIPLE_INSTANCE.sum[4]"/>
+    <direct input="combb[1].sum" name="MULTIPLE_INSTANCE-sum[5]" output="MULTIPLE_INSTANCE.sum[5]"/>
+    <direct input="combb[2].sum" name="MULTIPLE_INSTANCE-sum[6]" output="MULTIPLE_INSTANCE.sum[6]"/>
+    <direct input="combb[3].sum" name="MULTIPLE_INSTANCE-sum[7]" output="MULTIPLE_INSTANCE.sum[7]"/>
+    <direct input="MULTIPLE_INSTANCE.a[0]" name="comba[0]-a" output="comba[0].a"/>
+    <direct input="MULTIPLE_INSTANCE.b[0]" name="comba[0]-b" output="comba[0].b"/>
+    <direct input="MULTIPLE_INSTANCE.cin" name="comba[0]-cin" output="comba[0].cin"/>
+    <direct input="MULTIPLE_INSTANCE.a[1]" name="comba[1]-a" output="comba[1].a"/>
+    <direct input="MULTIPLE_INSTANCE.b[1]" name="comba[1]-b" output="comba[1].b"/>
+    <direct input="MULTIPLE_INSTANCE.cin" name="comba[1]-cin" output="comba[1].cin"/>
+    <direct input="MULTIPLE_INSTANCE.a[2]" name="comba[2]-a" output="comba[2].a"/>
+    <direct input="MULTIPLE_INSTANCE.b[2]" name="comba[2]-b" output="comba[2].b"/>
+    <direct input="MULTIPLE_INSTANCE.cin" name="comba[2]-cin" output="comba[2].cin"/>
+    <direct input="MULTIPLE_INSTANCE.a[3]" name="comba[3]-a" output="comba[3].a"/>
+    <direct input="MULTIPLE_INSTANCE.b[3]" name="comba[3]-b" output="comba[3].b"/>
+    <direct input="MULTIPLE_INSTANCE.cin" name="comba[3]-cin" output="comba[3].cin"/>
+    <direct input="MULTIPLE_INSTANCE.c[0]" name="combb[0]-a" output="combb[0].a"/>
+    <direct input="MULTIPLE_INSTANCE.d[0]" name="combb[0]-b" output="combb[0].b"/>
+    <direct input="comba[0].cout" name="combb[0]-cin" output="combb[0].cin">
+      <pack_pattern in_port="comba[0].cout" name="carry-ADDER" out_port="combb[0].cin"/>
+    </direct>
+    <direct input="MULTIPLE_INSTANCE.c[1]" name="combb[1]-a" output="combb[1].a"/>
+    <direct input="MULTIPLE_INSTANCE.d[1]" name="combb[1]-b" output="combb[1].b"/>
+    <direct input="comba[1].cout" name="combb[1]-cin" output="combb[1].cin">
+      <pack_pattern in_port="comba[1].cout" name="carry-ADDER" out_port="combb[1].cin"/>
+    </direct>
+    <direct input="MULTIPLE_INSTANCE.c[2]" name="combb[2]-a" output="combb[2].a"/>
+    <direct input="MULTIPLE_INSTANCE.d[2]" name="combb[2]-b" output="combb[2].b"/>
+    <direct input="comba[2].cout" name="combb[2]-cin" output="combb[2].cin">
+      <pack_pattern in_port="comba[2].cout" name="carry-ADDER" out_port="combb[2].cin"/>
+    </direct>
+    <direct input="MULTIPLE_INSTANCE.c[3]" name="combb[3]-a" output="combb[3].a"/>
+    <direct input="MULTIPLE_INSTANCE.d[3]" name="combb[3]-b" output="combb[3].b"/>
+    <direct input="comba[3].cout" name="combb[3]-cin" output="combb[3].cin">
+      <pack_pattern in_port="comba[3].cout" name="carry-ADDER" out_port="combb[3].cin"/>
+    </direct>
+  </interconnect>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/full-test.xml b/tests/convert_and_merge_composable_tests/full-test.xml
new file mode 100644
index 0000000..c5a31ef
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/full-test.xml
@@ -0,0 +1,166 @@
+<?xml version='1.0' encoding='utf-8'?>
+<pb_type xmlns:xi="http://www.w3.org/2001/XInclude" name="MULTIPLE_INSTANCE" num_pb="1">
+  <input name="a" num_pins="4"/>
+  <input name="b" num_pins="4"/>
+  <input name="c" num_pins="4"/>
+  <input name="cin" num_pins="1"/>
+  <input name="d" num_pins="4"/>
+  <output name="cout" num_pins="1"/>
+  <output name="sum" num_pins="8"/>
+  <pb_type name="comba" num_pb="4">
+    <xi:include href="full-test-inner.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <pb_type name="combb" num_pb="4">
+    <xi:include href="full-test-inner.xml" xpointer="xpointer(pb_type/child::node())"/>
+  </pb_type>
+  <interconnect>
+    <direct>
+      <port name="a[3]" type="input"/>
+      <port from="comba[3]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="b[3]" type="input"/>
+      <port from="comba[3]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port name="cin" type="input"/>
+      <port from="comba[0]" name="cin" type="output"/>
+    </direct>
+    <direct>
+      <port name="cin" type="input"/>
+      <port from="comba[1]" name="cin" type="output"/>
+    </direct>
+    <direct>
+      <port name="cin" type="input"/>
+      <port from="comba[2]" name="cin" type="output"/>
+    </direct>
+    <direct>
+      <port name="cin" type="input"/>
+      <port from="comba[3]" name="cin" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[3]" name="sum" type="input"/>
+      <port name="sum[3]" type="output"/>
+    </direct>
+    <direct>
+      <port name="a[0]" type="input"/>
+      <port from="comba[0]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="b[0]" type="input"/>
+      <port from="comba[0]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[0]" name="sum" type="input"/>
+      <port name="sum[0]" type="output"/>
+    </direct>
+    <direct>
+      <port name="a[1]" type="input"/>
+      <port from="comba[1]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="b[1]" type="input"/>
+      <port from="comba[1]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[1]" name="sum" type="input"/>
+      <port name="sum[1]" type="output"/>
+    </direct>
+    <direct>
+      <port name="a[2]" type="input"/>
+      <port from="comba[2]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="b[2]" type="input"/>
+      <port from="comba[2]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[2]" name="sum" type="input"/>
+      <port name="sum[2]" type="output"/>
+    </direct>
+    <direct>
+      <port name="c[0]" type="input"/>
+      <port from="combb[0]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="d[0]" type="input"/>
+      <port from="combb[0]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[0]" name="cout" type="input"/>
+      <port from="combb[0]" name="cin" type="output"/>
+      <pack_pattern name="ADDER" type="carry">
+        <port from="comba[0]" name="cout" type="input"/>
+        <port from="combb[0]" name="cin" type="output"/>
+      </pack_pattern>
+    </direct>
+    <direct>
+      <port from="combb[0]" name="sum" type="input"/>
+      <port name="sum[4]" type="output"/>
+    </direct>
+    <direct>
+      <port name="c[1]" type="input"/>
+      <port from="combb[1]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="d[1]" type="input"/>
+      <port from="combb[1]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[1]" name="cout" type="input"/>
+      <port from="combb[1]" name="cin" type="output"/>
+      <pack_pattern name="ADDER" type="carry">
+        <port from="comba[1]" name="cout" type="input"/>
+        <port from="combb[1]" name="cin" type="output"/>
+      </pack_pattern>
+    </direct>
+    <direct>
+      <port from="combb[1]" name="sum" type="input"/>
+      <port name="sum[5]" type="output"/>
+    </direct>
+    <direct>
+      <port name="c[2]" type="input"/>
+      <port from="combb[2]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="d[2]" type="input"/>
+      <port from="combb[2]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[2]" name="cout" type="input"/>
+      <port from="combb[2]" name="cin" type="output"/>
+      <pack_pattern name="ADDER" type="carry">
+        <port from="comba[2]" name="cout" type="input"/>
+        <port from="combb[2]" name="cin" type="output"/>
+      </pack_pattern>
+    </direct>
+    <direct>
+      <port from="combb[2]" name="sum" type="input"/>
+      <port name="sum[6]" type="output"/>
+    </direct>
+    <direct>
+      <port name="c[3]" type="input"/>
+      <port from="combb[3]" name="a" type="output"/>
+    </direct>
+    <direct>
+      <port name="d[3]" type="input"/>
+      <port from="combb[3]" name="b" type="output"/>
+    </direct>
+    <direct>
+      <port from="comba[3]" name="cout" type="input"/>
+      <port from="combb[3]" name="cin" type="output"/>
+      <pack_pattern name="ADDER" type="carry">
+        <port from="comba[3]" name="cout" type="input"/>
+        <port from="combb[3]" name="cin" type="output"/>
+      </pack_pattern>
+    </direct>
+    <direct>
+      <port from="combb[3]" name="cout" type="input"/>
+      <port name="cout" type="output"/>
+    </direct>
+    <direct>
+      <port from="combb[3]" name="sum" type="input"/>
+      <port name="sum[7]" type="output"/>
+    </direct>
+  </interconnect>
+</pb_type>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.golden.xml b/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.golden.xml
new file mode 100644
index 0000000..7e983c0
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.golden.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xml>
+  <interconnect>
+    <direct input="LUTFF.FCIN" name="SB_CARRY-CI" output="SB_CARRY.CI">
+      <pack_pattern in_port="LUTFF.FCIN" name="CARRYCHAIN" out_port="SB_CARRY.CI"/>
+    </direct>
+    <direct input="SB_FF.D" name="VPR_FF-D" output="VPR_FF.D">
+      <pack_pattern in_port="SB_FF.D" name="A" out_port="VPR_FF.D"/>
+    </direct>
+  </interconnect>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.xml b/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.xml
new file mode 100644
index 0000000..0a23c15
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-copy-direct-ports.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+  Convert
+     <direct XXXX><pack_pattern name="xxx"/>
+  to
+     <direct XXXX><pack_pattern name="xxx" XXXX/>
+  -->
+<xml>
+	<interconnect>
+  <direct input="SB_FF.D" name="VPR_FF-D" output="VPR_FF.D">
+    <pack_pattern name="A"/>
+  </direct>
+  <direct>
+   <port type="input" from="LUTFF" name="FCIN"/><port type="output" from="SB_CARRY" name="CI"/>
+   <pack_pattern name="CARRYCHAIN"/>
+  </direct>
+ </interconnect>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.golden.xml b/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.golden.xml
new file mode 100644
index 0000000..f93626e
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.golden.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type>
+    <direct>
+      <pack_pattern name="chain-B"/>
+    </direct>
+    <mux>
+      <pack_pattern name="molecule-A">
+        <innertag/>
+      </pack_pattern>
+    </mux>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.xml b/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.xml
new file mode 100644
index 0000000..040ce3a
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-merge-type-into-name.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Convert
+     <pack_pattern name="xxx" type="yyy
+  to
+     <pack_pattern name="yyy-xxx"
+
+  The idea is that eventually VPR will be explicit about chain and molecule
+  patterns.
+
+  -->
+<xml>
+ <pb_type>
+  <direct>
+   <pack_pattern name="B" type="chain" />
+  </direct>
+  <mux>
+   <pack_pattern name="A" type="molecule" >
+    <innertag />
+   </pack_pattern>
+  </mux>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.golden.xml b/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.golden.xml
new file mode 100644
index 0000000..a6d6a3b
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.golden.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type>
+    <input name="in1"/>
+    <input name="in2"/>
+    <output name="o1"/>
+    <output name="o2"/>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.xml b/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.xml
new file mode 100644
index 0000000..da6866a
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/pack_pattern-strip-from-pb_type-ports.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Strip pack_pattern's from input/output tags on pb_types.
+
+  This allows us to add the pack_pattern annotation at the leaf values which
+  don't have an interconnect. It makes it explicit which ports are involved in
+  the chain (and hence won't end up on fabric).
+
+  -->
+<xml>
+ <pb_type>
+  <input name="in1">
+    <pack_pattern />
+  </input>
+  <input name="in2" />
+  <output name="o1" />
+  <output name="o2">
+   <pack_pattern>
+    <innertag />
+   </pack_pattern>
+  </output>
+ </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/preserve-interconnect.golden.xml b/tests/convert_and_merge_composable_tests/preserve-interconnect.golden.xml
new file mode 100644
index 0000000..59dbb7c
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/preserve-interconnect.golden.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type name="parent">
+    <input name="ia1"/>
+    <input name="ia2"/>
+    <input name="ia3"/>
+    <output name="o0"/>
+    <output name="o1"/>
+    <pb_type name="childa">
+      <input name="i1"/>
+      <input name="i2"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childb">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <direct input="parent.ia1" name="childa-i1" output="childa.i1"/>
+      <mux input="parent.ia2 parent.ia3" name="childa-input-i2" output="childa.i2">
+        <pack_pattern in_port="parent.ia2" name="MUX1" output="childa.i2"/>
+        <pack_pattern in_port="parent.ia3" name="MUX2" output="childa.i2"/>
+      </mux>
+      <direct input="childa.o" name="childb-i" output="childb.i"/>
+      <mux input="childa.o childb.o" name="childc-input" output="childc.i"/>
+      <direct input="childa.o" name="parent-o0" output="parent.o0">
+        <pack_pattern in_port="childa.o" name="CARRY" out_port="parent.o0" output="parent.o0"/>
+      </direct>
+      <mux input="childa.o childb.o childc.o" name="output" output="parent.o1"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/convert_and_merge_composable_tests/preserve-interconnect.xml b/tests/convert_and_merge_composable_tests/preserve-interconnect.xml
new file mode 100644
index 0000000..1053784
--- /dev/null
+++ b/tests/convert_and_merge_composable_tests/preserve-interconnect.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!-- Make sure existing interconnect values are preserved. -->
+<xml>
+  <pb_type name="parent">
+    <input name="ia1"/>
+    <input name="ia2"/>
+    <input name="ia3"/>
+    <output name="o0"/>
+    <output name="o1"/>
+    <pb_type name="childa">
+      <input name="i1"/>
+      <input name="i2"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childb">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <pb_type name="childc">
+      <input name="i"/>
+      <output name="o"/>
+    </pb_type>
+    <interconnect>
+      <direct input="parent.ia1" name="childa-i1" output="childa.i1"/>
+      <mux name="childa-input-i2" input="parent.ia2 parent.ia3" output="childa.i2">
+	<pack_pattern name="MUX1" in_port="parent.ia2" output="childa.i2" />
+	<pack_pattern name="MUX2" in_port="parent.ia3" output="childa.i2" />
+      </mux>
+      <direct input="childa.o" name="parent-o0" output="parent.o0">
+	<pack_pattern name="CARRY" in_port="childa.o" output="parent.o0" />
+      </direct>
+      <direct input="childa.o" name="childb-i" output="childb.i"/>
+      <mux name="childc-input" input="childa.o childb.o" output="childc.i"/>
+      <mux name="output" input="childa.o childb.o childc.o" output="parent.o1"/>
+    </interconnect>
+  </pb_type>
+</xml>
diff --git a/tests/test_converting.py b/tests/test_converting.py
new file mode 100644
index 0000000..d6f4e81
--- /dev/null
+++ b/tests/test_converting.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import pytest
+from vtr_xml_utils import convert
+
+
+@pytest.mark.parametrize("testdatafile",
+                         convert.get_filenames_containing("*.golden.xml",
+                                                          __file__))
+def test_converting_and_merging_fpga_architecture(testdatafile):
+    inputname = testdatafile.replace('.golden.xml', '.xml')
+    result = convert.vtr_stylize_xml(inputname)
+    with open(testdatafile) as res:
+        golden = res.read()
+        assert result == golden
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..7fcb0fc
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,28 @@
+[tox]
+envlist = py{27,34,35,36,37}
+
+[testenv]
+setenv =
+    PYTHONPATH={toxinidir}/vtr_xml_utils
+basepython =
+    py35: python3.5
+    py36: python3.6
+    py37: python3.7
+deps =
+    check-manifest
+    # If your project uses README.rst, uncomment the following:
+    # readme_renderer
+    flake8
+    pytest
+    lxml
+commands =
+    check-manifest --ignore tox.ini,tests*
+    # This repository uses a Markdown long_description, so the -r flag to
+    # `setup.py check` is not needed. If your project contains a README.rst,
+    # use `python setup.py check -m -r -s` instead.
+    python setup.py check -m -s
+    flake8 .
+    pytest
+[flake8]
+exclude = .tox,*.egg,build,data
+select = E,W,F
diff --git a/vtr_xml_utils/__init__.py b/vtr_xml_utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vtr_xml_utils/__init__.py
diff --git a/vtr_xml_utils/__main__.py b/vtr_xml_utils/__main__.py
new file mode 100644
index 0000000..7204119
--- /dev/null
+++ b/vtr_xml_utils/__main__.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+from . import convert
+
+import argparse
+import sys
+import os
+
+
+def main(args):
+    if not os.path.isfile(args.input_xml):
+        print("The {} file does not exist or is a directory"
+              .format(args.input_xml))
+        exit(2)
+    elif not os.path.isdir(os.path.dirname(os.path.realpath(args.output))):
+        print("The {} file cannot be created - no such directory"
+              .format(args.output))
+        exit(2)
+    result = convert.vtr_stylize_xml(args.input_xml)
+    with open(args.output, 'w') as out:
+        out.write(result)
+    exit(0)
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(
+        prog='vtr_xml_utils',
+        description="A tool for applying styling changes to the XML files \
+                     for Verilog"
+    )
+    parser.add_argument(
+        "input_xml",
+        metavar="input.xml",
+        type=str,
+        help="The path to file that needs to be stylized with XSL files",
+    )
+    parser.add_argument(
+        "--output",
+        "-o",
+        type=str,
+        default="output.xml",
+        help="Output filename default 'output.xml'"
+    )
+
+    args = parser.parse_args()
+    sys.exit(main(args))
diff --git a/vtr_xml_utils/convert.py b/vtr_xml_utils/convert.py
new file mode 100644
index 0000000..d751651
--- /dev/null
+++ b/vtr_xml_utils/convert.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+import lxml.etree as ET
+import pkg_resources
+import os
+from pathlib import Path
+
+
+def get_filenames_containing(pattern, rootdir):
+    return list(set([str(f) for f in
+                     Path(os.path.dirname(rootdir)).rglob(pattern)]))
+
+
+def vtr_stylize_xml(xmlfilename: str):
+    """Applies a set of stylesheet rules to the input model or PB type XML file.
+    It also includes the XInclude blocks in the final output.
+
+    Parameters
+    ----------
+    xmlfilename : str
+        The path to the input XML file.
+
+    Returns
+    -------
+    str
+        A string containing formatted XML file, with added parts from the
+        XInclude statements in the original XML.
+    """
+    xslresourcesroot = pkg_resources.resource_filename('vtr_xml_utils',
+                                                       'resources')
+    xslresourcesroot += '/'
+    converters = [
+        'identity.xsl',
+        'convert-pb_type-attributes.xsl',
+        'convert-port-tag.xsl',
+        'convert-prefix-port.xsl',
+        'pack-patterns.xsl',
+        'remove-duplicate-models.xsl',
+        'attribute-fixes.xsl',
+        'sort-tags.xsl']
+    parser = ET.XMLParser(remove_comments=True)
+    etdata = ET.parse(xmlfilename, parser)
+    etdata.xinclude()
+    for c in converters:
+        xslt = ET.parse(xslresourcesroot + c, parser)
+        transform = ET.XSLT(xslt)
+        etdata = transform(etdata)
+    return '<?xml version="1.0"?>\n' \
+           + ET.tostring(etdata, pretty_print=True).decode('utf-8')
diff --git a/vtr_xml_utils/resources/attribute-fixes.xsl b/vtr_xml_utils/resources/attribute-fixes.xsl
new file mode 100644
index 0000000..ed4d65b
--- /dev/null
+++ b/vtr_xml_utils/resources/attribute-fixes.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+
+  <!-- Strip xml:base attribute -->
+  <xsl:template match="@xml:base"/>
+
+  <!-- Normalize space around attributes on a tag -->
+  <xsl:template match="@*">
+    <xsl:copy>
+      <xsl:value-of select="normalize-space( . )" />
+    </xsl:copy>
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <!-- Sort the attributes by name -->
+  <xsl:template match="*">
+    <xsl:copy>
+      <xsl:for-each select="@*[name()!='xml:base']">
+        <xsl:sort select="name( . )"/>
+        <xsl:attribute name="{local-name()}"><xsl:value-of select="normalize-space(.)"/></xsl:attribute>
+      </xsl:for-each>
+      <xsl:apply-templates/>
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/convert-pb_type-attributes.xsl b/vtr_xml_utils/resources/convert-pb_type-attributes.xsl
new file mode 100644
index 0000000..0f497ee
--- /dev/null
+++ b/vtr_xml_utils/resources/convert-pb_type-attributes.xsl
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+
+  <xsl:template match="pb_type">
+    <xsl:copy>
+      <!--
+        Convert
+          <pb_type><blif_model>XXX</blif_model></pb_type>
+        to
+          <pb_type blif_model="XXX"></pb_type>
+        -->
+      <xsl:if test="blif_model">
+        <xsl:attribute name="blif_model"><xsl:value-of select="blif_model/text()"/></xsl:attribute>
+      </xsl:if>
+      <!--
+        Convert
+          <pb_type><pb_class>XXX</pb_class></pb_type>
+        to
+          <pb_type class="XXX"></pb_type>
+        -->
+      <xsl:if test="pb_class">
+        <xsl:attribute name="class"><xsl:value-of select="pb_class/text()"/></xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates select="@*"/>
+      <xsl:apply-templates select="node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="pb_type/blif_model"/>
+  <xsl:template match="pb_type/pb_class"/>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/convert-port-tag.xsl b/vtr_xml_utils/resources/convert-port-tag.xsl
new file mode 100644
index 0000000..7ee6dc3
--- /dev/null
+++ b/vtr_xml_utils/resources/convert-port-tag.xsl
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+  <!-- template-function: Allow from attribute which gives you a relative to a given pb_type -->
+  <xsl:template name="from-pb_type">
+    <xsl:choose>
+      <xsl:when test="@from='current'"><xsl:value-of select="ancestor::pb_type[1]/@name"/></xsl:when>
+      <xsl:when test="@from"><xsl:value-of select="@from"/></xsl:when>
+      <xsl:otherwise><xsl:value-of select="ancestor::pb_type[1]/@name"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- template-function: Called to convert
+     * <port name=XXX>                      to XXX
+     * <port name=XXX bit=Y>                to XXX[Y]
+     * <port name=XXX bit_msb=M bit_lsb=L>  to XXX[M:L]
+    -->
+  <xsl:template name="port-value"><xsl:value-of select="@name"/><xsl:choose><xsl:when test="@bit">[<xsl:value-of select="@bit"/>]</xsl:when><xsl:when test="@bit-msb">[<xsl:value-of select="@bit-msb"/>:<xsl:value-of select="@bit-lsb"/>]</xsl:when><xsl:otherwise></xsl:otherwise></xsl:choose></xsl:template>
+
+  <!-- Testing matcher for the port-value template function -->
+  <xsl:template match="port-value-test/port">
+    <xsl:attribute name="o">
+      <xsl:call-template name="port-value"/>
+    </xsl:attribute>
+  </xsl:template>
+
+  <!--
+    Convert
+      <interconnect><xxx><pack_pattern><port type='input' ...><port type='output' ...></pack_pattern></xxx><YYY../></interconnect>
+    to
+      <interconnect><xxx><pack_pattern in_port="XXXX" out_port="XXXX" /></xxx></interconnect>
+    -->
+  <xsl:template match="pack_pattern/port[@type='input']">
+    <xsl:attribute name="in_port"><xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/></xsl:attribute>
+  </xsl:template>
+  <xsl:template match="pack_pattern/port[@type='output']">
+    <xsl:attribute name="out_port"><xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/></xsl:attribute>
+  </xsl:template>
+
+  <!--
+    Convert
+      <interconnect><direct><port type='input' ...><port type='output' ...></direct><YYY../></interconnect>
+    to
+      <interconnect><direct input='...' name='xxx-xxx' output='...'><YYY../></direct></interconnect>
+    -->
+  <xsl:template match="interconnect/direct/port[@type='input']">
+    <xsl:attribute name="input"><xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/></xsl:attribute>
+  </xsl:template>
+  <xsl:template match="interconnect/direct/port[@type='output']">
+    <xsl:attribute name="name"><xsl:call-template name="from-pb_type"/>-<xsl:call-template name="port-value"/></xsl:attribute>
+    <xsl:attribute name="output"><xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/></xsl:attribute>
+  </xsl:template>
+
+  <!--
+    Convert
+      <interconnect><mux><port type='input' ...><port type='input' ...><port type='output' ...></mux><YYY../></interconnect>
+    to
+      <interconnect><mux input='in1 in2' name='xxx-xxx' output='...'><YYY../></mux></interconnect>
+    -->
+  <xsl:template match="interconnect/mux/port"></xsl:template>
+  <xsl:template match="interconnect/mux">
+    <xsl:copy>
+      <xsl:attribute name="input">
+        <xsl:for-each select="port[@type='input']">
+          <xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/>
+          <xsl:if test="position() != last()"><xsl:text> </xsl:text></xsl:if>
+        </xsl:for-each>
+      </xsl:attribute>
+      <xsl:attribute name="output">
+        <xsl:for-each select="port[@type='output']">
+          <xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/>
+        </xsl:for-each>
+      </xsl:attribute>
+      <xsl:for-each select="@*"><xsl:copy /></xsl:for-each>
+      <xsl:if test="metadata">
+        <metadata><xsl:text>&#xa;</xsl:text>
+          <!-- The fasm_mux metadata attribute needs special handling. -->
+          <xsl:if test="*/metadata/meta[@name='fasm_mux']">
+            <meta name="fasm_mux"><xsl:text>&#xa;</xsl:text>
+              <xsl:for-each select="port[@type='input']">
+                <xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/><xsl:text> : </xsl:text><xsl:value-of select="metadata/meta[@name='fasm_mux']" /><xsl:text>&#xa;</xsl:text>
+              </xsl:for-each>
+            </meta>
+          </xsl:if>
+          <xsl:for-each select="metadata">
+            <xsl:apply-templates/>
+          </xsl:for-each>
+        </metadata><xsl:text>&#xa;</xsl:text>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </xsl:copy>
+  </xsl:template>
+  <xsl:template match="interconnect/mux/metadata"></xsl:template>
+
+  <!--
+    Convert
+      <loc ...><port ...><port ...></loc>
+    to
+      <loc ...>BLOCK.PORT BLOCK.PORT</loc>
+    -->
+  <xsl:template match="pinlocations/loc/port">
+    <xsl:text>&#xa;</xsl:text>
+    <xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/>
+  </xsl:template>
+  <xsl:template match="pinlocations/loc/port[last()]">
+    <xsl:text>&#xa;</xsl:text>
+    <xsl:call-template name="from-pb_type"/>.<xsl:call-template name="port-value"/>
+    <xsl:text>&#xa;</xsl:text>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/convert-prefix-port.xsl b/vtr_xml_utils/resources/convert-prefix-port.xsl
new file mode 100644
index 0000000..c7f8867
--- /dev/null
+++ b/vtr_xml_utils/resources/convert-prefix-port.xsl
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+
+  <!-- template-function: Allow from attribute which gives you a relative to a given pb_type -->
+  <xsl:template name="parent-pb_type">
+    <xsl:value-of select="ancestor::pb_type[1]/@name"/>
+  </xsl:template>
+
+  <xsl:template match="pack_pattern/@in_port">
+    <xsl:copy />
+  </xsl:template>
+  <xsl:template match="pack_pattern/@out_port">
+    <xsl:copy />
+  </xsl:template>
+
+  <!-- Prefix in_port / out_port values with the parent name. -->
+  <xsl:template match="@out_port[not(contains(.,'.'))]">
+    <xsl:attribute name="out_port"><xsl:call-template name="parent-pb_type"/>.<xsl:value-of select="."/></xsl:attribute>
+  </xsl:template>
+  <xsl:template match="@in_port[not(contains(.,'.'))]">
+    <xsl:attribute name="in_port"><xsl:call-template name="parent-pb_type"/>.<xsl:value-of select="."/></xsl:attribute>
+  </xsl:template>
+  <xsl:template match="@port[not(contains(.,'.'))]">
+    <xsl:attribute name="port"><xsl:call-template name="parent-pb_type"/>.<xsl:value-of select="."/></xsl:attribute>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/fpga_architecture.xsd b/vtr_xml_utils/resources/fpga_architecture.xsd
new file mode 100644
index 0000000..c5e8908
--- /dev/null
+++ b/vtr_xml_utils/resources/fpga_architecture.xsd
@@ -0,0 +1,874 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2018 Jeppe Johansen

+

+  XML 1.0 Schema for the FPGA architecture description structure developed based on documentation here:

+  http://vtr-verilog-to-routing.readthedocs.io/en/latest/arch/index.html

+-->

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

+

+  <!-- Metadata -->

+  <xs:complexType name="meta">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="name" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="metadata">

+    <xs:sequence>

+      <xs:element name="meta" type="meta" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:simpleType name="stringlist">

+    <xs:list itemType="xs:string"/>

+  </xs:simpleType>

+

+  <xs:simpleType name="intlist">

+    <xs:list itemType="xs:int"/>

+  </xs:simpleType>

+

+  <xs:simpleType name="floatlist">

+    <xs:list itemType="xs:float"/>

+  </xs:simpleType>

+

+  <!-- Actual definitions -->

+  <xs:complexType name="port">

+    <xs:attribute name="name" type="xs:string" use="required" />

+    <xs:attribute name="is_clock" type="xs:boolean" />

+    <xs:attribute name="is_non_clock_global" type="xs:boolean" />

+    <xs:attribute name="clock" type="xs:string" />

+    <xs:attribute name="combinational_sink_ports" type="stringlist" />

+  </xs:complexType>

+

+  <xs:complexType name="port_list">

+    <xs:sequence>

+      <xs:element name="port" type="port" minOccurs="0" maxOccurs="unbounded" />

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="model">

+    <xs:all>

+      <xs:element name="input_ports" type="port_list" minOccurs="0"/>

+      <xs:element name="output_ports" type="port_list" minOccurs="0"/>

+    </xs:all>

+    <xs:attribute name="name" type="xs:string" use="required" />

+  </xs:complexType>

+

+  <xs:complexType name="models">

+    <xs:sequence>

+      <xs:element name="model" type="model" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="fill">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="perimeter">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="corners">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="single">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+    <xs:attribute name="x" type="xs:string" use="required"/>

+    <xs:attribute name="y" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="col">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+    <xs:attribute name="startx" type="xs:string" use="required"/>

+    <xs:attribute name="repeatx" type="xs:string"/>

+    <xs:attribute name="starty" type="xs:string" default="0"/>

+    <xs:attribute name="incry" type="xs:string" default="h"/>

+  </xs:complexType>

+

+  <xs:complexType name="row">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+    <xs:attribute name="starty" type="xs:string" use="required"/>

+

+    <xs:attribute name="repeaty" type="xs:string"/>

+    <xs:attribute name="startx" type="xs:string" default="0"/>

+    <xs:attribute name="incrx" type="xs:string" default="w"/>

+  </xs:complexType>

+

+  <xs:complexType name="region">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="priority" type="xs:int" use="required"/>

+

+    <xs:attribute name="startx" type="xs:string" default="0"/>

+    <xs:attribute name="endx" type="xs:string" default="W-1"/>

+    <xs:attribute name="incrx" type="xs:string" default="w"/>

+    <xs:attribute name="repeatx" type="xs:string"/>

+

+    <xs:attribute name="starty" type="xs:string" default="0"/>

+    <xs:attribute name="endy" type="xs:string" default="H-1"/>

+    <xs:attribute name="incry" type="xs:string" default="h"/>

+    <xs:attribute name="repeaty" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="layout_info">

+    <xs:choice minOccurs="0" maxOccurs="unbounded">

+      <xs:element name="fill" type="fill"/>

+      <xs:element name="perimeter" type="perimeter"/>

+      <xs:element name="corners" type="corners"/>

+      <xs:element name="single" type="single"/>

+      <xs:element name="col" type="col"/>

+      <xs:element name="row" type="row"/>

+      <xs:element name="region" type="region"/>

+    </xs:choice>

+  </xs:complexType>

+

+  <xs:complexType name="auto_layout">

+    <xs:complexContent>

+      <xs:extension base="layout_info">

+        <xs:attribute name="aspect_ratio" type="xs:float" default="1.0" />

+      </xs:extension>

+    </xs:complexContent>

+  </xs:complexType>

+

+  <xs:complexType name="fixed_layout">

+    <xs:complexContent>

+      <xs:extension base="layout_info">

+        <xs:attribute name="name" type="xs:string" use="required" />

+        <xs:attribute name="width" type="xs:int" use="required" />

+        <xs:attribute name="height" type="xs:int" use="required" />

+      </xs:extension>

+    </xs:complexContent>

+  </xs:complexType>

+

+  <xs:complexType name="layout">

+    <xs:choice minOccurs="1">

+      <xs:element name="auto_layout" type="auto_layout" maxOccurs="1"/>

+      <xs:element name="fixed_layout" type="fixed_layout" maxOccurs="unbounded"/>

+    </xs:choice>

+  </xs:complexType>

+

+  <xs:simpleType name="switch_block_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="wilton"/>

+      <xs:enumeration value="subset"/>

+      <xs:enumeration value="universal"/>

+      <xs:enumeration value="custom"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="fc_type_enum">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="frac"/>

+      <xs:enumeration value="abs"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="chan_distribution">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="gaussian"/>

+      <xs:enumeration value="uniform"/>

+      <xs:enumeration value="pulse"/>

+      <xs:enumeration value="delta"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="chan_dist">

+    <xs:attribute name="distr" type="chan_distribution" use="required"/>

+    <xs:attribute name="peak" type="xs:float" use="required"/>

+    <xs:attribute name="width" type="xs:float"/>

+    <xs:attribute name="xpeak" type="xs:float"/>

+    <xs:attribute name="dc" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="chan_width_distr">

+    <xs:all>

+      <xs:element name="x" type="chan_dist"/>

+      <xs:element name="y" type="chan_dist"/>

+    </xs:all>

+  </xs:complexType>

+

+  <xs:complexType name="device">

+    <xs:all>

+      <xs:element name="sizing">

+        <xs:complexType>

+          <xs:attribute name="R_minW_nmos" type="xs:float" use="required"/>

+          <xs:attribute name="R_minW_pmos" type="xs:float" use="required"/>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="connection_block">

+        <xs:complexType>

+          <xs:attribute name="input_switch_name" type="xs:string" use="required"/>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="area">

+        <xs:complexType>

+          <xs:attribute name="grid_logic_tile_area" type="xs:float" use="required"/>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="switch_block">

+        <xs:complexType>

+          <xs:attribute name="type" type="switch_block_type" use="required"/>

+          <xs:attribute name="fs" type="xs:int" default="3"/>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="chan_width_distr" minOccurs="0" type="chan_width_distr"/>

+      <xs:element name="default_fc" minOccurs="0">

+        <xs:complexType>

+          <xs:attribute name="in_type" type="fc_type_enum" use="required"/>

+          <xs:attribute name="in_val" type="xs:float" use="required"/>

+          <xs:attribute name="out_type" type="fc_type_enum" use="required"/>

+          <xs:attribute name="out_val" type="xs:float" use="required"/>

+        </xs:complexType>

+      </xs:element>

+    </xs:all>

+  </xs:complexType>

+

+  <xs:simpleType name="switch_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="mux"/>

+      <xs:enumeration value="tristate"/>

+      <xs:enumeration value="pass_gate"/>

+      <xs:enumeration value="short"/>

+      <xs:enumeration value="buffer"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="buf_size">

+    <xs:union memberTypes="xs:float">

+      <xs:simpleType>

+        <xs:restriction base="xs:NMTOKEN">

+          <xs:enumeration value="auto"/>

+        </xs:restriction>

+      </xs:simpleType>

+    </xs:union>

+  </xs:simpleType>

+

+  <xs:complexType name="switch">

+    <xs:sequence>

+      <xs:element name="Tdel" minOccurs="0" maxOccurs="unbounded">

+        <xs:complexType>

+          <xs:attribute name="num_inputs" type="xs:int" use="required"/>

+          <xs:attribute name="delay" type="xs:float" use="required"/>

+        </xs:complexType>

+      </xs:element>

+    </xs:sequence>

+    <xs:attribute name="type" type="switch_type" use="required"/>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="R" type="xs:float" use="required"/>

+    <xs:attribute name="Cin" type="xs:float" use="required"/>

+    <xs:attribute name="Cinternal" type="xs:float"/>

+    <xs:attribute name="Cout" type="xs:float"/>

+    <xs:attribute name="Tdel" type="xs:float"/>

+    <xs:attribute name="buf_size" type="buf_size" default="auto"/>

+    <xs:attribute name="mux_trans_size" type="xs:float"/>

+    <xs:attribute name="power_buf_size" type="xs:int"/>

+  </xs:complexType>

+

+  <xs:complexType name="switchlist">

+    <xs:sequence>

+      <xs:element name="switch" type="switch" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:simpleType name="pb_type_class">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="lut"/>

+      <xs:enumeration value="flipflop"/>

+      <xs:enumeration value="memory"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="input_equivalent">

+     <xs:restriction base="xs:string">

+      <xs:enumeration value="none"/>

+      <xs:enumeration value="full"/>

+      <xs:enumeration value="instance"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="input_port">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="equivalent" type="input_equivalent" default="none"/>

+    <xs:attribute name="num_pins" type="xs:int" use="required"/>

+    <xs:attribute name="is_non_clock_global" type="xs:boolean"/>

+    <xs:attribute name="port_class" type="xs:string" />

+  </xs:complexType>

+

+  <xs:simpleType name="output_equivalent">

+     <xs:restriction base="xs:string">

+      <xs:enumeration value="none"/>

+      <xs:enumeration value="full"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="output_port">

+    <xs:sequence>

+      <xs:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="equivalent" type="output_equivalent" default="none"/>

+    <xs:attribute name="num_pins" type="xs:int" use="required"/>

+    <xs:attribute name="port_class" type="xs:string" />

+  </xs:complexType>

+

+  <xs:simpleType name="clock_equivalent">

+     <xs:restriction base="xs:string">

+      <xs:enumeration value="none"/>

+      <xs:enumeration value="full"/>

+      <xs:enumeration value="instance"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="clock_port">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="equivalent" type="clock_equivalent" default="none"/>

+    <xs:attribute name="num_pins" type="xs:int" use="required"/>

+    <xs:attribute name="port_class" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:simpleType name="delay_matrix_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="min"/>

+      <xs:enumeration value="max"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="delay_matrix">

+    <xs:simpleContent>

+      <xs:extension base="floatlist">

+        <xs:attribute name="type" type="delay_matrix_type" use="required"/>

+        <xs:attribute name="in_port" type="xs:string" use="required"/>

+        <xs:attribute name="out_port" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="T_timing_minmax">

+    <xs:attribute name="max" type="xs:float"/>

+    <xs:attribute name="min" type="xs:float"/>

+    <xs:attribute name="in_port" type="xs:string" use="required"/>

+    <xs:attribute name="out_port" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="T_timing">

+    <xs:attribute name="value" type="xs:float" use="required"/>

+    <xs:attribute name="port" type="xs:string" use="required"/>

+    <xs:attribute name="clock" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="T_clock_timing">

+    <xs:attribute name="max" type="xs:float"/>

+    <xs:attribute name="min" type="xs:float"/>

+    <xs:attribute name="port" type="xs:string" use="required"/>

+    <xs:attribute name="clock" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:group name="timing_group">

+    <xs:choice>

+      <xs:element name="delay_constant" type="T_timing_minmax"/>

+      <xs:element name="delay_matrix" type="delay_matrix"/>

+    </xs:choice>

+  </xs:group>

+

+  <xs:group name="timing_group_pbtype">

+    <xs:choice>

+      <xs:group ref="timing_group" minOccurs="0"/>

+      <xs:element name="T_setup" type="T_timing"/>

+      <xs:element name="T_hold" type="T_timing"/>

+      <xs:element name="T_clock_to_Q" type="T_clock_timing"/>

+    </xs:choice>

+  </xs:group>

+

+  <xs:complexType name="interconnect_type">

+    <xs:choice maxOccurs="unbounded">

+      <xs:element name="pack_pattern" type="pack_pattern"/>

+      <xs:group ref="timing_group" minOccurs="0"/>

+      <xs:element name="metadata" type="metadata"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="input" type="stringlist" use="required"/>

+    <xs:attribute name="output" type="stringlist" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="pack_pattern">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="in_port" type="stringlist" use="required"/>

+    <xs:attribute name="out_port" type="stringlist" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="interconnect">

+    <xs:choice maxOccurs="unbounded">

+      <xs:element name="complete" type="interconnect_type"/>

+      <xs:element name="direct" type="interconnect_type"/>

+      <xs:element name="mux" type="interconnect_type"/>

+    </xs:choice>

+  </xs:complexType>

+

+  <xs:simpleType name="power_estimation_method">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="specify-size"/>

+      <xs:enumeration value="auto-size"/>

+      <xs:enumeration value="pin-toggle"/>

+      <xs:enumeration value="C-internal"/>

+      <xs:enumeration value="absolute"/>

+      <xs:enumeration value="ignore"/>

+      <xs:enumeration value="sum-of-children"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="power_dynamic_power">

+    <xs:attribute name="power_per_instance" type="xs:float"/>

+    <xs:attribute name="C_internal" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="power_static_power">

+    <xs:attribute name="power_per_instance" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="power_port">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="energy_per_toggle" type="xs:float" use="required"/>

+    <xs:attribute name="scaled_by_static_prob" type="xs:string"/>

+    <xs:attribute name="scaled_by_static_prob_n" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_local_interconnect">

+    <xs:attribute name="C_wire" type="xs:float" default="0"/>

+    <xs:attribute name="factor" type="xs:float" default="0.5"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_buffers">

+    <xs:attribute name="logical_effort_factor" type="xs:float" default="4"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_ff_size">

+    <xs:attribute name="FF_size" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_LUT_transistor_size">

+    <xs:attribute name="LUT_transistor_size" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_mux_transistor_size">

+    <xs:attribute name="mux_transistor_size" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="gpower_sram">

+    <xs:attribute name="transistors_per_bit" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="power">

+    <xs:choice minOccurs="0" maxOccurs="unbounded">

+      <xs:element name="dynamic_power" type="power_dynamic_power"/>

+      <xs:element name="static_power" type="power_static_power"/>

+      <xs:element name="port" type="power_port"/>

+    </xs:choice>

+    <xs:attribute name="method" type="power_estimation_method" default="auto-size"/>

+  </xs:complexType>

+

+<!-- Global power is very schema-unfriendly. Default values are assigned if the elements

+	holding the attributes aren't present. There is no way for XSD to know that.

+	It could be much better if the <power> tag had all these settings as its own attributes. -->

+  <xs:complexType name="global_power">

+    <xs:choice maxOccurs="unbounded">

+      <xs:element name="local_interconnect" type="gpower_local_interconnect"/>

+      <xs:element name="buffers" type="gpower_buffers"/>

+      <xs:element name="sram" type="gpower_sram"/>

+      <xs:element name="mux_transistor_size" type="gpower_mux_transistor_size"/>

+      <xs:element name="FF_size" type="gpower_ff_size"/>

+      <xs:element name="LUT_transistor_size" type="gpower_LUT_transistor_size"/>

+    </xs:choice>

+    <xs:attribute name="method" type="power_estimation_method" default="auto-size"/>

+  </xs:complexType>

+

+  <xs:simpleType name="pinlocations_pattern">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="spread"/>

+      <xs:enumeration value="spread_inputs_perimeter_outputs"/>

+      <xs:enumeration value="perimeter"/>

+      <xs:enumeration value="custom"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="loc_side">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="left"/>

+      <xs:enumeration value="right"/>

+      <xs:enumeration value="bottom"/>

+      <xs:enumeration value="top"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="loc">

+    <xs:simpleContent>

+      <xs:extension base="stringlist">

+        <xs:attribute name="side" type="loc_side" use="required"/>

+        <xs:attribute name="xoffset" type="xs:int" default="0"/>

+        <xs:attribute name="yoffset" type="xs:int" default="0"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="pinlocations">

+    <xs:sequence>

+      <xs:element name="loc" type="loc" maxOccurs="unbounded" minOccurs="0" />

+    </xs:sequence>

+    <xs:attribute name="pattern" type="pinlocations_pattern"/>

+  </xs:complexType>

+

+  <xs:simpleType name="switchblock_locations_pattern">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="external_full_internal_straight"/>

+      <xs:enumeration value="all"/>

+      <xs:enumeration value="external"/>

+      <xs:enumeration value="internal"/>

+      <xs:enumeration value="none"/>

+      <xs:enumeration value="custom"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="sb_loc_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="full"/>

+      <xs:enumeration value="straight"/>

+      <xs:enumeration value="turns"/>

+      <xs:enumeration value="none"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="sb_loc">

+    <xs:attribute name="type" type="sb_loc_type" default="full"/>

+    <xs:attribute name="xoffset" type="xs:int" default="0"/>

+    <xs:attribute name="yoffset" type="xs:int" default="0"/>

+    <xs:attribute name="switch_override" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="switchblock_locations">

+    <xs:sequence>

+      <xs:element name="sb_loc" type="sb_loc" maxOccurs="unbounded" minOccurs="0" />

+    </xs:sequence>

+    <xs:attribute name="pattern" type="switchblock_locations_pattern" default="external_full_internal_straight"/>

+    <xs:attribute name="internal_switch" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="fc">

+    <xs:sequence>

+      <xs:element name="fc_override" minOccurs="0" maxOccurs="unbounded">

+        <xs:complexType>

+          <xs:attribute name="fc_type" type="fc_type_enum" use="required"/>

+          <xs:attribute name="fc_val" type="xs:float" use="required"/>

+          <xs:attribute name="port_name" type="xs:string"/>

+          <xs:attribute name="segment_name" type="xs:string"/>

+        </xs:complexType>

+      </xs:element>

+    </xs:sequence>

+    <xs:attribute name="in_type" type="fc_type_enum" use="required"/>

+    <xs:attribute name="in_val" type="xs:float" use="required"/>

+    <xs:attribute name="out_type" type="fc_type_enum" use="required"/>

+    <xs:attribute name="out_val" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="mode">

+    <xs:choice maxOccurs="unbounded" minOccurs="0">

+      <xs:element name="pb_type" type="pb_type"/>

+      <xs:element name="interconnect" type="interconnect"/>

+      <xs:element name="pinlocations" type="pinlocations"/>

+      <xs:element name="switchblock_locations" type="switchblock_locations"/>

+      <xs:element name="metadata" type="metadata"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="map">

+    <xs:attribute name="from" type="xs:string" use="required"/>

+    <xs:attribute name="to" type="xs:string" use="required"/>

+    <xs:attribute name="num_pins" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="tile_mode">

+    <xs:choice maxOccurs="unbounded" minOccurs="0">

+      <xs:element name="map" type="map"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="equivalent_sites">

+    <xs:choice maxOccurs="unbounded" minOccurs="0">

+      <xs:element name="site"/>

+    </xs:choice>

+  </xs:complexType>

+

+  <xs:complexType name="tile">

+    <xs:choice maxOccurs="unbounded" minOccurs="0">

+      <xs:element name="input" type="input_port"/>

+      <xs:element name="output" type="output_port"/>

+      <xs:element name="clock" type="clock_port"/>

+      <xs:element name="equivalent_sites" type="equivalent_sites"/>

+      <xs:element name="pinlocations" type="pinlocations"/>

+      <xs:element name="fc" type="fc"/>

+      <xs:element name="switchblock_locations" type="switchblock_locations"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="capacity" type="xs:int"/>

+    <xs:attribute name="width" type="xs:int"/>

+    <xs:attribute name="height" type="xs:int"/>

+    <xs:attribute name="area" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="tiles">

+    <xs:sequence>

+      <xs:element name="tile" type="tile" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="pb_type">

+    <xs:choice maxOccurs="unbounded" minOccurs="0">

+      <xs:element name="pb_type" type="pb_type"/>

+      <xs:element name="input" type="input_port"/>

+      <xs:element name="output" type="output_port"/>

+      <xs:element name="clock" type="clock_port"/>

+      <xs:element name="metadata" type="metadata"/>

+      <xs:element name="mode" type="mode"/>

+      <xs:element name="interconnect" type="interconnect"/>

+      <xs:group ref="timing_group_pbtype"/>

+      <xs:element name="power" type="power"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="num_pb" type="xs:int"/>

+    <xs:attribute name="blif_model" type="xs:string"/>

+    <xs:attribute name="class" type="pb_type_class"/>

+  </xs:complexType>

+

+  <xs:simpleType name="segment_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="bidir"/>

+      <xs:enumeration value="unidir"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="segment_length">

+    <xs:union memberTypes="xs:nonNegativeInteger">

+      <xs:simpleType>

+        <xs:restriction base="xs:NMTOKEN">

+          <xs:enumeration value="longline"/>

+        </xs:restriction>

+      </xs:simpleType>

+    </xs:union>

+  </xs:simpleType>

+

+  <xs:complexType name="complexblocklist">

+    <xs:sequence>

+      <xs:element name="pb_type" type="pb_type" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="segment_block">

+    <xs:simpleContent>

+      <xs:extension base="intlist">

+        <xs:attribute name="type" type="xs:string" use="required" fixed="pattern"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="segment_mux">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="segment_wire_switch">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+  </xs:complexType>

+

+<!-- Segment type relies on the "type" attr to determine the required children.

+	XSD 1.1 provides an <alternative> tag to check some attribute and choose a sub-type.

+	Segment wire_switches and opin_switches correspond to switch names.

+	XSD 1.1 also provides a <keyref> tag which asserts a correspondence to some value

+	at an XPath.

+	Being able to use these tags requires some work in the parser generator.

+	Therefore, for now, further validation about segments should be implemented in the postprocessor. -->

+  <xs:complexType name="segment">

+      <xs:choice maxOccurs="unbounded">

+        <xs:element name="sb" type="segment_block"/>

+        <xs:element name="cb" type="segment_block"/>

+        <xs:element name="mux" type="segment_mux"/>

+        <xs:element name="wire_switch" type="segment_wire_switch"/>

+        <xs:element name="opin_switch" type="segment_wire_switch"/>

+    </xs:choice>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="length" type="segment_length" use="required"/>

+    <xs:attribute name="type" type="segment_type" use="required"/>

+    <xs:attribute name="freq" type="xs:float" use="required"/>

+    <xs:attribute name="Rmetal" type="xs:float" use="required"/>

+    <xs:attribute name="Cmetal" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="segmentlist">

+    <xs:sequence>

+      <xs:element name="segment" type="segment" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="direct">

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="from_pin" type="xs:string" use="required"/>

+    <xs:attribute name="to_pin" type="xs:string" use="required"/>

+    <xs:attribute name="x_offset" type="xs:int" use="required"/>

+    <xs:attribute name="y_offset" type="xs:int" use="required"/>

+    <xs:attribute name="z_offset" type="xs:int" use="required"/>

+    <xs:attribute name="switch_name" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="directlist">

+    <xs:sequence>

+      <xs:element name="direct" type="direct" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:simpleType name="switchblock_location_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="EVERYWHERE"/>

+      <xs:enumeration value="PERIMETER"/>

+      <xs:enumeration value="CORNER"/>

+      <xs:enumeration value="FRINGE"/>

+      <xs:enumeration value="CORE"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="switchblock_location">

+    <xs:attribute name="type" type="switchblock_location_type" use="required"/>

+  </xs:complexType>

+

+  <xs:simpleType name="switchblock_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="bidir"/>

+      <xs:enumeration value="unidir"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="func_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="lt"/>

+      <xs:enumeration value="lr"/>

+      <xs:enumeration value="lb"/>

+      <xs:enumeration value="tr"/>

+      <xs:enumeration value="tb"/>

+      <xs:enumeration value="tl"/>

+      <xs:enumeration value="rb"/>

+      <xs:enumeration value="rl"/>

+      <xs:enumeration value="rt"/>

+      <xs:enumeration value="bl"/>

+      <xs:enumeration value="bt"/>

+      <xs:enumeration value="br"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="switchblock_func">

+    <xs:sequence>

+      <xs:element name="func" maxOccurs="unbounded">

+        <xs:complexType>

+          <xs:attribute name="type" type="func_type" use="required" />

+          <xs:attribute name="formula" type="xs:string" use="required" />

+        </xs:complexType>

+      </xs:element>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="wireconn_connection">

+    <xs:attribute name="type" type="xs:string" use="required"/>

+    <xs:attribute name="switchpoint" type="xs:string" use="required"/>

+  </xs:complexType>

+

+<!-- It would be better to change the string or int lists here to use whitespace as a

+	delimiter instead of commas, so they can be expressed as <xs:list>s instead of

+	just strings. -->

+  <xs:complexType name="wireconn">

+    <xs:choice minOccurs="0" maxOccurs="unbounded">

+      <xs:element name="from" type="wireconn_connection" maxOccurs="unbounded"/>

+      <xs:element name="to" type="wireconn_connection" maxOccurs="unbounded"/>

+    </xs:choice>

+    <xs:attribute name="num_conns_type" type="xs:string" use="required"/>

+    <xs:attribute name="from_type" type="xs:string"/>

+    <xs:attribute name="to_type" type="xs:string"/>

+    <xs:attribute name="from_switchpoint" type="xs:string"/>

+    <xs:attribute name="to_switchpoint" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="switchblock">

+    <xs:sequence>

+      <xs:element name="switchblock_location" type="switchblock_location"/>

+      <xs:element name="switchfuncs" type="switchblock_func"/>

+      <xs:element name="wireconn" type="wireconn" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="type" type="switchblock_type" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="switchblocklist">

+    <xs:sequence>

+      <xs:element name="switchblock" type="switchblock" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="clock">

+    <xs:attribute name="C_wire" type="xs:float"/>

+    <xs:attribute name="C_wire_per_m" type="xs:float"/>

+    <xs:attribute name="buffer_size" type="buf_size"/>

+  </xs:complexType>

+

+  <xs:complexType name="clocks">

+    <xs:sequence>

+      <xs:element name="clock" type="clock" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:element name="architecture">

+    <xs:complexType>

+      <xs:all>

+        <xs:element name="models" type="models"/>

+        <xs:element name="layout" type="layout"/>

+        <xs:element name="device" type="device"/>

+        <xs:element name="switchlist" type="switchlist"/>

+        <xs:element name="segmentlist" type="segmentlist"/>

+        <xs:element name="switchblocklist" type="switchblocklist" minOccurs="0"/>

+        <xs:element name="complexblocklist" type="complexblocklist"/>

+        <xs:element name="directlist" type="directlist" minOccurs="0"/>

+        <xs:element name="power" type="global_power" minOccurs="0"/>

+        <xs:element name="clocks" type="clocks" minOccurs="0"/>

+        <xs:element name="tiles" type="tiles" minOccurs="0"/>

+      </xs:all>

+    </xs:complexType>

+  </xs:element>

+

+</xs:schema>

diff --git a/vtr_xml_utils/resources/identity.xsl b/vtr_xml_utils/resources/identity.xsl
new file mode 100644
index 0000000..23ff094
--- /dev/null
+++ b/vtr_xml_utils/resources/identity.xsl
@@ -0,0 +1,30 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="xml" indent="yes"/>
+  <xsl:strip-space elements="*"/>
+
+  <xsl:template match="@*">
+    <xsl:copy/>
+  </xsl:template>
+
+  <xsl:template match="*">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <xsl:apply-templates/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="text()|processing-instruction()">
+    <xsl:copy>
+      <xsl:apply-templates select="text()|processing-instruction()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:param name="strip_comments" select="''" />
+  <xsl:template match="comment()">
+    <xsl:choose>
+      <xsl:when test="$strip_comments"></xsl:when>
+      <xsl:otherwise><xsl:copy /></xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/pack-patterns.xsl b/vtr_xml_utils/resources/pack-patterns.xsl
new file mode 100644
index 0000000..0203b5c
--- /dev/null
+++ b/vtr_xml_utils/resources/pack-patterns.xsl
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+
+  <!--
+    Strip pack_pattern's from input/output tags on pb_types.
+    -->
+  <xsl:template match="pb_type/input/pack_pattern"/>
+  <xsl:template match="pb_type/output/pack_pattern"/>
+
+  <!--
+    Convert
+       <pack_pattern name="xxx" type="yyy"
+    to
+       <pack_pattern name="yyy-xxx"
+    -->
+  <xsl:template match="pack_pattern/@type"/>
+  <xsl:template match="pack_pattern[@type]/@name">
+    <xsl:attribute name="name">
+      <xsl:value-of select="../@type"/>-<xsl:value-of select="../@name"/>
+    </xsl:attribute>
+  </xsl:template>
+  <xsl:template match="pack_pattern[not(@type)]/@name">
+    <xsl:copy />
+  </xsl:template>
+  <xsl:template match="pack_pattern/*">
+    <xsl:copy />
+  </xsl:template>
+
+  <!--
+    Convert
+      <interconnect><direct input="IN" output="OUT"><pack_pattern name="PACK"/></direct></interconnect>
+    to
+      <interconnect><direct input="IN" output="OUT"><pack_pattern name="PACK" in_port="IN" out_port="OUT"/></direct></interconnect>
+    -->
+  <xsl:template match="direct[@input and @output]/pack_pattern">
+    <xsl:copy>
+      <xsl:attribute name="in_port"><xsl:value-of select="../@input" /></xsl:attribute>
+      <xsl:attribute name="out_port"><xsl:value-of select="../@output" /></xsl:attribute>
+      <xsl:apply-templates select="@*"></xsl:apply-templates>
+    </xsl:copy>
+    <xsl:apply-templates/>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/packed_netlist.xsd b/vtr_xml_utils/resources/packed_netlist.xsd
new file mode 100644
index 0000000..90631af
--- /dev/null
+++ b/vtr_xml_utils/resources/packed_netlist.xsd
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2018 Jeppe Johansen

+

+  XML 1.0 Schema for packed netlist format developed based on documentation here:

+  http://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#packed-netlist-format-net

+-->

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

+

+  <xs:complexType name="named_value">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="name" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="port">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="name" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="port_rotation_map">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="name" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="port_group" mixed="true">

+    <xs:sequence>

+      <xs:element name="port" type="port" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="block">

+    <xs:choice minOccurs="0" maxOccurs="unbounded">

+      <xs:element name="inputs">

+        <xs:complexType  mixed="true">

+          <xs:choice minOccurs="0" maxOccurs="unbounded">

+            <xs:element name="port" type="port"/>

+            <xs:element name="port_rotation_map" type="port_rotation_map"/>

+          </xs:choice>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="outputs" type="port_group"/>

+      <xs:element name="clocks" type="port_group"/>

+      <xs:element name="attributes">

+        <xs:complexType>

+          <xs:sequence>

+            <xs:element name="attribute" type="named_value" minOccurs="0" maxOccurs="unbounded"/>

+          </xs:sequence>

+        </xs:complexType>

+      </xs:element>

+      <xs:element name="parameters">

+        <xs:complexType>

+          <xs:sequence>

+            <xs:element name="parameter" type="named_value" minOccurs="0" maxOccurs="unbounded"/>

+          </xs:sequence>

+        </xs:complexType>

+      </xs:element>

+

+      <xs:element name="block" type="block"/>

+    </xs:choice>

+

+    <xs:attribute name="name" type="xs:string"/>

+    <xs:attribute name="instance" type="xs:string"/>

+    <xs:attribute name="mode" type="xs:string"/>

+    <xs:attribute name="architecture_id" type="xs:string"/>

+    <xs:attribute name="atom_netlist_id" type="xs:string"/>

+    <xs:attribute name="pb_type_num_modes" type="xs:integer"/>

+  </xs:complexType>

+

+  <xs:element name="block" type="block"/>

+

+</xs:schema>

diff --git a/vtr_xml_utils/resources/remove-duplicate-models.xsl b/vtr_xml_utils/resources/remove-duplicate-models.xsl
new file mode 100644
index 0000000..3166d53
--- /dev/null
+++ b/vtr_xml_utils/resources/remove-duplicate-models.xsl
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:include href="identity.xsl" />
+
+  <!-- Remove duplicate model nodes -->
+  <xsl:key name="model-by-name" match="model" use="@name" />
+  <xsl:template match="models">
+    <models>
+      <xsl:for-each select="model[count(. | key('model-by-name', @name)[1]) = 1]">
+        <xsl:copy>
+          <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
+          <xsl:apply-templates/>
+        </xsl:copy>
+      </xsl:for-each>
+    </models>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/vtr_xml_utils/resources/routing_resource.xsd b/vtr_xml_utils/resources/routing_resource.xsd
new file mode 100644
index 0000000..f890844
--- /dev/null
+++ b/vtr_xml_utils/resources/routing_resource.xsd
@@ -0,0 +1,280 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2018 Jeppe Johansen

+

+  XML 1.0 Schema for rr_graph structure developed based on documentation here:

+  http://vtr-verilog-to-routing.readthedocs.io/en/latest/vpr/file_formats.html#routing-resource-graph-file-format-xml

+-->

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

+

+  <xs:complexType name="channel">

+    <xs:attribute name="chan_width_max" type="xs:int" use="required"/>

+    <xs:attribute name="x_min" type="xs:int" use="required"/>

+    <xs:attribute name="y_min" type="xs:int" use="required"/>

+    <xs:attribute name="x_max" type="xs:int" use="required"/>

+    <xs:attribute name="y_max" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="x_list">

+    <xs:attribute name="index" type="xs:unsignedInt" use="required"/>

+    <xs:attribute name="info" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="y_list">

+    <xs:attribute name="index" type="xs:unsignedInt" use="required"/>

+    <xs:attribute name="info" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:simpleType name="switch_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="mux"/>

+      <xs:enumeration value="tristate"/>

+      <xs:enumeration value="pass_gate"/>

+      <xs:enumeration value="short"/>

+      <xs:enumeration value="buffer"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="timing">

+    <xs:attribute name="R" type="xs:float"/>

+    <xs:attribute name="Cin" type="xs:float"/>

+    <xs:attribute name="Cinternal" type="xs:float"/>

+    <xs:attribute name="Cout" type="xs:float"/>

+    <xs:attribute name="Tdel" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="sizing">

+    <xs:attribute name="mux_trans_size" type="xs:float" use="required"/>

+    <xs:attribute name="buf_size" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="switch">

+    <xs:all>

+      <xs:element name="timing" type="timing" minOccurs="0"/>

+      <xs:element name="sizing" type="sizing"/>

+    </xs:all>

+    <xs:attribute name="id" type="xs:int" use="required"/>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="type" type="switch_type"/>

+  </xs:complexType>

+

+  <xs:complexType name="segment_timing">

+    <xs:attribute name="R_per_meter" type="xs:float"/>

+    <xs:attribute name="C_per_meter" type="xs:float"/>

+  </xs:complexType>

+

+  <xs:complexType name="segment">

+    <xs:all>

+      <xs:element name="timing" type="segment_timing" minOccurs="0"/>

+    </xs:all>

+    <xs:attribute name="id" type="xs:int" use="required"/>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="pin">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="ptc" type="xs:int" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="pin_class">

+    <xs:sequence>

+      <xs:element name="pin" type="pin" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="type" type="pin_type" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="meta">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="name" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>

+

+  <xs:complexType name="metadata">

+    <xs:sequence>

+      <xs:element name="meta" type="meta" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="block_type">

+    <xs:sequence>

+      <xs:element name="pin_class" type="pin_class" minOccurs="0" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="id" type="xs:int" use="required"/>

+    <xs:attribute name="name" type="xs:string" use="required"/>

+    <xs:attribute name="width" type="xs:int" use="required"/>

+    <xs:attribute name="height" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:simpleType name="pin_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="OPEN"/>

+      <xs:enumeration value="OUTPUT"/>

+      <xs:enumeration value="INPUT"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="grid_loc">

+    <xs:attribute name="x" type="xs:int" use="required"/>

+    <xs:attribute name="y" type="xs:int" use="required"/>

+    <xs:attribute name="block_type_id" type="xs:int" use="required"/>

+    <xs:attribute name="width_offset" type="xs:int" use="required"/>

+    <xs:attribute name="height_offset" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:simpleType name="node_type">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="CHANX"/>

+      <xs:enumeration value="CHANY"/>

+      <xs:enumeration value="SOURCE"/>

+      <xs:enumeration value="SINK"/>

+      <xs:enumeration value="OPIN"/>

+      <xs:enumeration value="IPIN"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="node_direction">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="INC_DIR"/>

+      <xs:enumeration value="DEC_DIR"/>

+      <xs:enumeration value="BI_DIR"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:simpleType name="loc_side">

+    <xs:restriction base="xs:string">

+      <xs:enumeration value="LEFT"/>

+      <xs:enumeration value="RIGHT"/>

+      <xs:enumeration value="TOP"/>

+      <xs:enumeration value="BOTTOM"/>

+    </xs:restriction>

+  </xs:simpleType>

+

+  <xs:complexType name="node_loc">

+    <xs:attribute name="xlow" type="xs:int" use="required"/>

+    <xs:attribute name="ylow" type="xs:int" use="required"/>

+    <xs:attribute name="xhigh" type="xs:int" use="required"/>

+    <xs:attribute name="yhigh" type="xs:int" use="required"/>

+    <xs:attribute name="side" type="loc_side"/>

+    <xs:attribute name="ptc" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="node_timing">

+    <xs:attribute name="R" type="xs:float" use="required"/>

+    <xs:attribute name="C" type="xs:float" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="node_segment">

+    <xs:attribute name="segment_id" type="xs:int" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="node">

+    <xs:all>

+      <xs:element name="loc" type="node_loc"/>

+      <xs:element name="timing" type="node_timing" minOccurs="0"/>

+      <xs:element name="segment" type="node_segment" minOccurs="0"/>

+      <xs:element name="metadata" type="metadata" minOccurs="0"/>

+    </xs:all>

+    <xs:attribute name="id" type="xs:unsignedInt" use="required"/>

+    <xs:attribute name="type" type="node_type" use="required"/>

+    <xs:attribute name="direction" type="node_direction"/>

+    <xs:attribute name="capacity" type="xs:unsignedInt" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="edge">

+    <xs:all>

+      <xs:element name="metadata" type="metadata" minOccurs="0"/>

+    </xs:all>

+    <xs:attribute name="id" type="xs:unsignedInt"/>

+    <xs:attribute name="src_node" type="xs:unsignedInt" use="required"/>

+    <xs:attribute name="sink_node" type="xs:unsignedInt" use="required"/>

+    <xs:attribute name="switch_id" type="xs:unsignedInt" use="required"/>

+  </xs:complexType>

+

+  <xs:complexType name="channels">

+    <xs:sequence>

+      <xs:element name="channel" type="channel"/>

+      <xs:element name="x_list" type="x_list" maxOccurs="unbounded"/>

+      <xs:element name="y_list" type="y_list" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="switches">

+    <xs:sequence>

+      <xs:element name="switch" type="switch" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="segments">

+    <xs:sequence>

+      <xs:element name="segment" type="segment" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="block_types">

+    <xs:sequence>

+      <xs:element name="block_type" type="block_type" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="grid_locs">

+    <xs:sequence>

+      <xs:element name="grid_loc" type="grid_loc" maxOccurs="unbounded"/>

+    </xs:sequence>

+  </xs:complexType>

+

+  <xs:complexType name="rr_nodes">

+    <xs:choice maxOccurs="unbounded">

+      <xs:element name="node" type="node"/>

+    </xs:choice>

+  </xs:complexType>

+  

+  <xs:complexType name="rr_edges">

+    <xs:choice maxOccurs="unbounded">

+      <xs:element name="edge" type="edge"/>

+    </xs:choice>

+  </xs:complexType>

+

+  <xs:complexType name="bin_nodes">

+    <xs:attribute name="file" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="connection_box">

+    <xs:attribute name="id" type="xs:int"/>

+    <xs:attribute name="name" type="xs:string"/>

+  </xs:complexType>

+

+  <xs:complexType name="connection_boxes">

+    <xs:sequence>

+      <xs:element name="connection_box" type="connection_box" maxOccurs="unbounded"/>

+    </xs:sequence>

+    <xs:attribute name="x_dim" type="xs:int"/>

+    <xs:attribute name="y_dim" type="xs:int"/>

+    <xs:attribute name="num_boxes" type="xs:int"/>

+  </xs:complexType>

+

+  <xs:element name="rr_graph">

+    <xs:complexType>

+      <xs:all>

+        <xs:element name="binary_nodes_and_edges" type="bin_nodes" minOccurs="0"/>

+        <xs:element name="connection_boxes" type="connection_boxes" minOccurs="0"/>

+        <xs:element name="channels" type="channels"/>

+        <xs:element name="switches" type="switches"/>

+        <xs:element name="segments" type="segments"/>

+        <xs:element name="block_types" type="block_types"/>

+        <xs:element name="grid" type="grid_locs"/>

+        <xs:element name="rr_nodes" type="rr_nodes"/>

+        <xs:element name="rr_edges" type="rr_edges"/>

+      </xs:all>

+

+      <xs:attribute name="tool_name" type="xs:string"/>

+      <xs:attribute name="tool_version" type="xs:string"/>

+      <xs:attribute name="tool_comment" type="xs:string"/>

+    </xs:complexType>

+  </xs:element>

+

+</xs:schema>

diff --git a/vtr_xml_utils/resources/sort-tags.xsl b/vtr_xml_utils/resources/sort-tags.xsl
new file mode 100644
index 0000000..3507bd8
--- /dev/null
+++ b/vtr_xml_utils/resources/sort-tags.xsl
@@ -0,0 +1,35 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:include href="identity.xsl" />
+
+ <!-- Sort <pb_type><clock> by "name" attribute -->
+ <!-- Sort <pb_type><input> by "name" attribute -->
+ <!-- Sort <pb_type><output> by "name" attribute -->
+ <xsl:template match="pb_type">
+  <xsl:copy>
+   <xsl:apply-templates select="@*"/>
+   <xsl:apply-templates select="clock">
+    <xsl:sort select="@name" order="ascending"/>
+   </xsl:apply-templates>
+   <xsl:apply-templates select="input">
+    <xsl:sort select="@name" order="ascending"/>
+   </xsl:apply-templates>
+   <xsl:apply-templates select="output">
+    <xsl:sort select="@name" order="ascending"/>
+   </xsl:apply-templates>
+   <xsl:apply-templates select="pb_type">
+    <xsl:sort select="@name" order="ascending"/>
+   </xsl:apply-templates>
+   <xsl:apply-templates select="*[not(self::clock or self::input or self::output or self::pb_type)]"/>
+  </xsl:copy>
+ </xsl:template>
+ <!-- Sort <interconnect><XXX> tags by output - direct first then muxes, finally input -->
+ <xsl:template match="interconnect">
+  <xsl:copy>
+   <xsl:apply-templates>
+    <xsl:sort select="concat(@output, name(), @input)" order="ascending"/>
+   </xsl:apply-templates>
+  </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>