xml: Improve xslt transform.

Continue to improve the `xmlsort.xsl` script to be a tool which merges a
modified FPGA architecture.

Currently it also converts a more composable format and converts it into
the format that VtR accepts. Eventually the hope is that upstream VtR
will accept this composable format in the future. See;
https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/272

Signed-off-by: Tim 'mithro' Ansell <me@mith.ro>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..3786bf8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,9 @@
+include("xsl_tests.cmake")
+xsl_golden_test(NAME "attribute-cleanup")
+xsl_golden_test(NAME "composable-interconnect-fasm-mux-levels")
+xsl_golden_test(NAME "composable-interconnect-fasm-mux")
+xsl_golden_test(NAME "composable-interconnect-implicit-parent")
+xsl_golden_test(NAME "composable-loc-implicit-parent")
+xsl_golden_test(NAME "pack_pattern-merge-type-into-name")
+xsl_golden_test(NAME "pack_pattern-strip-from-pb_type-ports")
+xsl_golden_test(NAME "xml-explicit-port")
diff --git a/attribute-cleanup.golden.xml b/attribute-cleanup.golden.xml
new file mode 100644
index 0000000..4f0a14d
--- /dev/null
+++ b/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/attribute-cleanup.xml b/attribute-cleanup.xml
new file mode 100644
index 0000000..decb65e
--- /dev/null
+++ b/attribute-cleanup.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   a2="2"   b1="abc"    a1="2">Hello</innertag>
+ </tag>
+</xml>
diff --git a/composable-interconnect-fasm-mux-levels.golden.xml b/composable-interconnect-fasm-mux-levels.golden.xml
new file mode 100644
index 0000000..064a7be
--- /dev/null
+++ b/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 name="outmux" input="blocka.a blockb.b blockc[0].c blockc[1].c" output="blocko.i">
+        <metadata>
+          <meta name="fasm_mux">
+            blocka.a : a1
+            blockb.b : b1
+            blockc[0].c : c0
+            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/composable-interconnect-fasm-mux-levels.xml b/composable-interconnect-fasm-mux-levels.xml
new file mode 100644
index 0000000..b3f7424
--- /dev/null
+++ b/composable-interconnect-fasm-mux-levels.xml
@@ -0,0 +1,58 @@
+<?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 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</meta>
+     </metadata>
+    </port>
+    <port type="input" name="c" from="blockc[0]">
+     <metadata>
+      <meta name="fasm_mux">c0</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/composable-interconnect-fasm-mux.xml b/composable-interconnect-fasm-mux.xml
new file mode 100644
index 0000000..a52d9a7
--- /dev/null
+++ b/composable-interconnect-fasm-mux.xml
@@ -0,0 +1,36 @@
+<?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>
+    <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/composable-interconnect-implicit-parent.xml b/composable-interconnect-implicit-parent.xml
new file mode 100644
index 0000000..a9ab9f5
--- /dev/null
+++ b/composable-interconnect-implicit-parent.xml
@@ -0,0 +1,25 @@
+<?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>
+    <port type="output" name="o" />
+    <port type="input" from="child" name="o" />
+   </direct>
+   <mux name="mux1">
+    <port type="input" name="i0" />
+    <port type="input" name="i1" />
+    <port type="output" from="child" name="i" />
+   </mux>
+ </interconnect>
+ </pb_type>
+</xml>
diff --git a/composable-loc-implicit-parent.xml b/composable-loc-implicit-parent.xml
new file mode 100644
index 0000000..d148f05
--- /dev/null
+++ b/composable-loc-implicit-parent.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xml>
+ <pb_type name="parent">
+  <input name="i" width="2" />
+  <loc>
+   <port name="o" />
+   <port name="i" bit="0" />
+   <port name="i" bit="1" />
+  </loc>
+ </pb_type>
+</xml>
diff --git a/pack_pattern-merge-type-into-name.golden.xml b/pack_pattern-merge-type-into-name.golden.xml
new file mode 100644
index 0000000..34abd19
--- /dev/null
+++ b/pack_pattern-merge-type-into-name.golden.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<xml>
+  <pb_type>
+    <direct>
+      <pack_pattern name="carry-B"/>
+    </direct>
+    <mux>
+      <pack_pattern name="pack-A">
+        <innertag/>
+      </pack_pattern>
+    </mux>
+  </pb_type>
+</xml>
diff --git a/pack_pattern-merge-type-into-name.xml b/pack_pattern-merge-type-into-name.xml
new file mode 100644
index 0000000..ae102ea
--- /dev/null
+++ b/pack_pattern-merge-type-into-name.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<xml>
+ <pb_type>
+  <direct>
+   <pack_pattern name="B" type="carry" />
+  </direct>
+  <mux>
+   <pack_pattern name="A" type="pack">
+    <innertag />
+   </pack_pattern>
+  </mux>
+ </pb_type>
+</xml>
diff --git a/pack_pattern-strip-from-pb_type-ports.golden.xml b/pack_pattern-strip-from-pb_type-ports.golden.xml
new file mode 100644
index 0000000..a6d6a3b
--- /dev/null
+++ b/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/pack_pattern-strip-from-pb_type-ports.xml b/pack_pattern-strip-from-pb_type-ports.xml
new file mode 100644
index 0000000..988de09
--- /dev/null
+++ b/pack_pattern-strip-from-pb_type-ports.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<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/xml-explicit-port.golden.xml b/xml-explicit-port.golden.xml
new file mode 100644
index 0000000..2bd3d8f
--- /dev/null
+++ b/xml-explicit-port.golden.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<xml>
+port-name
+port-name[8]
+port-name[8:4]
+</xml>
diff --git a/xml-explicit-port.xml b/xml-explicit-port.xml
new file mode 100644
index 0000000..a58530f
--- /dev/null
+++ b/xml-explicit-port.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<xml>
+  <port name="port-name" />
+  <port name="port-name" bit="8" />
+  <port name="port-name" bit_msb="8" bit_lsb="4" />
+</xml>
diff --git a/xsl_tests.cmake b/xsl_tests.cmake
new file mode 100644
index 0000000..65d02d1
--- /dev/null
+++ b/xsl_tests.cmake
@@ -0,0 +1,44 @@
+# Creating new target to call all the added tests
+add_custom_target(all_xsl_tests ALL)
+
+function(XSL_GOLDEN_TEST)
+  # ~~~
+  # XSL_GOLDEN_TEST(
+  #   NAME name
+  #   TOP_MODULE name
+  #   )
+  # ~~~
+  #
+  # This function is to test both the pb_type XML generation. It will call V2X_TEST_GENERIC multiple times first with the field TYPE set to `pb_type`
+  # then with `model`
+  #
+  # NAME name of the test.
+  # TOP_MODULE name of the top verilog module that has to be tested.
+  #
+  # Usage: v2x_test_model(NAME <test_name> TOP_MODULE <top_module.v>) (All fields are required)
+
+  set(oneValueArgs NAME TOP_MODULE)
+  cmake_parse_arguments(
+    XSL_GOLDEN_TEST
+    "${options}"
+    "${oneValueArgs}"
+    "${multiValueArgs}"
+    ${ARGN}
+  )
+
+  set(NAME ${XSL_GOLDEN_TEST_NAME})
+  set(TOP_MODULE ${XSL_GOLDEN_TEST_TOP_MODULE})
+
+  set(INPUT_XML ${NAME}.xml)
+  add_file_target(FILE ${INPUT_XML} SCANNER_TYPE xml)
+
+  set(ACTUAL_XML ${NAME}.actual.xml)
+  xml_canonicalize_merge(NAME merge_${ACTUAL_XML} FILE ${INPUT_XML} OUTPUT ${ACTUAL_XML})
+
+  set(GOLDEN_XML ${NAME}.golden.xml)
+  add_file_target(FILE ${GOLDEN_XML} SCANNER_TYPE xml)
+
+  diff(NAME diff_${NAME} GOLDEN ${GOLDEN_XML} ACTUAL ${ACTUAL_XML})
+
+  add_dependencies(all_xsl_tests diff_${NAME})
+endfunction(XSL_GOLDEN_TEST)