Merge pull request #1606 from antmicro/auto_frames_count

005-tilegrid: Extract frames count information from part's json
diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py
index c2f3c22..021f14f 100644
--- a/fuzzers/005-tilegrid/add_tdb.py
+++ b/fuzzers/005-tilegrid/add_tdb.py
@@ -108,7 +108,7 @@
         ("hclk_cmt", 30, 10),
         ("hclk_ioi", 42, 1),
         ("pcie", 36, 101),
-        ("gtp_common", 42, 101),
+        ("gtp_common", 32, 101),
         ("gtp_channel", 32, 22),
         ("clb_int", int_frames, int_words),
         ("iob_int", int_frames, int_words),
diff --git a/fuzzers/030-iob/process_rdb.py b/fuzzers/030-iob/process_rdb.py
index d6b9c12..c1c2887 100644
--- a/fuzzers/030-iob/process_rdb.py
+++ b/fuzzers/030-iob/process_rdb.py
@@ -196,19 +196,43 @@
                 if enum is not None:
                     common_groups[site][(bits, group)]['enums'].add(enum)
 
+    visited_iostandards = list()
     for site, groups in common_groups.items():
         for (bits, group), v in groups.items():
-            if v['enums']:
+            iostandards = v['IOSTANDARDS']
+            enums = v['enums']
+
+            # It happens that some features appear only in one of the IOB sites and not
+            # in the other. This makes it hard to assign the correct features to the correct
+            # site in the P&R toolchain.
+            #
+            # The following code makes sure that the same set of iostandards
+            # (even if not really present at a site location) appears for each site
+            for visited_iostandard, visited_group, visited_enums in visited_iostandards:
+                same_enum = enums == visited_enums
+                same_group = group == visited_group
+                compatible_iostd = any(
+                    x in iostandards for x in visited_iostandard)
+                take_visited_iostd = len(visited_iostandard) > len(iostandards)
+                if same_enum and same_group and compatible_iostd and take_visited_iostd:
+                    iostandards = visited_iostandard
+                    break
+
+            visited_iostandards.append((iostandards, group, enums))
+
+            iostandards_string = '_'.join(sorted(iostandards))
+
+            if enums:
                 feature = 'IOB33.{site}.{iostandards}.{group}.{enums}'.format(
                     site=site,
-                    iostandards='_'.join(sorted(v['IOSTANDARDS'])),
+                    iostandards=iostandards_string,
                     group=group,
-                    enums='_'.join(sorted(v['enums'])),
+                    enums='_'.join(sorted(enums)),
                 )
             else:
                 feature = 'IOB33.{site}.{iostandards}.{group}'.format(
                     site=site,
-                    iostandards='_'.join(sorted(v['IOSTANDARDS'])),
+                    iostandards=iostandards_string,
                     group=group,
                 )
 
diff --git a/fuzzers/031-cmt-mmcm/write_mmcm_reg.py b/fuzzers/031-cmt-mmcm/write_mmcm_reg.py
index 8a8afe1..81fd570 100644
--- a/fuzzers/031-cmt-mmcm/write_mmcm_reg.py
+++ b/fuzzers/031-cmt-mmcm/write_mmcm_reg.py
@@ -171,7 +171,7 @@
     Other features generated in fuzzing are passed through.
 
     """
-    base_offset_register = 'CMT_LOWER_B.MMCME2.CLKOUT5_DIVIDE[1]'
+    base_offset_register = 'CMT_LOWER_B.MMCME2_ADV.CLKOUT5_DIVIDE[1]'
 
     bit_offset = None
     in_use = None
@@ -266,7 +266,7 @@
                             continue
 
                         print(
-                            'CMT_LOWER_B.MMCME2.{}_{}_{}[{}] {}'.format(
+                            'CMT_LOWER_B.MMCME2_ADV.{}_{}_{}[{}] {}'.format(
                                 register_name, layout, field, bit,
                                 reg.next_bit()))
             else:
@@ -279,7 +279,7 @@
                             continue
 
                         print(
-                            'CMT_LOWER_B.MMCME2.{}[{}] {}'.format(
+                            'CMT_LOWER_B.MMCME2_ADV.{}[{}] {}'.format(
                                 field, start_bit + bit, reg.next_bit()))
 
             assert bit_count == 16
@@ -287,11 +287,11 @@
             for bit in range(16):
                 if register_name != layout or layout in ['CLKOUT1', 'CLKOUT2']:
                     print(
-                        'CMT_LOWER_B.MMCME2.{}_{}[{}] {}'.format(
+                        'CMT_LOWER_B.MMCME2_ADV.{}_{}[{}] {}'.format(
                             register_name, layout, bit, reg.next_bit()))
                 else:
                     print(
-                        'CMT_LOWER_B.MMCME2.{}[{}] {}'.format(
+                        'CMT_LOWER_B.MMCME2_ADV.{}[{}] {}'.format(
                             register_name, bit, reg.next_bit()))
 
     parts = in_use.split()
diff --git a/fuzzers/032-cmt-pll/write_pll_reg.py b/fuzzers/032-cmt-pll/write_pll_reg.py
index 749a84d..aeeae4a 100644
--- a/fuzzers/032-cmt-pll/write_pll_reg.py
+++ b/fuzzers/032-cmt-pll/write_pll_reg.py
@@ -151,7 +151,7 @@
     Other features generated in fuzzing are passed through.
 
     """
