Merge pull request #1627 from dnltz/WIP/dnltz/parts_fixups

Docu fixup and prevent AssertionError
diff --git a/docs/dev_database/common/cell_data.rst b/docs/dev_database/common/cell_data.rst
index 07dbf8d..37b0dcd 100644
--- a/docs/dev_database/common/cell_data.rst
+++ b/docs/dev_database/common/cell_data.rst
@@ -65,7 +65,8 @@
 
 This is a JSON file containing a dictionary of ports, each one with two attributes:
 
-    - Direction: Corresponds to the port directiona and can have the ``input`` or ``output`` values.
+    - Direction: Corresponds to the port directiona and can have the ``input``, ``output``, ``clock`` values.
+                 Note that the ``clock`` value is implicitly considered also as an ``input``.
     - Width: Indicates the width of the port bus.
 
 As an example of parameter please, refer to the following::
diff --git a/fuzzers/061-pcie-conf/generate_ports.tcl b/fuzzers/061-pcie-conf/generate_ports.tcl
index 603d37e..262fe22 100644
--- a/fuzzers/061-pcie-conf/generate_ports.tcl
+++ b/fuzzers/061-pcie-conf/generate_ports.tcl
@@ -6,28 +6,7 @@
 #
 # SPDX-License-Identifier: ISC
 
-proc dump_pins {file_name site_prefix} {
-    set fp [open $file_name w]
-
-    puts $fp "name,is_input,is_output"
-    set site [lindex [get_sites $site_prefix*] 0]
-
-    set pins [get_site_pins -of_objects $site]
-    foreach pin $pins {
-        set connected_pip [get_pips -of_objects [get_nodes -of_objects $pin]]
-
-        if { $connected_pip == "" } {
-            continue
-        }
-
-        set pin_name [lindex [split $pin "/"] 1]
-        set is_input [get_property IS_INPUT $pin]
-        set is_output [get_property IS_OUTPUT $pin]
-
-        puts $fp "$pin_name,$is_input,$is_output"
-    }
-    close $fp
-}
+source "$::env(XRAY_DIR)/utils/utils.tcl"
 
 create_project -force -name design -part $::env(XRAY_PART)
 set_property design_mode PinPlanning [current_fileset]
diff --git a/fuzzers/063-gtp-common-conf/generate_ports.tcl b/fuzzers/063-gtp-common-conf/generate_ports.tcl
index 75f7c7f..4dab678 100644
--- a/fuzzers/063-gtp-common-conf/generate_ports.tcl
+++ b/fuzzers/063-gtp-common-conf/generate_ports.tcl
@@ -6,28 +6,7 @@
 #
 # SPDX-License-Identifier: ISC
 
-proc dump_pins {file_name site_prefix} {
-    set fp [open $file_name w]
-
-    puts $fp "name,is_input,is_output"
-    set site [lindex [get_sites $site_prefix*] 0]
-
-    set pins [get_site_pins -of_objects $site]
-    foreach pin $pins {
-        set connected_pip [get_pips -of_objects [get_nodes -of_objects $pin]]
-
-        if { $connected_pip == "" } {
-            continue
-        }
-
-        set pin_name [lindex [split $pin "/"] 1]
-        set is_input [get_property IS_INPUT $pin]
-        set is_output [get_property IS_OUTPUT $pin]
-
-        puts $fp "$pin_name,$is_input,$is_output"
-    }
-    close $fp
-}
+source "$::env(XRAY_DIR)/utils/utils.tcl"
 
 create_project -force -name design -part $::env(XRAY_PART)
 set_property design_mode PinPlanning [current_fileset]
diff --git a/fuzzers/064-gtp-channel-conf/attrs.json b/fuzzers/064-gtp-channel-conf/attrs.json
index f852a25..6c1e022 100644
--- a/fuzzers/064-gtp-channel-conf/attrs.json
+++ b/fuzzers/064-gtp-channel-conf/attrs.json
@@ -904,13 +904,13 @@
         "type": "INT",
         "values": [1, 2, 4, 8],
         "encoding": [0, 1, 2, 3],
