diff --git a/minitests/iostandard/dump_iobs.tcl b/minitests/iostandard/dump_iobs.tcl index e7b71d46..4902a4e0 100644 --- a/minitests/iostandard/dump_iobs.tcl +++ b/minitests/iostandard/dump_iobs.tcl @@ -1,7 +1,7 @@ proc dump_iobs {file_name} { set fp [open $file_name w] - puts $fp "tile,site_name,site_type,clock_region,bank,is_bonded,is_clock,is_global_clock,is_vref" + puts $fp "tile,site_name,site_type,clock_region,bank,pkg_pin,is_bonded,is_clock,is_global_clock,is_vref" foreach tile [get_tiles *IOB33*] { foreach site [get_sites -of_objects $tile] { diff --git a/minitests/iostandard/features/Makefile b/minitests/iostandard/features/Makefile index 32c41f07..35e393b1 100644 --- a/minitests/iostandard/features/Makefile +++ b/minitests/iostandard/features/Makefile @@ -1,7 +1,7 @@ -PART=xc7a50tfgg484-1 -VIVADO_PART=xc7a50tfgg484-1 +PART?=xc7a50tfgg484-1 +VIVADO_PART?=$(PART) -BIT2FASM_ARGS= --part "$(XRAY_DIR)/database/artix7/$(PART)" --verbose +BIT2FASM_ARGS= --part "$(XRAY_DIR)/database/$(XRAY_DATABASE)/$(PART)" --verbose DESIGN_FILES=$(wildcard design*.v) CSV_FILES=$(subst .v,.csv,$(DESIGN_FILES)) diff --git a/minitests/iostandard/features/README.md b/minitests/iostandard/features/README.md index 8ff7737e..71b30bce 100644 --- a/minitests/iostandard/features/README.md +++ b/minitests/iostandard/features/README.md @@ -1,6 +1,6 @@ # IOSTANDARD feature correlation minitest -This test checks which fasm features present in the db are set for given IO settings (IOSTANDARD + DRIVE + SLEW) and for which IOB type (IBUF, OBUF, IOBUF). It also checks what features are set on unused IOBs of a given bank in which active IOBs are instantiated. To avoid conflicts, a single iosettings combination is used within an IO bank. +This test checks which fasm features present in the db are set for given IO settings (IOSTANDARD + DRIVE + SLEW) and for which IOB type (IBUF, OBUF, IOBUF, IBUFDS, OBUFDS, IOBUFDS). It also checks what features are set on unused IOBs of a given bank in which active IOBs are instantiated. To avoid conflicts, a single iosettings combination is used within an IO bank. ## Running the minitest diff --git a/minitests/iostandard/features/analyze.py b/minitests/iostandard/features/analyze.py index b5203d82..c18c0464 100644 --- a/minitests/iostandard/features/analyze.py +++ b/minitests/iostandard/features/analyze.py @@ -1,3 +1,12 @@ +""" +This script performs the analysis of disassembled bitstream and design information. +It correlates presence/absence of particular fasm features in the bitstream +with presence/absence of a particular IOB type. It also checks for features +that are set for unused IOBs that are in the same bank as the used ones. + +The list of available fasm features is read from the prjxray database. The +analysis result is written to a CSV file. +""" import os import argparse import json @@ -44,6 +53,13 @@ def load_iob_segbits(): def correlate_features(features, tile, site, set_features): """ Correlate each feature with the fasm disassembly for given tile/site. + + Given a set of all possible fasm features (for an IOB) in the first + argument, checks whether they are set or cleared for the given tile+site in + a design. The parameter set_features contains fasm dissassembly of the + design. + + Returns a list of tuples with feature names and whether they are set or not. """ result = [] @@ -152,7 +168,7 @@ def run(): csv_data[iosettings][feature] = s # Write header - line = [""] + sorted(features) + line = ["iosettings"] + sorted(features) fp.write(",".join(line) + "\n") # Write data diff --git a/minitests/iostandard/features/generate.py b/minitests/iostandard/features/generate.py index 470257d3..c08e6e7f 100644 --- a/minitests/iostandard/features/generate.py +++ b/minitests/iostandard/features/generate.py @@ -1,6 +1,7 @@ import os import random import json +import csv from collections import defaultdict try: @@ -15,30 +16,17 @@ def load_iob_sites(file_name): """ Loads IOB site dump from the given CSV file. """ - iob_sites = defaultdict(lambda: []) + # Load the data with open(file_name, "r") as fp: - fp.readline() + data = [row for row in csv.DictReader(fp)] - for line in fp: - - fields = line.split(",") - if len(fields) != 10: - continue - - iob_sites[fields[3]].append( - { - "tile": fields[0], - "name": fields[1], - "type": fields[2], - "bank": fields[4], - "pkg_pin": fields[5], - "is_bonded": bool(int(fields[6])), - "is_clock": bool(int(fields[7])), - "is_global_clock": bool(int(fields[8])), - "is_vref": bool(int(fields[9])), - }) + # Index IOB site data by clock regions + iob_sites = defaultdict(lambda: []) + for site_data in data: + iob_sites[site_data["clock_region"]].append(site_data) + print(data) return iob_sites @@ -133,14 +121,14 @@ def run(): tiles = defaultdict(lambda: {}) for site in sites: - site_to_pkg_pin[site["name"]] = site["pkg_pin"] - if site["type"] == "IOB33M": + site_to_pkg_pin[site["site_name"]] = site["pkg_pin"] + if site["site_type"] == "IOB33M": tiles[site["tile"]]["M"] = site - if site["type"] == "IOB33S": + if site["site_type"] == "IOB33S": tiles[site["tile"]]["S"] = site for sites in tiles.values(): - master_to_slave[sites["M"]["name"]] = sites["S"]["name"] + master_to_slave[sites["M"]["site_name"]] = sites["S"]["site_name"] # Generate designs iosettings_gen = gen_iosettings() @@ -164,10 +152,10 @@ def run(): # Get sites sites = [ ( - site["name"], - site["type"], + site["site_name"], + site["site_type"], ) for site in iob_sites[region] if site["is_bonded"] - and not site["is_vref"] and "SING" not in site["tile"] + and not int(site["is_vref"]) and "SING" not in site["tile"] ] if not len(sites): continue @@ -205,12 +193,13 @@ def run(): "inout": used_sites[4:5], }) print(region, iosettings) - print("----") # No more if len(region_data) == 0: break + print("----") + # Generate the design verilog = """ module top ( @@ -473,7 +462,8 @@ module top ( "IOB33S": "IOB_Y1" } site_to_loc = { - s["name"]: "{}.{}".format(s["tile"], type_to_loc[s["type"]]) + s["site_name"]: "{}.{}".format( + s["tile"], type_to_loc[s["site_type"]]) for s in iob_sites[data["region"]] } diff --git a/minitests/iostandard/features/snippets.py b/minitests/iostandard/features/snippets.py index d0a25a4d..be8e5ea1 100644 --- a/minitests/iostandard/features/snippets.py +++ b/minitests/iostandard/features/snippets.py @@ -1,5 +1,18 @@ +""" +This script generates code snippets for cell definition, technology mapping and +VPR architecture definition. It reads correlation of IOB fasm features with +IO standard settings such as IOSTANDARD, DRIVE and SLEW and generates: + +- Verilog model parameter definitions that match fasm features. +- Xilinx's IOB parameter translation to those features. +- Assignment of model parameters to the actual fasm features for VPR arch def. + +Generated code snippets need to be manually copied to relevant places in the +target code / arch. def. +""" import os import argparse +import csv from collections import namedtuple @@ -12,31 +25,21 @@ def load_feature_data(fname): """ Load feature vs. IO settings correlation data from a CSV file. """ + + # Load the data from CSV feature_data = {} - - # Open the file with open(fname, "r") as fp: + for line in csv.DictReader(fp): - # Header - line = fp.readline() - features = line.strip().split(",")[1:] - - # Data - for line in fp: - fields = line.strip().split(",") - - # IOSettings - parts = fields[0].split(".") + # Get IOSettings + ios_parts = line["iosettings"].split(".") ios = IOSettings( - parts[0], - int(parts[1][1:]) if parts[1][1:] != "_FIXED" else None, - parts[2], "DIFF_" in parts[0]) + ios_parts[0], + int(ios_parts[1][1:]) if ios_parts[1][1:] != "_FIXED" else + None, ios_parts[2], "DIFF_" in ios_parts[0]) # Feature activity - feature_data[ios] = { - f: fields[1 + i] - for i, f in enumerate(features) - } + feature_data[ios] = {k: line[k] for k in list(line.keys())[1:]} return feature_data