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
|
||||
ppips
|
||||
mask
|
||||
cell_data
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ SPECIMENS := $(addprefix ${BUILD_DIR}/specimen_,$(shell seq -f '%03.0f' $(N)))
|
|||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
FUZDIR ?= ${PWD}
|
||||
|
||||
CELLS_DATA_DIR = ${XRAY_FAMILY_DIR}/cells_data
|
||||
|
||||
all: database
|
||||
|
||||
|
|
@ -36,7 +37,17 @@ 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)
|
||||
${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*")
|
||||
|
||||
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
|
||||
|
||||
.PHONY: database pushdb
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ def main():
|
|||
tile_type = params_dict["tile_type"]
|
||||
params_list = params_dict["params"]
|
||||
|
||||
sites_in_tile = dict()
|
||||
|
||||
for params in params_list:
|
||||
site = params["site"]
|
||||
tile = params["tile"]
|
||||
|
|
@ -69,6 +71,8 @@ def main():
|
|||
if "GTPE2_COMMON" not in site:
|
||||
continue
|
||||
|
||||
sites_in_tile[tile] = site
|
||||
|
||||
in_use = params["IN_USE"]
|
||||
|
||||
segmk.add_site_tag(site, "IN_USE", in_use)
|
||||
|
|
@ -109,7 +113,7 @@ def main():
|
|||
"BOTH_GTREFCLK_USED"]:
|
||||
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:
|
||||
site = params["site"]
|
||||
|
|
@ -132,9 +136,11 @@ def main():
|
|||
value=params["CLKSWING_CFG"], digits=2)[::-1]
|
||||
]
|
||||
|
||||
gtp_common_site = sites_in_tile[tile]
|
||||
for i in range(2):
|
||||
segmk.add_tile_tag(
|
||||
tile, "IBUFDS_GTE2.CLKSWING_CFG[%u]" % (i), bitstr[i])
|
||||
segmk.add_site_tag(
|
||||
gtp_common_site, "IBUFDS_GTE2.CLKSWING_CFG[%u]" % (i),
|
||||
bitstr[i])
|
||||
|
||||
if tile_type.startswith("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))
|
||||
FUZDIR ?= ${PWD}
|
||||
|
||||
CELLS_DATA_DIR = ${XRAY_FAMILY_DIR}/cells_data
|
||||
|
||||
all: database
|
||||
|
||||
|
|
@ -34,7 +35,17 @@ 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)
|
||||
${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]*")
|
||||
|
||||
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
|
||||
|
||||
.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