-        "digits": 3
+        "digits": 2
     },
     "RXOUT_DIV": {
         "type": "INT",
         "values": [1, 2, 4, 8],
         "encoding": [0, 1, 2, 3],
-        "digits": 3
+        "digits": 2
     },
     "CFOK_CFG": {
         "type": "BIN",
diff --git a/fuzzers/064-gtp-channel-conf/generate_ports.tcl b/fuzzers/064-gtp-channel-conf/generate_ports.tcl
index f847924..2c1d63c 100644
--- a/fuzzers/064-gtp-channel-conf/generate_ports.tcl
+++ b/fuzzers/064-gtp-channel-conf/generate_ports.tcl
@@ -6,28 +6,7 @@
 #
 # SPDX-License-Identifier: ISC
 
-proc dump_pins {file_name site_prefix} {
-    set fp [open $file_name w]
-
-    puts $fp "name,is_input,is_output"
-    set site [lindex [get_sites $site_prefix*] 0]
-
-    set pins [get_site_pins -of_objects $site]
-    foreach pin $pins {
-        set connected_pip [get_pips -of_objects [get_nodes -of_objects $pin]]
-
-        if { $connected_pip == "" } {
-            continue
-        }
-
-        set pin_name [lindex [split $pin "/"] 1]
-        set is_input [get_property IS_INPUT $pin]
-        set is_output [get_property IS_OUTPUT $pin]
-
-        puts $fp "$pin_name,$is_input,$is_output"
-    }
-    close $fp
-}
+source "$::env(XRAY_DIR)/utils/utils.tcl"
 
 create_project -force -name design -part $::env(XRAY_PART)
 set_property design_mode PinPlanning [current_fileset]
diff --git a/fuzzers/071-ppips/generate.tcl b/fuzzers/071-ppips/generate.tcl
index 1fbad4b..09e713f 100644
--- a/fuzzers/071-ppips/generate.tcl
+++ b/fuzzers/071-ppips/generate.tcl
@@ -246,7 +246,7 @@
         set skip_wire false
 
         foreach wire $forbids {
-            if {[regexp $wire $dst_wire]} {
+            if {[regexp $wire $src_wire]} {
                 set skip_wire true
                 break
             }
@@ -257,7 +257,7 @@
 
         set skip_wire true
         foreach wire $allows {
-            if {[regexp $wire $dst_wire]} {
+            if {[regexp $wire $src_wire]} {
                 set skip_wire false
                 break
             }
@@ -361,8 +361,8 @@
     set tiles [get_tiles -filter "TILE_TYPE == $tile_type"]
     if {[llength $tiles] != 0} {
         set tile [lindex $tiles 0]
-        set allow_wires {"IMUX_OUT" "IMUX_L" "LOGIC_OUTS"}
-        set forbid_wires {"DELAY"}
+        set allow_wires {"IMUX_L\[0-9\]+" "IMUX\[0-9\]+" "LOGIC_OUTS"}
+        set forbid_wires {"DELAY\[0-9\]+"}
         write_pcie_int_interface_ppips_db "ppips_[string tolower $tile_type].db" $tile $allow_wires $forbid_wires
     }
 }
diff --git a/utils/make_ports.py b/utils/make_ports.py
index e31600c..27eecda 100644
--- a/utils/make_ports.py
+++ b/utils/make_ports.py
@@ -81,9 +81,12 @@
         # Get direction
         is_input = int(pin["is_input"])
         is_output = int(pin["is_output"])
+        is_clock = int(pin["is_clock"])
 
         if is_input:
             direction = "input"
+            if is_clock:
+                direction = "clock"
         elif is_output:
             direction = "output"
         else:
diff --git a/utils/update_resources.py b/utils/update_resources.py
index 275aea6..3b2209d 100755
--- a/utils/update_resources.py
+++ b/utils/update_resources.py
@@ -13,6 +13,8 @@
 import subprocess
 import os
 import re
+import tempfile
+import json
 from prjxray import util
 
 
@@ -39,23 +41,36 @@
     information = {}
 
     parts = util.get_parts(args.db_root)
+    processed_parts = dict()
     for part in parts.keys():
+        # Skip parts which differ only in the speedgrade, as they have the same pins
+        fields = part.split("-")
+        common_part = fields[0]
+        if common_part in processed_parts:
+            information[part] = processed_parts[common_part]
+            continue
+
         print("Find pins for {}".format(part))
         env['XRAY_PART'] = part
+        _, tmp_file = tempfile.mkstemp()
         # Asks with get_package_pins and different filters for pins with
         # specific properties.
-        command = "{} -mode batch -source update_resources.tcl".format(
-            env['XRAY_VIVADO'])
+        command = "env TMP_FILE={} {} -mode batch -source update_resources.tcl".format(
+            tmp_file, env['XRAY_VIVADO'])
         result = subprocess.run(
             command.split(' '),
             check=True,
             env=env,
             cwd=cwd,
             stdout=subprocess.PIPE)
-        # Formats the output and stores the pins
-        output = result.stdout.decode('utf-8').splitlines()
-        clk_pins = output[-4].split(' ')
-        data_pins = output[-2].strip().split(' ')
+
+        with open(tmp_file, "r") as fp:
+            pins_json = json.load(fp)
+
+        os.remove(tmp_file)
+
+        clk_pins = pins_json["clk_pins"].split()
+        data_pins = pins_json["data_pins"].split()
         pins = {
             0: clk_pins[0],
             1: data_pins[0],
@@ -63,6 +78,7 @@
             3: data_pins[-1]
         }
         information[part] = {'pins': pins}
+        processed_parts[common_part] = {'pins': pins}
 
     # Overwrites the <family>/resources.yaml file completly with new data
     util.set_part_resources(resource_path, information)
diff --git a/utils/update_resources.tcl b/utils/update_resources.tcl
index a95f1e0..292041d 100644
--- a/utils/update_resources.tcl
+++ b/utils/update_resources.tcl
@@ -21,5 +21,9 @@
     append data_pins " " [get_package_pins -filter "IS_GENERAL_PURPOSE && BANK==$bank"]
 }
 
-puts $clk_pins
-puts $data_pins
+set fp [open $::env(TMP_FILE) w]
+
+puts $fp "{"
+    puts $fp "\t\"clk_pins\": \"$clk_pins\","
+    puts $fp "\t\"data_pins\": \"$data_pins\""
+puts $fp "}"
diff --git a/utils/utils.tcl b/utils/utils.tcl
index 751f884..83c8cba 100644
--- a/utils/utils.tcl
+++ b/utils/utils.tcl
@@ -168,3 +168,37 @@
     write_checkpoint -force design.dcp
     write_bitstream -force design.bit
 }
+
+# Dumps all pins of a site, with the direction info (clock, input, output)
+proc dump_pins {file_name site_prefix} {
+    set fp [open $file_name w]
+
+    puts $fp "name,is_input,is_output,is_clock"
+    set site [lindex [get_sites $site_prefix*] 0]
+    set bel [get_bels -of_objects $site]
+    set bel_pins [get_bel_pins -of_objects $bel]
+
+    set bel_pins_dict [dict create]
+    foreach pin $bel_pins {
+        set pin_name [lindex [split $pin "/"] 2]
+        set is_clock [get_property IS_CLOCK $pin]
+        dict set bel_pins_dict $pin_name $is_clock
+    }
+
+    set site_pins [get_site_pins -of_objects $site]
+    foreach pin $site_pins {
+        set connected_pip [get_pips -of_objects [get_nodes -of_objects $pin]]
+
+        if { $connected_pip == "" } {
+            continue
+        }
+
+        set pin_name [lindex [split $pin "/"] 1]
+        set is_input [get_property IS_INPUT $pin]
+        set is_output [get_property IS_OUTPUT $pin]
+        set is_clock [dict get $bel_pins_dict $pin_name]
+
+        puts $fp "$pin_name,$is_input,$is_output,$is_clock"
+    }
+    close $fp
+}