diff --git a/prjxray/util.py b/prjxray/util.py index a282fad7..6c285795 100644 --- a/prjxray/util.py +++ b/prjxray/util.py @@ -49,6 +49,14 @@ def get_part_information(db_root, part): return part +def set_part_information(db_root, information): + filename = os.path.join(db_root, "mapping", "parts.yaml") + with open(filename, 'w+') as stream: + yaml.dump(information, stream) + assert os.path.isfile(filename), \ + "Mapping file {} does not exists".format(filename) + + def get_part_resources(file_path, part): filename = os.path.join(file_path, "resources.yaml") assert os.path.isfile(filename), \ @@ -60,6 +68,14 @@ def get_part_resources(file_path, part): return res +def set_part_resources(file_path, information): + filename = os.path.join(file_path, "resources.yaml") + with open(filename, 'w+') as stream: + yaml.dump(information, stream) + assert os.path.isfile(filename), \ + "Mapping file {} does not exists".format(filename) + + def get_fabric_for_part(db_root, part): filename = os.path.join(db_root, "mapping", "devices.yaml") assert os.path.isfile(filename), \ @@ -73,6 +89,24 @@ def get_fabric_for_part(db_root, part): return device['fabric'] +def get_devices(db_root): + filename = os.path.join(db_root, "mapping", "devices.yaml") + assert os.path.isfile(filename), \ + "Mapping file {} does not exists".format(filename) + with open(filename, 'r') as stream: + device_mapping = yaml.load(stream, Loader=yaml.FullLoader) + return device_mapping + + +def get_parts(db_root): + filename = os.path.join(db_root, "mapping", "parts.yaml") + assert os.path.isfile(filename), \ + "Mapping file {} does not exists".format(filename) + with open(filename, 'r') as stream: + part_mapping = yaml.load(stream, Loader=yaml.FullLoader) + return part_mapping + + def roi_xy(): x1 = int(os.getenv('XRAY_ROI_GRID_X1', 0)) x2 = int(os.getenv('XRAY_ROI_GRID_X2', 58)) diff --git a/utils/roi_all.py b/utils/roi_all.py new file mode 100755 index 00000000..660f9521 --- /dev/null +++ b/utils/roi_all.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2017-2021 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 +import argparse +import yaml +import subprocess +import os +import re +from prjxray import util + + +def main(): + """Rois all parts for a family by calling "make roi_only" over all parts + with the same device as XRAY_PART. + + Example: + prjxray$ ./utils/roi_all.py --db-root database/artix7/ --part xc7a100tfgg676-1 + """ + env = os.environ.copy() + db_root = util.get_db_root() + assert db_root + part = util.get_part() + assert part + + information = util.get_part_information(db_root, part) + + valid_devices = [] + for name, device in util.get_devices(db_root).items(): + if device['fabric'] == information['device']: + valid_devices.append(name) + + for part, data in util.get_parts(db_root).items(): + if data['device'] in valid_devices: + command = "make roi_only" + env['XRAY_PART'] = part + cwd = os.getenv('XRAY_FUZZERS_DIR') + subprocess.run(command.split(' '), check=True, env=env, cwd=cwd) + + +if __name__ == '__main__': + main() diff --git a/utils/update_parts.py b/utils/update_parts.py new file mode 100755 index 00000000..e143b500 --- /dev/null +++ b/utils/update_parts.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2017-2021 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 +import argparse +import yaml +import subprocess +import os +import re +from prjxray import util + + +def main(): + """Tool to update all supported, available parts in a mapping file for the + given family. It will read all parts from Vivado, filter them by the family, + and will only add these where a device exists for. + + Example: + prjxray$ ./utils/update_parts.py artix7 --db-root database/artix7/ + """ + parser = argparse.ArgumentParser( + description="Saves all supported parts for a family.") + + parser.add_argument( + 'family', + help="Name of the device family.", + choices=['artix7', 'kintex7', 'zynq7']) + util.db_root_arg(parser) + + args = parser.parse_args() + env = os.environ.copy() + # Vivado does not use the suffix 7 for zynq + env['FILTER'] = "zynq" if args.family == "zynq7" else args.family + cwd = os.path.dirname(os.path.abspath(__file__)) + information = {} + + # Read all supported devices + supported_devices = util.get_devices(args.db_root).keys() + + # Fetch all parts for a family (FILTER = family) + command = "{} -mode batch -source update_parts.tcl".format( + env['XRAY_VIVADO']) + result = subprocess.run( + command.split(' '), + check=True, + env=env, + cwd=cwd, + stdout=subprocess.PIPE) + parts = result.stdout.decode('utf-8').split('# }\n')[1].splitlines()[:-1] + + # Splits up the part number and checks if the device is supported + for part in parts: + part, device, package, speed = part.split(',') + if device in supported_devices: + information[part] = { + 'device': device, + 'package': package, + 'speedgrade': speed[1:] + } + else: + print("Part {} has an unsupported device {}".format(part, device)) + + # Overwrites the /parts.yaml file completly with new data + util.set_part_information(args.db_root, information) + + +if __name__ == '__main__': + main() diff --git a/utils/update_parts.tcl b/utils/update_parts.tcl new file mode 100644 index 00000000..01cba7b7 --- /dev/null +++ b/utils/update_parts.tcl @@ -0,0 +1,14 @@ +# Copyright (C) 2017-2021 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 +# Writes a JSON5 to filename containing timing for current design. +# This can be used with create_timing_worksheet_db.py to compare prjxray model +# with Vivado timing model outputs. +set parts [get_parts -filter "FAMILY == $::env(FILTER)"] +foreach part $parts { + puts "$part,[get_property DEVICE $part],[get_property PACKAGE $part],[get_property SPEED $part]" +} diff --git a/utils/update_resources.py b/utils/update_resources.py new file mode 100755 index 00000000..275aea6c --- /dev/null +++ b/utils/update_resources.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2017-2021 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 +import argparse +import yaml +import subprocess +import os +import re +from prjxray import util + + +def main(): + """Tool to update the used resources by the fuzzers for each available part. + + Example: + prjxray$ ./utils/update_resources.py artix7 --db-root database/artix7/ + """ + parser = argparse.ArgumentParser( + description="Saves all resource information for a family.") + + parser.add_argument( + 'family', + help="Name of the device family.", + choices=['artix7', 'kintex7', 'zynq7']) + util.db_root_arg(parser) + + args = parser.parse_args() + env = os.environ.copy() + cwd = os.path.dirname(os.path.abspath(__file__)) + resource_path = os.path.join( + os.getenv('XRAY_DIR'), 'settings', args.family) + information = {} + + parts = util.get_parts(args.db_root) + for part in parts.keys(): + print("Find pins for {}".format(part)) + env['XRAY_PART'] = part + # Asks with get_package_pins and different filters for pins with + # specific properties. + command = "{} -mode batch -source update_resources.tcl".format( + 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(' ') + pins = { + 0: clk_pins[0], + 1: data_pins[0], + 2: data_pins[int(len(data_pins) / 2)], + 3: data_pins[-1] + } + information[part] = {'pins': pins} + + # Overwrites the /resources.yaml file completly with new data + util.set_part_resources(resource_path, information) + + +if __name__ == '__main__': + main() diff --git a/utils/update_resources.tcl b/utils/update_resources.tcl new file mode 100644 index 00000000..a95f1e06 --- /dev/null +++ b/utils/update_resources.tcl @@ -0,0 +1,25 @@ +# Copyright (C) 2017-2021 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 +# Writes a JSON5 to filename containing timing for current design. +# This can be used with create_timing_worksheet_db.py to compare prjxray model +# with Vivado timing model outputs. +link_design -part $::env(XRAY_PART) + +# one pin -> 0 +set clk_pins [get_package_pins -filter "IS_CLK_CAPABLE"] + +# three pins -> 1, 2, 3 on HR banks only +set banks [get_iobanks -filter "BANK_TYPE==BT_HIGH_RANGE"] + +set data_pins "" +foreach bank [split $banks " "] { + append data_pins " " [get_package_pins -filter "IS_GENERAL_PURPOSE && BANK==$bank"] +} + +puts $clk_pins +puts $data_pins