mirror of https://github.com/lnis-uofu/SOFA.git
162 lines
6.7 KiB
Python
162 lines
6.7 KiB
Python
|
|
import argparse
|
|
import json
|
|
import os
|
|
import yaml
|
|
import logging
|
|
import xml.etree.ElementTree as ET
|
|
from itertools import chain
|
|
from pprint import pprint
|
|
|
|
logger = logging.getLogger('Bitstream conversion')
|
|
|
|
#PROJ_NAME = os.environ.get('PROJ_NAME')
|
|
|
|
|
|
def formatter(prog): return argparse.HelpFormatter(prog, max_help_position=60)
|
|
|
|
|
|
def get_module_of_instance(mapping, instance):
|
|
for module, instance_list in mapping.items():
|
|
if instance in instance_list:
|
|
return module
|
|
return None
|
|
|
|
|
|
def get_ccff_paths(module, ccff_path_directory):
|
|
filename = ccff_path_directory.format(module)
|
|
with open(filename, "r") as stream:
|
|
try:
|
|
bitstream = yaml.safe_load(stream)
|
|
except yaml.YAMLError as exc:
|
|
print(exc)
|
|
return bitstream
|
|
|
|
|
|
def restructure_bitstream(original_bitstream, original_bitstream_distribution, instance_mapping, ccff_path_directory, output_bitstream_xml, fabric_name):
|
|
print(f"-> original_bitstream {original_bitstream}")
|
|
print(f"-> instance_mapping {instance_mapping}")
|
|
print(f"-> ccff_path_directory {ccff_path_directory}")
|
|
|
|
with open(instance_mapping, "r") as fp:
|
|
instance_map = json.load(fp)
|
|
|
|
bitstream_tree = ET.parse(original_bitstream)
|
|
bitstream = bitstream_tree.getroot()
|
|
|
|
tree = ET.parse(original_bitstream_distribution)
|
|
bitstream_dist = tree.getroot()
|
|
|
|
with open(ccff_path_directory.format("fpga_top"), "r") as stream:
|
|
top_ccff = yaml.safe_load(stream)
|
|
|
|
validate_bitstream_length(instance_map, bitstream_dist, ccff_path_directory, fabric_name)
|
|
|
|
# Iterate over each region in fabric key
|
|
for each_region, instances in top_ccff.items():
|
|
region_id = each_region.split("_")[-1]
|
|
bitvalues = bitstream.findall(f'.//region[@id="{region_id}"]/*')
|
|
bit_number = 0
|
|
# Iterate over each module in fabric region
|
|
for instance, head_port in instances:
|
|
module = get_module_of_instance(instance_map, instance)
|
|
or_bit = bitstream_dist.findall(f'.//*block[@name="{instance}"]')[0]
|
|
if module is None:
|
|
logger.debug(f"skipping {instance}")
|
|
continue # Skip if module is merged already
|
|
paths = get_ccff_paths(module, ccff_path_directory)[head_port]
|
|
for line in paths:
|
|
# replace slash in the line with dot
|
|
line_dot = line.replace('/', '.')
|
|
line_dot = line_dot[:-1] + "Q"
|
|
# print(bit_number, f"fpga_top/fpga_core_inst/{instance}/{line}")
|
|
bitvalues[-1*(bit_number+1)].attrib["new_path"] = f"fpga_top.fpga_core_inst.{instance}.{line_dot}"
|
|
bitvalues[-1*(bit_number+1)].attrib["id"] = str(bit_number)
|
|
bit_number += 1
|
|
# print(f"module {module:10} bitno={bit_number:<10} paths={len(paths): 4}")
|
|
print(f">>>>> Region {region_id:4} TotalBits {bit_number:5} /" +
|
|
f" {len(bitvalues):5} = {(bit_number-len(bitvalues)):3}")
|
|
bitstream_tree.write(output_bitstream_xml)
|
|
|
|
|
|
def validate_bitstream_length(instance_map, bitstream_dist, ccff_path_directory, fabric_name):
|
|
seen = []
|
|
bitmap = {
|
|
"cby_0__1_": ["grid_io_left_left_0__1_"],
|
|
"cby_8__1_": ["grid_io_right_right_9__1_"],
|
|
"cbx_1__0_": ["grid_io_bottom_bottom_1__0_"],
|
|
"cbx_1__8_": ["grid_io_top_top_1__9_"],
|
|
"cby_0__6_": ["sb_0__5_", "sb_0__6_", "grid_io_left_left_0__1_"],
|
|
"cby_8__6_": ["sb_8__5_", "sb_8__6_", "grid_io_right_right_9__1_"],
|
|
"cby_0__3_": ["sb_0__2_", "sb_0__3_", "grid_io_left_left_0__1_"],
|
|
"cby_8__3_": ["sb_8__2_", "sb_8__3_", "grid_io_right_right_9__1_"],
|
|
"cby_2__3_": ["sb_6__2_", "sb_6__3_"],
|
|
"cby_2__6_": ["sb_6__5_", "sb_6__6_"],
|
|
"grid_ram9k": ["cbx_1__2_", "cbx_1__3_",
|
|
"sb_1__2_", "sb_1__3_",
|
|
"cbx_2__2_", "cbx_2__3_"],
|
|
"grid_dsp": ["cbx_1__5_", "cbx_1__6_",
|
|
"sb_1__5_", "sb_1__6_",
|
|
"cbx_2__5_", "cbx_2__6_"]
|
|
}
|
|
if fabric_name == "FPGA25x24_flex4k":
|
|
bitmap = {
|
|
"cby_0__1_": ["grid_io_left_left_0__1_"],
|
|
"cby_8__1_": ["grid_io_right_right_25__1_"],
|
|
"cbx_1__0_": ["grid_io_bottom_bottom_1__0_"],
|
|
"cbx_1__8_": ["grid_io_top_top_1__26_"],
|
|
"cby_0__6_": ["sb_0__12_", "sb_0__13_", "grid_io_left_left_0__1_"],
|
|
"cby_8__6_": ["sb_24__12_", "sb_24__13_", "grid_io_right_right_25__1_"],
|
|
"cby_0__3_": ["sb_0__2_", "sb_0__3_", "grid_io_left_left_0__1_"],
|
|
"cby_8__3_": ["sb_24__2_", "sb_24__3_", "grid_io_right_right_25__1_"],
|
|
"cby_2__3_": ["sb_6__2_", "sb_6__3_"],
|
|
"cby_2__6_": ["sb_6__12_", "sb_6__13_"],
|
|
"grid_ram9k": ["cbx_1__2_", "cbx_1__3_",
|
|
"sb_1__2_", "sb_1__3_",
|
|
"cbx_2__2_", "cbx_2__3_"],
|
|
"grid_dsp": ["cbx_1__12_", "cbx_1__13_",
|
|
"sb_1__12_", "sb_1__13_",
|
|
"cbx_2__12_", "cbx_2__13_"]
|
|
}
|
|
|
|
print("{:15} {:7} {:8} {:4}".format(
|
|
"Modules", "expected", "obtained", "diff"))
|
|
for module, instances in instance_map.items():
|
|
bit_cnt = 0
|
|
for m in bitmap.get(module, []) + [instances[0], ]:
|
|
try:
|
|
or_bit = bitstream_dist.findall(
|
|
f'.//*block[@name="{m}"]')[0]
|
|
except IndexError:
|
|
print(f"{m} not found")
|
|
bit_cnt += int(or_bit.attrib['number_of_bits'])
|
|
|
|
# CCFF Paths
|
|
filename = ccff_path_directory.format(module)
|
|
bitstream = yaml.safe_load(open(filename, "r"))
|
|
path_cnt = sum([len(i) for i in bitstream.values()])
|
|
|
|
print(f"{module:15} {bit_cnt:8} {path_cnt:8} {(bit_cnt-path_cnt):4}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
parser = argparse.ArgumentParser(formatter_class=formatter)
|
|
|
|
# Mandatory arguments
|
|
parser.add_argument('--original_bitstream', type=str,
|
|
required=True)
|
|
parser.add_argument('--instance_mapping', type=str,
|
|
required=True)
|
|
parser.add_argument('--ccff_path_directory', type=str,
|
|
required=True)
|
|
parser.add_argument('--original_bitstream_distribution', type=str,
|
|
required=True)
|
|
parser.add_argument('--output_bitstream_xml', type=str,
|
|
required=True)
|
|
parser.add_argument('--fabric_name', type=str,
|
|
default=os.environ.get('PROJ_NAME'))
|
|
args = parser.parse_args()
|
|
|
|
restructure_bitstream(args.original_bitstream, args.original_bitstream_distribution, args.instance_mapping, args.ccff_path_directory, args.output_bitstream_xml, args.fabric_name)
|