mirror of https://github.com/openXC7/prjxray.git
Merge pull request #1614 from antmicro/add-gtp-ports-attrs-file
gtp: generate attributes and ports files to add to the db
This commit is contained in:
commit
0d9418a908
|
|
@ -0,0 +1,82 @@
|
||||||
|
===============
|
||||||
|
cell data files
|
||||||
|
===============
|
||||||
|
|
||||||
|
The *cell data* files are meant for specific primitives which have a common attribute format. The data contained in these files is generated/copied from the corresponding primitives' fuzzers.
|
||||||
|
|
||||||
|
Naming convention
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The naming scheme for the cell data files is the following::
|
||||||
|
|
||||||
|
<primitive_name>_<data_file_type>.json
|
||||||
|
|
||||||
|
Example files:
|
||||||
|
|
||||||
|
- ``gtpe2_common_attrs.json``
|
||||||
|
- ``gtpe2_channel_ports.json``
|
||||||
|
|
||||||
|
File format
|
||||||
|
-----------
|
||||||
|
|
||||||
|
There are two main data file types:
|
||||||
|
|
||||||
|
- *Ports*
|
||||||
|
- *Attributes*
|
||||||
|
|
||||||
|
Attributes files
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This is a JSON file containing a dictionary of parameters, each one with, at most, four attributes:
|
||||||
|
|
||||||
|
- Type: one of BIN, INT, STR, BOOL.
|
||||||
|
- 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 enable 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.
|
||||||
|
|
||||||
|
As an example of parameter please, refer to the following::
|
||||||
|
|
||||||
|
{
|
||||||
|
"PLL0_REFCLK_DIV": {
|
||||||
|
"type": "INT",
|
||||||
|
"values": [1, 2],
|
||||||
|
"encoding": [16, 0],
|
||||||
|
"digits": 5
|
||||||
|
},
|
||||||
|
"RXLPMRESET_TIME": {
|
||||||
|
"type": "BIN",
|
||||||
|
"values": [127],
|
||||||
|
"digits": 7
|
||||||
|
},
|
||||||
|
"RX_XCLK_SEL": {
|
||||||
|
"type": "STR",
|
||||||
|
"values": ["RXREC", "RXUSR"],
|
||||||
|
"digits": 1
|
||||||
|
},
|
||||||
|
"TX_LOOPBACK_DRIVE_HIZ": {
|
||||||
|
"type": "BOOL",
|
||||||
|
"values": ["FALSE", "TRUE"],
|
||||||
|
"digits": 1
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ports files
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
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.
|
||||||
|
- Width: Indicates the width of the port bus.
|
||||||
|
|
||||||
|
As an example of parameter please, refer to the following::
|
||||||
|
|
||||||
|
{
|
||||||
|
"CFGRESET": {
|
||||||
|
"direction": "input",
|
||||||
|
"width": 1
|
||||||
|
},
|
||||||
|
"CLKRSVD0": {
|
||||||
|
"direction": "input",
|
||||||
|
"width": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,3 +13,4 @@ that are common for all Xilinx series 7 chip architectures.
|
||||||
tile_type
|
tile_type
|
||||||
ppips
|
ppips
|
||||||
mask
|
mask
|
||||||
|
cell_data
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ SPECIMENS := $(addprefix ${BUILD_DIR}/specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||||
FUZDIR ?= ${PWD}
|
FUZDIR ?= ${PWD}
|
||||||
|
|
||||||
|
CELLS_DATA_DIR = ${XRAY_FAMILY_DIR}/cells_data
|
||||||
|
|
||||||
all: database
|
all: database
|
||||||
|
|
||||||
|
|
@ -36,7 +37,17 @@ clean:
|
||||||
|
|
||||||
.PHONY: all run clean
|
.PHONY: all run clean
|
||||||
|
|
||||||
database: ${BUILD_DIR}/segbits_gtp_common.db
|
# These are pins that are hard to parse as a regexp given that the port name ends with a number, which is misinterpreted
|
||||||
|
# as the index in the port bus
|
||||||
|
SPECIAL_PINS = PLLRSVD1,PLLRSVD2,GTREFCLK0,GTREFCLK1,GTGREFCLK0,GTGREFCLK1,GTEASTREFCLK0,GTEASTREFCLK1,GTWESTREFCLK0,GTWESTREFCLK1,REFCLKOUTMONITOR0,REFCLKOUTMONITOR1
|
||||||
|
|
||||||
|
$(BUILD_DIR)/gtpe2_common_ports.csv: generate_ports.tcl
|
||||||
|
env FILE_NAME=$(BUILD_DIR)/gtpe2_common_pins.csv ${XRAY_VIVADO} -mode batch -source generate_ports.tcl
|
||||||
|
|
||||||
|
$(BUILD_DIR)/gtpe2_common_ports.json: $(BUILD_DIR)/gtpe2_common_ports.csv
|
||||||
|
python3 ${XRAY_UTILS_DIR}/make_ports.py $(BUILD_DIR)/gtpe2_common_pins.csv $(BUILD_DIR)/gtpe2_common_ports.json --special-pins $(SPECIAL_PINS)
|
||||||
|
|
||||||
|
database: ${BUILD_DIR}/segbits_gtp_common.db $(BUILD_DIR)/gtpe2_common_ports.json
|
||||||
|
|
||||||
${BUILD_DIR}/segbits_gtp_common.rdb: $(SPECIMENS_OK)
|
${BUILD_DIR}/segbits_gtp_common.rdb: $(SPECIMENS_OK)
|
||||||
${XRAY_SEGMATCH} -o ${BUILD_DIR}/segbits_gtp_common.rdb $$(find $(SPECIMENS) -name "segdata_gtp_common*")
|
${XRAY_SEGMATCH} -o ${BUILD_DIR}/segbits_gtp_common.rdb $$(find $(SPECIMENS) -name "segdata_gtp_common*")
|
||||||
|
|
@ -48,6 +59,9 @@ ${BUILD_DIR}/segbits_gtp_common.db: ${BUILD_DIR}/segbits_gtp_common.rdb
|
||||||
${XRAY_MASKMERGE} ${BUILD_DIR}/mask_gtp_common.db $$(find $(SPECIMENS) -name "segdata_gtp_common*")
|
${XRAY_MASKMERGE} ${BUILD_DIR}/mask_gtp_common.db $$(find $(SPECIMENS) -name "segdata_gtp_common*")
|
||||||
|
|
||||||
pushdb:
|
pushdb:
|
||||||
|
mkdir -p $(CELLS_DATA_DIR)
|
||||||
|
cp attrs.json $(CELLS_DATA_DIR)/gtpe2_common_attrs.json
|
||||||
|
cp $(BUILD_DIR)/gtpe2_common_ports.json $(CELLS_DATA_DIR)/gtpe2_common_ports.json
|
||||||
BUILD_DIR=$(BUILD_DIR) source pushdb.sh
|
BUILD_DIR=$(BUILD_DIR) source pushdb.sh
|
||||||
|
|
||||||
.PHONY: database pushdb
|
.PHONY: database pushdb
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,8 @@ def main():
|
||||||
tile_type = params_dict["tile_type"]
|
tile_type = params_dict["tile_type"]
|
||||||
params_list = params_dict["params"]
|
params_list = params_dict["params"]
|
||||||
|
|
||||||
|
sites_in_tile = dict()
|
||||||
|
|
||||||
for params in params_list:
|
for params in params_list:
|
||||||
site = params["site"]
|
site = params["site"]
|
||||||
tile = params["tile"]
|
tile = params["tile"]
|
||||||
|
|
@ -69,6 +71,8 @@ def main():
|
||||||
if "GTPE2_COMMON" not in site:
|
if "GTPE2_COMMON" not in site:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
sites_in_tile[tile] = site
|
||||||
|
|
||||||
in_use = params["IN_USE"]
|
in_use = params["IN_USE"]
|
||||||
|
|
||||||
segmk.add_site_tag(site, "IN_USE", in_use)
|
segmk.add_site_tag(site, "IN_USE", in_use)
|
||||||
|
|
@ -109,7 +113,7 @@ def main():
|
||||||
"BOTH_GTREFCLK_USED"]:
|
"BOTH_GTREFCLK_USED"]:
|
||||||
segmk.add_site_tag(site, param, params[param])
|
segmk.add_site_tag(site, param, params[param])
|
||||||
|
|
||||||
segmk.add_tile_tag(tile, "ENABLE_DRP", params["ENABLE_DRP"])
|
segmk.add_site_tag(site, "ENABLE_DRP", params["ENABLE_DRP"])
|
||||||
|
|
||||||
for params in params_list:
|
for params in params_list:
|
||||||
site = params["site"]
|
site = params["site"]
|
||||||
|
|
@ -132,9 +136,11 @@ def main():
|
||||||
value=params["CLKSWING_CFG"], digits=2)[::-1]
|
value=params["CLKSWING_CFG"], digits=2)[::-1]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
gtp_common_site = sites_in_tile[tile]
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
segmk.add_tile_tag(
|
segmk.add_site_tag(
|
||||||
tile, "IBUFDS_GTE2.CLKSWING_CFG[%u]" % (i), bitstr[i])
|
gtp_common_site, "IBUFDS_GTE2.CLKSWING_CFG[%u]" % (i),
|
||||||
|
bitstr[i])
|
||||||
|
|
||||||
if tile_type.startswith("GTP_COMMON_MID"):
|
if tile_type.startswith("GTP_COMMON_MID"):
|
||||||
bitfilter = bitfilter_gtp_common_mid
|
bitfilter = bitfilter_gtp_common_mid
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2017-2020 The Project X-Ray Authors
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a ISC-style
|
||||||
|
# license that can be found in the LICENSE file or at
|
||||||
|
# https://opensource.org/licenses/ISC
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
create_project -force -name design -part $::env(XRAY_PART)
|
||||||
|
set_property design_mode PinPlanning [current_fileset]
|
||||||
|
open_io_design -name io_1
|
||||||
|
|
||||||
|
dump_pins $::env(FILE_NAME) GTPE2_COMMON
|
||||||
|
|
@ -16,6 +16,7 @@ SPECIMENS := $(addprefix ${BUILD_DIR}/specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||||
FUZDIR ?= ${PWD}
|
FUZDIR ?= ${PWD}
|
||||||
|
|
||||||
|
CELLS_DATA_DIR = ${XRAY_FAMILY_DIR}/cells_data
|
||||||
|
|
||||||
all: database
|
all: database
|
||||||
|
|
||||||
|
|
@ -34,7 +35,17 @@ clean:
|
||||||
|
|
||||||
.PHONY: all run clean
|
.PHONY: all run clean
|
||||||
|
|
||||||
database: ${BUILD_DIR}/segbits_gtp_channelx.db
|
# These are pins that are hard to parse as a regexp given that the port name ends with a number, which is misinterpreted
|
||||||
|
# as the index in the port bus
|
||||||
|
SPECIAL_PINS = CLKRSVD0,CLKRSVD1,GTREFCLK0,GTREFCLK1,GTNORTHREFCLK0,GTNORTHREFCLK1,GTSOUTHREFCLK0,GTSOUTHREFCLK1,RXUSRCLK,RXUSRCLK2,TXUSRCLK,TXUSRCLK2,RXOSINTID0,PMARSVDIN0,PMARSVDIN1,PMARSVDIN2,PMARSVDIN3,PMARSVDIN4,PMARSVDOUT0,PMARSVDOUT1
|
||||||
|
|
||||||
|
$(BUILD_DIR)/gtpe2_channel_ports.csv:
|
||||||
|
env FILE_NAME=$(BUILD_DIR)/gtpe2_channel_pins.csv ${XRAY_VIVADO} -mode batch -source generate_ports.tcl
|
||||||
|
|
||||||
|
$(BUILD_DIR)/gtpe2_channel_ports.json: $(BUILD_DIR)/gtpe2_channel_ports.csv
|
||||||
|
python3 ${XRAY_UTILS_DIR}/make_ports.py $(BUILD_DIR)/gtpe2_channel_pins.csv $(BUILD_DIR)/gtpe2_channel_ports.json --special-pins $(SPECIAL_PINS)
|
||||||
|
|
||||||
|
database: ${BUILD_DIR}/segbits_gtp_channelx.db $(BUILD_DIR)/gtpe2_channel_ports.json
|
||||||
|
|
||||||
${BUILD_DIR}/segbits_gtp_channelx.rdb: $(SPECIMENS_OK)
|
${BUILD_DIR}/segbits_gtp_channelx.rdb: $(SPECIMENS_OK)
|
||||||
${XRAY_SEGMATCH} -c 9 -o ${BUILD_DIR}/segbits_gtp_channelx.rdb $$(find $(SPECIMENS) -name "segdata_gtp_channel_[0123]*")
|
${XRAY_SEGMATCH} -c 9 -o ${BUILD_DIR}/segbits_gtp_channelx.rdb $$(find $(SPECIMENS) -name "segdata_gtp_channel_[0123]*")
|
||||||
|
|
@ -46,6 +57,9 @@ ${BUILD_DIR}/segbits_gtp_channelx.db: ${BUILD_DIR}/segbits_gtp_channelx.rdb
|
||||||
${XRAY_MASKMERGE} ${BUILD_DIR}/mask_gtp_channelx.db $$(find $(SPECIMENS) -name "segdata_gtp_channel_[0123]*")
|
${XRAY_MASKMERGE} ${BUILD_DIR}/mask_gtp_channelx.db $$(find $(SPECIMENS) -name "segdata_gtp_channel_[0123]*")
|
||||||
|
|
||||||
pushdb:
|
pushdb:
|
||||||
|
mkdir -p $(CELLS_DATA_DIR)
|
||||||
|
cp attrs.json $(CELLS_DATA_DIR)/gtpe2_channel_attrs.json
|
||||||
|
cp $(BUILD_DIR)/gtpe2_channel_ports.json $(CELLS_DATA_DIR)/gtpe2_channel_ports.json
|
||||||
BUILD_DIR=$(BUILD_DIR) source pushdb.sh
|
BUILD_DIR=$(BUILD_DIR) source pushdb.sh
|
||||||
|
|
||||||
.PHONY: database pushdb
|
.PHONY: database pushdb
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2017-2020 The Project X-Ray Authors
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a ISC-style
|
||||||
|
# license that can be found in the LICENSE file or at
|
||||||
|
# https://opensource.org/licenses/ISC
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
create_project -force -name design -part $::env(XRAY_PART)
|
||||||
|
set_property design_mode PinPlanning [current_fileset]
|
||||||
|
open_io_design -name io_1
|
||||||
|
|
||||||
|
dump_pins $::env(FILE_NAME) GTPE2_CHANNEL
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017-2020 The Project X-Ray Authors.
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a ISC-style
|
||||||
|
# license that can be found in the LICENSE file or at
|
||||||
|
# https://opensource.org/licenses/ISC
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: ISC
|
||||||
|
"""
|
||||||
|
This script loads the pin dump of the desired BEL from Vivado and groups pins into ports.
|
||||||
|
|
||||||
|
Ports that are not connected to the PL are not included. These ports are usually test and
|
||||||
|
debug related ports, which are not useful from a P&R perspective.
|
||||||
|
|
||||||
|
Ports are then written to a JSON file.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
BUS_REGEX = re.compile("(.*[A-Z_])([0-9]+)$")
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=__doc__,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
|
||||||
|
parser.add_argument("csv", type=str, help="BEL pin dump file")
|
||||||
|
parser.add_argument(
|
||||||
|
"json",
|
||||||
|
type=str,
|
||||||
|
help="Output JSON file with BEL pins grouped into ports")
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--special-pins",
|
||||||
|
default="",
|
||||||
|
type=str,
|
||||||
|
required=False,
|
||||||
|
help="Some pins cannot be decoded with the regex")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Load pin dump
|
||||||
|
with open(args.csv, "r") as fp:
|
||||||
|
pin_dump = list(csv.DictReader(fp))
|
||||||
|
|
||||||
|
# Group pins into ports
|
||||||
|
ports = defaultdict(lambda: {"direction": None, "width": 0})
|
||||||
|
|
||||||
|
special_pins = args.special_pins.split(",")
|
||||||
|
|
||||||
|
for pin in list(pin_dump):
|
||||||
|
pin_name = pin["name"]
|
||||||
|
|
||||||
|
name = None
|
||||||
|
if pin_name in special_pins:
|
||||||
|
# Full match
|
||||||
|
name = pin_name
|
||||||
|
else:
|
||||||
|
# Partial match
|
||||||
|
for special_pin in special_pins:
|
||||||
|
if pin_name.startswith(special_pin):
|
||||||
|
name = special_pin
|
||||||
|
break
|
||||||
|
|
||||||
|
if name is None:
|
||||||
|
match = BUS_REGEX.match(pin_name)
|
||||||
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
else:
|
||||||
|
name = pin_name
|
||||||
|
|
||||||
|
# Get direction
|
||||||
|
is_input = int(pin["is_input"])
|
||||||
|
is_output = int(pin["is_output"])
|
||||||
|
|
||||||
|
if is_input:
|
||||||
|
direction = "input"
|
||||||
|
elif is_output:
|
||||||
|
direction = "output"
|
||||||
|
else:
|
||||||
|
assert False, pin
|
||||||
|
|
||||||
|
# Add to port
|
||||||
|
port = ports[name]
|
||||||
|
|
||||||
|
if port["direction"] is None:
|
||||||
|
port["direction"] = direction
|
||||||
|
else:
|
||||||
|
assert port["direction"] == direction, (port, direction, name)
|
||||||
|
|
||||||
|
port["width"] += 1
|
||||||
|
|
||||||
|
# Write pin ports to a JSON file
|
||||||
|
with open(args.json, "w") as fp:
|
||||||
|
json.dump(ports, fp, indent=1, sort_keys=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue