Skip to content

Commit

Permalink
Merge pull request #1566 from antmicro/improve-063-gtp-fuzzer
Browse files Browse the repository at this point in the history
063-gtp-common-conf: get features corresponding to IBUFDS -> GTP
  • Loading branch information
acomodi committed Feb 4, 2021
2 parents 83b2072 + 8495f46 commit 53e1678
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 49 deletions.
33 changes: 33 additions & 0 deletions fuzzers/063-gtp-common-conf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
GTPE2\_COMMON Primitive Configuration fuzzer
============================================

This fuzzer is used to document the parameters corresponding to the GTPE2\_COMMON primitive.

It uses pre-built JSON containing a dictionary of parameters, each one with four attributes:

- Type: one of Binary, Integer, String, Boolean.
- Values: all possible values that this parameter can assume. In case of `BIN` types, the values list contains only the maximum value reachable.
- Digits: number of digits (or bits) required to use a parameter.
- Encoding: This is present only for `INT` types of parameters. These reflect the actual encoding of the parameter value in the bit array.

E.g.:

```json
{
"PLL0_REFCLK_DIV": {
"type": "INT",
"values": [1, 2],
"encoding": [16, 0],
"digits": 5
}
}
```

In addition, there exist wires and PIPs that allow the connections of the `GTREFCLK` ports to clocks coming from the device fabric instead of the `IBUFDS_GTE2` primitive.

In fact, if the clock comes from the device fabric, the physical `GTGREFCLK[01]` port is used instead of the `GTREFCLK[01]` one (even though the design's primitive port is always `GTREFCLK`).

In the [User Guide (pg 27)](https://www.xilinx.com/support/documentation/user_guides/ug482_7Series_GTP_Transceivers.pdf), it is stated that the `GTGREFCLK[01]` port is used for "internal testing purposes".
Using this port is highly discouraged to get the reference clock from the fabric, as the recommended way is to get the clock from an external source using the `IBUFDS_GTE2` primitive.

Therefore, in addition to the parameters, `IN_USE` and `ZINV\INV` features, this fuzzer documents also the `GTREFCLK[01]_USED` and `BOTH_GTREFCLK[01]_USED` features.
14 changes: 6 additions & 8 deletions fuzzers/063-gtp-common-conf/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,12 @@ def main():
segmk.add_site_tag(
site, "%s[%u]" % (param, i), bitstr[i])

for param, invert in [("GTGREFCLK1", 0), ("GTGREFCLK0", 0),
("PLL0LOCKDETCLK", 1), ("PLL1LOCKDETCLK",
1), ("DRPCLK", 1)]:
if invert:
segmk.add_site_tag(
site, "ZINV_" + param, 1 ^ params[param])
else:
segmk.add_site_tag(site, "INV_" + param, params[param])
for param in ["PLL0LOCKDETCLK", "PLL1LOCKDETCLK", "DRPCLK"]:
segmk.add_site_tag(site, "ZINV_" + param, 1 ^ params[param])

for param in ["GTREFCLK0_USED", "GTREFCLK1_USED",
"BOTH_GTREFCLK_USED"]:
segmk.add_site_tag(site, param, params[param])

for params in params_list:
site = params["site"]
Expand Down
114 changes: 73 additions & 41 deletions fuzzers/063-gtp-common-conf/top.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,56 @@ def main():
params_dict = {"tile_type": None}
params_list = list()

clkswing_cfg_tiles = dict()
ibufds_out_wires = dict()
for tile_name, _, site_name, site_type in gen_sites("IBUFDS_GTE2"):
# Both the IBUFDS_GTE2 in the same tile need to have
# the same CLKSWING_CFG parameter
if tile_name not in clkswing_cfg_tiles:
clkswing_cfg = random.randint(0, 3)
clkswing_cfg_tiles[tile_name] = clkswing_cfg
else:
clkswing_cfg = clkswing_cfg_tiles[tile_name]

in_use = bool(random.randint(0, 9))
params = {
"site":
site_name,
"tile":
tile_name,
"IN_USE":
in_use,
"CLKRCV_TRST":
verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"),
"CLKCM_CFG":
verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"),
"CLKSWING_CFG":
clkswing_cfg,
}

if in_use:
ibufds_out_wire = "{}_O".format(site_name)

if tile_name not in ibufds_out_wires:
ibufds_out_wires[tile_name] = list()

ibufds_out_wires[tile_name].append(
(ibufds_out_wire, int(site_name[-1]) % 2))

print("wire {};".format(ibufds_out_wire))
print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name))
print(
"""
IBUFDS_GTE2 #(
.CLKRCV_TRST({CLKRCV_TRST}),
.CLKCM_CFG({CLKCM_CFG}),
.CLKSWING_CFG({CLKSWING_CFG})
) {site} (
.O({out})
);""".format(**params, out=ibufds_out_wire))