-    base_offset_register = 'CMT_UPPER_T.PLLE2.CLKOUT5_DIVIDE[1]'
+    base_offset_register = 'CMT_UPPER_T.PLLE2_ADV.CLKOUT5_DIVIDE[1]'
 
     bit_offset = None
     in_use = None
@@ -244,7 +244,7 @@
                             continue
 
                         print(
-                            'CMT_UPPER_T.PLLE2.{}_{}_{}[{}] {}'.format(
+                            'CMT_UPPER_T.PLLE2_ADV.{}_{}_{}[{}] {}'.format(
                                 register_name, layout, field, bit,
                                 reg.next_bit()))
             else:
@@ -257,7 +257,7 @@
                             continue
 
                         print(
-                            'CMT_UPPER_T.PLLE2.{}[{}] {}'.format(
+                            'CMT_UPPER_T.PLLE2_ADV.{}[{}] {}'.format(
                                 field, start_bit + bit, reg.next_bit()))
 
             assert bit_count == 16
@@ -265,11 +265,11 @@
             for bit in range(16):
                 if register_name != layout or layout in ['CLKOUT1', 'CLKOUT2']:
                     print(
-                        'CMT_UPPER_T.PLLE2.{}_{}[{}] {}'.format(
+                        'CMT_UPPER_T.PLLE2_ADV.{}_{}[{}] {}'.format(
                             register_name, layout, bit, reg.next_bit()))
                 else:
                     print(
-                        'CMT_UPPER_T.PLLE2.{}[{}] {}'.format(
+                        'CMT_UPPER_T.PLLE2_ADV.{}[{}] {}'.format(
                             register_name, bit, reg.next_bit()))
 
     parts = in_use.split()
diff --git a/fuzzers/063-gtp-common-conf/generate.py b/fuzzers/063-gtp-common-conf/generate.py
index f7bb4d9..073d696 100644
--- a/fuzzers/063-gtp-common-conf/generate.py
+++ b/fuzzers/063-gtp-common-conf/generate.py
@@ -103,7 +103,7 @@
                             site, "%s[%u]" % (param, i), bitstr[i])
 
             for param in ["PLL0LOCKDETCLK", "PLL1LOCKDETCLK", "DRPCLK"]:
-                segmk.add_site_tag(site, "ZINV_" + param, 1 ^ params[param])
+                segmk.add_site_tag(site, "INV_" + param, params[param])
 
             for param in ["GTREFCLK0_USED", "GTREFCLK1_USED",
                           "BOTH_GTREFCLK_USED"]:
@@ -134,7 +134,7 @@
 
             for i in range(2):
                 segmk.add_tile_tag(
-                    tile, "IBUFDS_GTE2.%s[%u]" % (param, i), bitstr[i])
+                    tile, "IBUFDS_GTE2.CLKSWING_CFG[%u]" % (i), bitstr[i])
 
     if tile_type.startswith("GTP_COMMON_MID"):
         bitfilter = bitfilter_gtp_common_mid
diff --git a/fuzzers/063-gtp-common-conf/top.py b/fuzzers/063-gtp-common-conf/top.py
index d7fe50c..0122e36 100644
--- a/fuzzers/063-gtp-common-conf/top.py
+++ b/fuzzers/063-gtp-common-conf/top.py
@@ -159,6 +159,8 @@
                 verilog_attr += """
             .{}({}),""".format(param, value_str)
 
+            verilog_ports = ""
+
             for param in ["PLL0LOCKDETCLK", "PLL1LOCKDETCLK", "DRPCLK"]:
                 is_inverted = random.randint(0, 1)
 
@@ -166,12 +168,12 @@
 
                 verilog_attr += """
             .IS_{}_INVERTED({}),""".format(param, is_inverted)
+                verilog_ports += """
+            .{}({}),""".format(param, luts.get_next_output_net())
 
             verilog_attr = verilog_attr.rstrip(",")
             verilog_attr += "\n)"
 
-            verilog_ports = ""
-
             for param in ["GTREFCLK0_USED", "GTREFCLK1_USED",
                           "BOTH_GTREFCLK_USED"]:
                 params[param] = 0
diff --git a/fuzzers/064-gtp-channel-conf/generate.py b/fuzzers/064-gtp-channel-conf/generate.py
index 19dd98e..5240aa0 100644
--- a/fuzzers/064-gtp-channel-conf/generate.py
+++ b/fuzzers/064-gtp-channel-conf/generate.py
@@ -113,8 +113,7 @@
                 for param in ["TXUSRCLK", "TXUSRCLK2", "TXPHDLYTSTCLK",
                               "SIGVALIDCLK", "RXUSRCLK", "RXUSRCLK2", "DRPCLK",
                               "DMONITORCLK", "CLKRSVD0", "CLKRSVD1"]:
-                    segmk.add_site_tag(
-                        site, "ZINV_" + param, 1 ^ params[param])
+                    segmk.add_site_tag(site, "INV_" + param, params[param])
 
     gtp_channel_x = [
         "GTP_CHANNEL_0",
diff --git a/fuzzers/064-gtp-channel-conf/top.py b/fuzzers/064-gtp-channel-conf/top.py
index 7e6dd64..ed09ca1 100644
--- a/fuzzers/064-gtp-channel-conf/top.py
+++ b/fuzzers/064-gtp-channel-conf/top.py
@@ -17,6 +17,7 @@
 random.seed(int(os.getenv("SEED"), 16))
 from prjxray import util
 from prjxray import verilog
+from prjxray.lut_maker import LutMaker
 from prjxray.db import Database
 
 INT = "INT"
@@ -76,6 +77,8 @@
 assign out = in;
 ''')
 
+    luts = LutMaker()
+
     primitives_list = list()
 
     for tile_name, tile_type, site_name, site_type in gen_sites(
@@ -122,6 +125,7 @@
                 verilog_attr += """
             .{}({}),""".format(param, value_str)
 
+            verilog_ports = ""
             for param in ["TXUSRCLK", "TXUSRCLK2", "TXPHDLYTSTCLK",
                           "SIGVALIDCLK", "RXUSRCLK", "RXUSRCLK2", "DRPCLK",
                           "DMONITORCLK", "CLKRSVD0", "CLKRSVD1"]:
@@ -131,19 +135,29 @@
 
                 verilog_attr += """
             .IS_{}_INVERTED({}),""".format(param, is_inverted)
+                verilog_ports += """
+            .{}({}),""".format(param, luts.get_next_output_net())
 
             verilog_attr = verilog_attr.rstrip(",")
             verilog_attr += "\n)"
 
             print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name))
             print(
-                """GTPE2_CHANNEL {} {} ();
-            """.format(verilog_attr, tile_type.lower()))
+                """GTPE2_CHANNEL {attrs} {site} (
+    {ports}
+);
+            """.format(
+                    attrs=verilog_attr,
+                    site=tile_type.lower(),
+                    ports=verilog_ports.rstrip(",")))
 
         params_list.append(params)
         params_dict["params"] = params_list
         primitives_list.append(params_dict)
 
+    for l in luts.create_wires_and_luts():
+        print(l)
+
     print("endmodule")
 
     with open('params.json', 'w') as f:
diff --git a/fuzzers/071-ppips/generate.tcl b/fuzzers/071-ppips/generate.tcl
index ce3da5c..50c7046 100644
--- a/fuzzers/071-ppips/generate.tcl
+++ b/fuzzers/071-ppips/generate.tcl
@@ -155,15 +155,20 @@
         set dst_wire [get_wires -downhill -of_objects $pip]
         set src_wire [get_wires -uphill -of_objects $pip]
 
-        set logic_outs [regexp "LOGIC_OUTS" $dst_wire]
-        set imux [regexp "IMUX" $src_wire]
-        set ctrl [regexp "GTPE2_CTRL" $src_wire]
-        set clk [regexp "GTPE2_CLK" $src_wire]
-        set ibufds [regexp "IBUFDS" $src_wire]
-        set refclk [regexp "COMMON_REFCLK" $src_wire]
-        set tx_pads [regexp "TX\[NP\]_PAD" $dst_wire]
-        set rx_pads [regexp "RX\[NP\]_PAD" $src_wire]
-        if {!$logic_outs && !$tx_pads && !$rx_pads && !$imux && !$ctrl && !$clk && !$refclk && !($ibufds && $tile_suffix == "")} {
+        set num_uphill_nodes [llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst_wire]]]
+
+        # All the "MID" GTP tiles (e.g. in the artix 200T devices) have configuration bits
+        # even for nodes with only one uphill nodes connections.
+        # E.g.: IBUFDS_GTPE2_1_MGTCLKOUT_MUX.IBUFDS_GTPE2_1_MGTCLKOUT
+        # The above is a real PIP and should not be added to the PPIPs list.
+        set mux [regexp "MUX" $dst_wire]
+
+        set mgt_clk [regexp "MGT_CLK\[0-9\]+" $dst_wire]
+        set mgtclkout [regexp "MGTCLKOUT" $dst_wire]
+
+        if {($num_uphill_nodes != 1 && !$mgtclkout) ||
+            $mux ||
+            ($mgt_clk && $tile_suffix != "")} {
             continue
         }
 
@@ -192,9 +197,20 @@
         set dst_wire [string map $map $dst_wire]
         set src_wire [string map $map $src_wire]
 
-        puts $fp "${tile_type}${tile_suffix}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
-    }
+        # Adding GTPE2_ prefix to wires only for GTP_INT_INTERFACE_[RL] and the wire is a LOGIC_OUTS type
+        # The GTP_INT_INTERFACE tile does not have the GTPE2_ prefix for this wires
+        set logic_outs [regexp "LOGIC_OUTS\[0-9\]+" $dst_wire]
+        if {$logic_outs && $wire_suffix != ""} {
+            set map {}
+            lappend map {INT_INTERFACE} GTPE2_INT_INTERFACE
 
+            set dst_wire [string map $map $dst_wire]
+            set src_wire [string map $map $src_wire]
+        }
+
+        puts $fp "${tile_type}${tile_suffix}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
+
+    }
     close $fp
 }
 
diff --git a/prjxray/segmaker.py b/prjxray/segmaker.py
index 2c16282..4d6795f 100644
--- a/prjxray/segmaker.py
+++ b/prjxray/segmaker.py
@@ -283,7 +283,7 @@
                     segment["tags"][tag] = value
 
             def add_site_tags():
-                site_prefix = site.split('_')[0]
+                site_prefix = "_".join(site.split('_')[0:-1])
 
                 def name_slice():
                     '''
@@ -331,7 +331,7 @@
                     'IDELAY': name_y0y1,
                     'ILOGIC': name_y0y1,
                     'OLOGIC': name_y0y1,
-                    'IBUFDS': name_y0y1,
+                    'IBUFDS_GTE2': name_y0y1,
                 }.get(site_prefix, name_default)()
                 self.verbose and print(
                     'site %s w/ %s prefix => tag %s' %