Merge pull request #1498 from antmicro/mmcm_rebuf_pips

Enable MMCM REBUF PIPs
diff --git a/README.md b/README.md
index 14be2bf..080bd1f 100644
--- a/README.md
+++ b/README.md
@@ -200,6 +200,9 @@
 The aim is to eventually document all parts in the Xilinx 7-series FPGAs but we
 can not do this alone, **we need your help**!
 
+## Adding a new part to an existing family
+
+We have written a [detailed guide](https://symbiflow.readthedocs.io/projects/prjxray/en/latest/db_dev_process/newpart.html) that walks through the process of adding a new part to an existing family.
 
 ## TODO List
 
diff --git a/docs/db_dev_process/index.rst b/docs/db_dev_process/index.rst
index c66b5d4..7b78fa0 100644
--- a/docs/db_dev_process/index.rst
+++ b/docs/db_dev_process/index.rst
@@ -11,4 +11,5 @@
    fuzzers/index
    minitests/index
    parts
+   newpart
 
diff --git a/docs/db_dev_process/newpart.rst b/docs/db_dev_process/newpart.rst
new file mode 100644
index 0000000..73f066e
--- /dev/null
+++ b/docs/db_dev_process/newpart.rst
@@ -0,0 +1,313 @@
+Guide to adding a new device to an existing family
+==================================================
+
+This documents how to add support for a new device. The running example
+is the addition of the xc7a100t device to the Artix-7 family.
+
+Adding a new device to an existing family is much simpler than adding a
+new family, since the building blocks (tiles) are already known. There
+are just more or fewer of them, arranged differently. No new fuzzers are
+needed. You just need to rerun some fuzzers for the new device to
+understand how the tiles are connected to each other and to IOs.
+
+*If you are*\ \  **just**\ \  *adding a new package for a device that is
+already supported, you can skip Steps 2 through 4.*
+
+Note: Since this guide was written, the xc7a100t has become the primary
+device in the database, not a secondary device as it was when it was
+originally added. Therefore the files currently in the repo don’t match
+what is described here. But if you look at the original PRs, they match
+what is described in the examples here.
+
+The main PR from the example is
+`#1313 <https://github.com/SymbiFlow/prjxray/pull/1313>`__. Followup
+fixes for problems revealed during testing are
+`#1334 <https://github.com/SymbiFlow/prjxray/pull/1334>`__ and
+`#1336 <https://github.com/SymbiFlow/prjxray/pull/1336>`__.
+
+Step 0
+~~~~~~
+
+Fork a copy of https://github.com/SymbiFlow/prjxray on GitHub (go to the
+page, click “Fork” button, select your own workspace).
+
+Clone your fork, and make a new branch, with a name related to the new
+device/package:
+
+::
+
+   git clone git@github.com:<yourUserID>/prjxray.git
+   cd prjxray
+   git checkout -b <new_branch_name>
+
+Step 1
+~~~~~~
+
+Follow the Project X-Ray developer setup instructions in the
+`documentation <https://symbiflow.readthedocs.io/en/latest/prjxray/docs/db_dev_process/readme.html>`__,
+up through Step 7 and choose Option 1 (invoke the
+``./download-latest-db.sh`` script). This script will clone the official
+prjxray-db database under ``database/``. The following steps will make
+changes under this directory. You may want to put these changes on your
+own fork of ``prjxray-db`` for testing. This is explained at the end,
+under “Database Updates”.
+
+Step 2
+~~~~~~
+
+Add a new settings file. Usually you will start with an existing
+settings file and modify it. Assuming you’re in prjxray/,
+
+::
+
+   cp settings/<baseline_device>.sh settings/<new_device>.sh
+   git add settings/<new_device>.sh
+
+Example:
+
+::
+
+   cp settings/artix7_200t.sh settings/artix7_100t.sh
+   git add settings/artix7_100t.sh
+
+Update the following values in the new settings file:
+
+-  ``XRAY_PART`` –
+   Important: choose a package that is fully bonded (typically the one with
+   the largest number of pins). If the part that you’re actually interested
+   in is different (with fewer bonded pins), it will be handled later. In
+   the running example, the actual part of interest was the xc7a100tcsg324,
+   since that is on the Arty A7-100T board. But here, the xc7a100tfgg676
+   part is used; the xc7a100tcsg324 is handled later.
+
+-  ``XRAY_ROI_TILEGRID`` – modify the bounding boxes to be a tight fit on
+   your new part.
+
+-  ``XRAY_IOI3_TILES`` – These tiles need special
+   handling for an irregularity in Xilinx 7-series FPGAs. See the
+   `comments <https://github.com/SymbiFlow/prjxray/blob/master/fuzzers/005-tilegrid/generate_full.py#L401>`__
+   in the 005 fuzzer for more information.
+
+-  ``XRAY_PIN_00`` – this must be a clock pin. You can look at the device in the Vivado GUI
+   interactively (click on IOs and check their properties until you find
+   one with IS_CLOCK=true), or run a small clocked design in Vivado and see
+   which pin is assigned to ‘clk’.
+
+-  ``XRAY_PIN_01`` and on – these should be normal data pins on the device.
+
+`This <https://github.com/tcal-x/prjxray/blob/fbf4dd897d5a1025ebfeb7c51c5077a6b6c9bc47/settings/artix7_100t.sh>`__
+is what the new settings file looked like in the example.
+
+Source this new settings file:
+
+::
+
+   source settings/<new_device>.sh
+
+Step 3
+~~~~~~
+
+Edit the top Makefile
+
+-  Update the Makefile by adding the new device to the `correct
+   list <https://github.com/tcal-x/prjxray/blob/fbf4dd897d5a1025ebfeb7c51c5077a6b6c9bc47/Makefile#L171>`__,
+   so that the Makefile generates targets for the new device (used in
+   Step 4). ``<new_device>`` is the basename of the new settings file
+   that you just created.
+
+::
+
+   <FAMILY>_PARTS=<existing_devices> <new_device>
+
+-  In our running example, we add ``artix7_100t`` to ``ARTIX_PARTS``:
+
+::
+
+   ARTIX_PARTS=artix7_200t artix7_100t
+
+Step 4
+~~~~~~
+
+Make sure you’ve sourced your new device settings file (see the end of
+step 2). Now it is time to run some fuzzers to figure out how the tiles
+on your new device are connected.
+
+Make the following target, with ``<new_device>`` as above, and setting
+the parallelism factor ``-j<n>`` appropriate for the number of cores
+your host has. The make job can benefit from large numbers of cores.
+
+::
+
+   make -j<n> MAX_VIVADO_PROCESS=<n> db-part-only-<new_device>
+
+Again, ``<new_device>`` must match the base name of the new settings
+file that was added. For example,
+
+::
+
+   make -j32 MAX_VIVADO_PROCESS=32 db-part-only-artix7_100t
+
+-  It should run fuzzers 000, 001, 005, 072, 073, 074, and 075.
+
+-  005 will take a long time. Using multiple cores will help.
+
+-  074 *will fail* the first time, since it hasn’t been told to ignore
+   certain wires.
+
+   -  After it fails, go to the build directory
+      ``cd fuzzers/074-dump_all/build_<XRAY_PART>`` (this is the
+      ``XRAY_PART`` from the new settings script; in our example, the
+      build directory is
+      ``fuzzers/074-dump_all/build_xc7a100tfgg676-1/``).
+   -  Run
+      ``python3 ../analyze_errors.py --output_ignore_list  > new-ignored``
+   -  Inspect and compare ``new-ignored`` against existing ignored wire
+      files in ``../ignored_wires/``.
+   -  If it looks good, copy it to an appropriately-named file:
+      ``cp new-ignored ../ignored_wires/artix7/<XRAY_PART>_ignored_wires.txt``
+      (in our example, it is
+      ``../ignored_wires/artix7/xc7a100tfgg676-1_ignored_wires.txt``).
+   -  Add it:
+      ``git add ../ignored_wires/artix7/<XRAY_PART>_ignored_wires.txt``
+
+-  Return to prjxray/ directory, and clean up 074 to prepare for the
+   rerun: ``make -C fuzzers/074-dump-all clean``
+
+-  Rerun the top make command,
+   e.g. ``make -j32 MAX_VIVADO_PROCESS=32 db-part-only-artix7_100t``
+
+Step 5
+~~~~~~
+
+The next task is handling the extra parts – those not fully bonded out.
+These are usually the parts you actually have on the boards you buy.
+
+-  Add a new entry in the appropriate ‘harness’ section for any
+   alternative packages (typically with fewer pins, in this example, 324
+   versus 676). If any ``XRAY_PIN_<XX>`` values you listed in the
+   settings file are not bonded out on the new part, you must specify
+   alternatives. In this example, we need to specify a new clock pin,
+   ``XRAY_PIN_00=N15``. Here, ``XRAY_PART`` is the extra part, and
+   ``XRAY_EQUIV_PART`` is the original, fully-bonded version:
+
+::
+
+   db-extras-artix7-harness:
+       +source settings/artix7.sh && \
+             XRAY_PIN_00=J13 XRAY_PIN_01=J14 XRAY_PIN_02=K15 XRAY_PIN_03=K16 \
+             XRAY_PART=xc7a35tftg256-1 XRAY_EQUIV_PART=xc7a50tfgg484-1 \
+             $(MAKE) -C fuzzers roi_only
+   +   +source settings/artix7_100t.sh && \
+   +         XRAY_PIN_00=N15 \
+   +         XRAY_PART=xc7a100tcsg324-1 XRAY_EQUIV_PART=xc7a100tfgg676-1 \
+   +         $(MAKE) -C fuzzers roi_only
+       +source settings/artix7_200t.sh && \
+             XRAY_PIN_00=V10 XRAY_PIN_01=W10 XRAY_PIN_02=Y11 XRAY_PIN_03=Y12 \
+             XRAY_PART=xc7a200tsbg484-1 XRAY_EQUIV_PART=xc7a200tffg1156-1 \
+             $(MAKE) -C fuzzers roi_only
+
+Make the appropriate harness target (adjusting for your family):
+
+::
+
+   make -j32 db-extras-artix7-harness
+
+This target will make updates for the extra parts of all of the family
+devices, not just your new device.
+
+Step 6
+~~~~~~
+
+Do a spot check.
+
+-  Check that there are new part directories in the database under the family subdirectory, for example:
+
+::
+
+   $ ll database/artix7/xc7a100*
+   database/artix7/xc7a100tcsg324-1:
+   total 19884
+   drwxrwxr-x  2 tcal tcal     4096 Apr 29 08:01 ./
+   drwxrwxr-x 13 tcal tcal    32768 Apr 29 08:00 ../
+   -rw-rw-r--  1 tcal tcal    10364 Apr 29 08:00 package_pins.csv
+   -rw-rw-r--  1 tcal tcal    32142 Apr 29 08:01 part.json
+   -rw-rw-r--  1 tcal tcal    22440 Apr 29 08:01 part.yaml
+   -rw-rw-r--  1 tcal tcal  8601612 Apr 29 08:01 tileconn.json
+   -rw-rw-r--  1 tcal tcal 11648042 Apr 29 08:01 tilegrid.json
+
+   database/artix7/xc7a100tfgg676-1:
+   total 19892
+   drwxrwxr-x  2 tcal tcal     4096 Apr 29 02:03 ./
+   drwxrwxr-x 13 tcal tcal    32768 Apr 29 08:00 ../
+   -rw-rw-r--  1 tcal tcal    16645 Apr 28 22:16 package_pins.csv
+   -rw-rw-r--  1 tcal tcal    32165 Apr 28 22:17 part.json
+   -rw-rw-r--  1 tcal tcal    22440 Apr 28 22:17 part.yaml
+   -rw-rw-r--  1 tcal tcal  8601612 Apr 29 02:03 tileconn.json
+   -rw-rw-r--  1 tcal tcal 11648042 Apr 28 22:37 tilegrid.json
+
+In this case, the tile grid is the same size since it’s the same chip,
+but the size of the package pins files differs, since there are
+different numbers of bonded pins.
+
+Note: These changes/additions under ``database/`` do *not* get checked
+in. They are in the ``prjxray-db`` repo. This spot check is to make sure
+that your changes in ``prjxray`` will do the right thing when the
+official database is fully rebuilt. See “Database Updates” below for
+more information.
+
+Step 7
+~~~~~~
+
+Assuming everything looks good, commit to your ``prjxray`` fork/branch.
+You should have a new file under settings/, a new ignored_wires file,
+and a modified Makefile (see the `initial
+PR <https://github.com/SymbiFlow/prjxray/pull/1313/files?file-filters%5B%5D=>`__
+of the example for reference).
+
+::
+
+   git add Makefile settings/artix7_100t.sh
+   git status
+   git commit --signoff
+
+Step 8
+~~~~~~
+
+Push to GitHub:
+
+::
+
+   git push origin <new_branch_name>
+
+Then make a pull request. Navigate to the GitHub page for your
+``prjxray`` fork/branch, and click the “New pull request” button.
+Making the pull request will kick off continuous integration tests.
+Watch the results and fix any issues.
+
+Database Updates
+~~~~~~~~~~~~~~~~
+
+The process above (steps 4 and 5) will create some new files and modify
+some existing files under database/, which is a different repo,
+``prjxray-db``.
+
+To test these changes before the next official prjxray-db gets built
+(and even before your PR on prjxray is merged), you can put these
+changes on your own fork of prjxray-db, and then test them in the
+context of
+`symbiflow-arch-defs <https://github.com/SymbiFlow/symbiflow-arch-defs>`__.
+
+To put the db updates on your own fork, create your fork of
+https://github.com/SymbiFlow/prjxray-db if you haven’t already. Then
+follow one of the approaches suggested in the checked solution of this
+StackOverflow
+`post <https://stackoverflow.com/questions/25545613/how-can-i-push-to-my-fork-from-a-clone-of-the-original-repo>`__.
+
+You are NEVER going to send a pull request on `prjxray-db`. The database is always rebuilt
+from scratch. After your changes on prjxray are merged, they will
+reflected in the next prjxray-db rebuild. The changes submitted to your
+prjxray-db fork are only for your own testing.
+
+To use your new repo/branch under
+symbiflow-arch-defs/third_party/prjxray-db/, you will need to change the
+submodule reference to point to your fork/branch of ``prjxray-db``.
diff --git a/prjxray/node_model.py b/prjxray/node_model.py
index 879f1cb..d187c57 100644
--- a/prjxray/node_model.py
+++ b/prjxray/node_model.py
@@ -143,6 +143,11 @@
         return self.nodes[tile, wire]
 
     def _build_wire_to_node_map(self):
+        self.wire_to_node_map = {}
+
+        if self.nodes is None:
+            self._build_nodes()
+
         for node, wires in self.nodes.items():
             for tile_wire in wires:
                 assert tile_wire not in self.wire_to_node_map