params_list.append(params)

for tile_name, tile_type, site_name, site_type in gen_sites(
"GTPE2_COMMON"):

Expand Down Expand Up @@ -102,8 +152,7 @@ def main():
verilog_attr += """
.{}({}),""".format(param, value_str)

for param in ["GTGREFCLK1", "GTGREFCLK0", "PLL0LOCKDETCLK",
"PLL1LOCKDETCLK", "DRPCLK"]:
for param in ["PLL0LOCKDETCLK", "PLL1LOCKDETCLK", "DRPCLK"]:
is_inverted = random.randint(0, 1)

params[param] = is_inverted
Expand All @@ -114,51 +163,34 @@ def main():
verilog_attr = verilog_attr.rstrip(",")
verilog_attr += "\n)"

print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name))
print(
"""GTPE2_COMMON {attrs} {site} (
.GTREFCLK0(1'b0),
.GTREFCLK1(1'b0)
);""".format(attrs=verilog_attr, site=site_name))
verilog_ports = ""

params_list.append(params)
for param in ["GTREFCLK0_USED", "GTREFCLK1_USED",
"BOTH_GTREFCLK_USED"]:
params[param] = 0

clkswing_cfg_tiles = dict()
for tile_name, _, site_name, site_type in gen_sites("IBUFDS_GTE2"):
# Both the IBUFDS_GTE2 in the same tile need to have
# the same CLKSWING_CFG parameter
if tile_name not in clkswing_cfg_tiles:
clkswing_cfg = random.randint(0, 3)
clkswing_cfg_tiles[tile_name] = clkswing_cfg
else:
clkswing_cfg = clkswing_cfg_tiles[tile_name]
if tile_name in ibufds_out_wires:
gtrefclk_ports_used = 0

in_use = bool(random.randint(0, 9))
params = {
"site":
site_name,
"tile":
tile_name,
"IN_USE":
in_use,
"CLKRCV_TRST":
verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"),
"CLKCM_CFG":
verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"),
"CLKSWING_CFG":
clkswing_cfg,
}
for wire, location in ibufds_out_wires[tile_name]:
if random.random() < 0.5:
continue

verilog_ports += """
.GTREFCLK{}({}),""".format(location, wire)

gtrefclk_ports_used += 1
params["GTREFCLK{}_USED".format(location)] = 1

if gtrefclk_ports_used == 2:
params["BOTH_GTREFCLK_USED"] = 1

if in_use:
print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name))
print(
"""
IBUFDS_GTE2 #(
.CLKRCV_TRST({CLKRCV_TRST}),
.CLKCM_CFG({CLKCM_CFG}),
.CLKSWING_CFG({CLKSWING_CFG})
) {site} (
);""".format(**params))
"""GTPE2_COMMON {attrs} {site} (
{ports}
.DRPCLK(1'b0)
);""".format(attrs=verilog_attr, ports=verilog_ports, site=site_name))

params_list.append(params)

Expand Down

0 comments on commit 53e1678

Please sign in to comment.