diff --git a/MANIFEST.in b/MANIFEST.in index e3ee5ded3c..0f5df72cc7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,3 +7,4 @@ recursive-include hls4ml *.py recursive-include hls4ml/contrib * global-exclude .git .gitmodules .gitlab-ci.yml *.pyc include hls4ml/backends/vivado_accelerator/supported_boards.json +include hls4ml/backends/vitis_unified/supported_boards.json diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 07a089cdf8..7403519baf 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -13,11 +13,14 @@ from hls4ml.backends.vitis.vitis_backend import VitisBackend # isort: skip +from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend # isort: skip + def _register_builtin_backends(): register_backend('Vivado', VivadoBackend) register_backend('VivadoAccelerator', VivadoAcceleratorBackend) register_backend('Vitis', VitisBackend) + register_backend('VitisUnified', VitisUnifiedBackend) register_backend('Quartus', QuartusBackend) register_backend('Catapult', CatapultBackend) register_backend('SymbolicExpression', SymbolicExpressionBackend) diff --git a/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py new file mode 100644 index 0000000000..33f25fa5f1 --- /dev/null +++ b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py @@ -0,0 +1,114 @@ +# we inherit it from vitis +import re +import zipfile + +from hls4ml.backends.vitis.passes.fifo_depth_optimization import ( + generate_depths_file, + initialize_large_fifos, + set_optimized_fifo_depths, +) +from hls4ml.model.optimizer.optimizer import ConfigurableOptimizerPass, ModelOptimizerPass + + +def get_vitis_optimized_fifo_depths(model, cus_hls_prj_path=None): + """Parse the files generated by the co-simulation to retrieve the optimized depths for the FIFOs. + Attention, only the FIFOs between the layers are profiled! + + Args: + model (ModelGraph): The model to which FIFO depth optimization is applied. + + Returns: + Dict[str, int]: A dictionary that contains the FIFO names as keys and the optimized depths as values. + """ + # channel.zip is generated after the co-simulation and contains the chan_status*.csv files + # in the chan_status*.csv files the max depth achieved during co-simulation can be found at the last (4th) line + + if cus_hls_prj_path is None: + cus_hls_prj_path = model.config.get_output_dir() + '/' + model.config.get_project_name() + '/_prj/solution1' + + path_to_zip_file = cus_hls_prj_path + '/.autopilot/db/channel_depth_info/' + + with zipfile.ZipFile(f'{path_to_zip_file}channel.zip', 'r') as zip_ref: + zip_ref.extractall(path_to_zip_file) + + # the channel_info.csv file contains the mapping of each fifo name (i.e layer4_out_U) to the respective + # chan_status*.csv file + names_file_path = cus_hls_prj_path + '/.autopilot/db/channel_info.csv' + + csv_fifo_depth_files = {} + with open(names_file_path) as names_file: + for line in names_file: + slitted_line = line.split(',') + if len(slitted_line[0]) == 0: + continue + layer_name = slitted_line[1] + csv_file_name = slitted_line[3][:-1] + csv_fifo_depth_files[layer_name] = csv_file_name + + optmized_fifo_depths = {} + for layer_name, file_name in csv_fifo_depth_files.items(): + with open(path_to_zip_file + file_name) as chan_status_file: + lines = chan_status_file.readlines() + cleaned_layer_name = re.sub(r'(_i)?_U$', '', layer_name) + optmized_fifo_depths[cleaned_layer_name] = int( + lines[-1] + ) # remove "_i_U" (axis) or "_U" (axim) from the layer name + # string and keep the last line of the file that contains the max depth + + return optmized_fifo_depths + + +def execute_cosim_to_profile_fifos(model): + model.write() + model.build( + reset=False, + csim=False, + synth=True, + cosim=False, + vsynth=False, + fifo_opt=True, + bitfile=False, + log_to_stdout=False, + ) + + +class FifoDepthOptimization(ConfigurableOptimizerPass, ModelOptimizerPass): + def __init__(self): + self.profiling_fifo_depth = 100_000 + + def transform(self, model): + """Perform FIFO depth optimization between the FIFOs of all layers to reduce resource utilization as the + initial FIFOs set by hls4ml might be larger than required. At the end of the optimization the FIFOs will + have the largest depths achieved during co-simulation without causing any deadlocks between the layers + (producer-consumer), thus no additional delays between the layers. In some cases, this optimization + might lead to bigger FIFOs than initially set by the hls4ml tool in order to prevent deadlocks. + + Args: + model (ModelGraph): The model to which FIFO depth optimization is applied. + + Raises: + ValueError: If the FIFO depth for profiling provided by the user is not a non-negative integer. + RuntimeError: If the IO type is not set to "io_stream". + + Returns: + bool: The execution state of the Optimizer Pass + """ + + if not isinstance(self.profiling_fifo_depth, int) or self.profiling_fifo_depth <= 0: + raise ValueError('The FIFO depth for profiling (profiling_fifo_depth variable) must be a non-negative integer.') + + # check axi-stream or io-stream + if not (model.config.get_config_value('IOType') == 'io_stream'): + raise RuntimeError('To use this optimization you have to set `IOType` field to `io_stream` in the HLS config.') + + hlsPrjPath = model.config.backend.writer.get_vitis_hls_exec_dir(model) + + initial_fifo_depths = initialize_large_fifos(model, self.profiling_fifo_depth) + execute_cosim_to_profile_fifos(model) + optimized_fifo_depths = get_vitis_optimized_fifo_depths(model, cus_hls_prj_path=hlsPrjPath + '/hls') + generate_depths_file(model, initial_fifo_depths, optimized_fifo_depths) + set_optimized_fifo_depths(model, optimized_fifo_depths) + + print('FIFO optimization completed') + + return False diff --git a/hls4ml/backends/vitis_unified/supported_boards.json b/hls4ml/backends/vitis_unified/supported_boards.json new file mode 100644 index 0000000000..324a845eea --- /dev/null +++ b/hls4ml/backends/vitis_unified/supported_boards.json @@ -0,0 +1,33 @@ +{ + "zcu102": { + "part": "xczu9eg-ffvb1156-2-e", + "axi_master": { + "platform_file": "base_platforms/xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm", + "python_driver": "axi_master_driver.py", + "c_drivers": "" + }, + "axi_stream": { + "platform_generator_tcl": "zcu102/tcl_scripts/create_xsa.tcl", + "platform_output": "zcu102/tcl_scripts/output/zcu102_axi_stream_platform.xsa", + "python_driver": "axi_stream_driver.py", + "c_drivers": "" + } + }, + + "kv260": { + "part": "sk-kv260-g", + "axi_master": { + "platform_generator_tcl": "kv260/tcl_scripts/create_xsa.tcl", + "platform_output": "kv260/tcl_scripts/output/kv260_axi_all_platform.xsa", + "python_driver": "axi_master_driver.py", + "c_drivers": "" + }, + "axi_stream": { + "platform_generator_tcl": "kv260/tcl_scripts/create_xsa.tcl", + "platform_output": "kv260/tcl_scripts/output/kv260_axi_all_platform.xsa", + "python_driver": "axi_stream_driver.py", + "c_drivers": "" + } + } + +} diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py new file mode 100644 index 0000000000..f67fb9c709 --- /dev/null +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -0,0 +1,162 @@ +import os +import subprocess +import sys +from shutil import copy2 + +from hls4ml.backends import VitisBackend, VivadoBackend +from hls4ml.model.flow import register_flow + + +class VitisUnifiedBackend(VitisBackend): + def __init__(self): + super(VivadoBackend, self).__init__(name='VitisUnified') + self._register_layer_attributes() + self._register_flows() + + def build( + self, + model, + reset=False, + csim=False, + synth=False, + cosim=False, + vsynth=False, + fifo_opt=False, + bitfile=False, + log_to_stdout=True, + ): + # it builds and return vivado reports + if 'linux' in sys.platform: + found = os.system('command -v v++ > /dev/null') + if found != 0: + raise Exception('Vitis installation not found. Make sure "vitis" is on PATH.') + + found = os.system('command -v vitis-run > /dev/null') + if found != 0: + raise Exception('Vitis installation not found. Make sure "vitis-run" is on PATH.') + + output_dir = model.config.get_output_dir() + + hls_config_file = os.path.join(output_dir, 'hls_kernel_config.cfg') + # build command + csynth_cmd = ('v++ -c --mode hls --config {configPath} --work_dir vitis_unified_project').format( + configPath=hls_config_file + ) + # util template (used in csim/cosim/package) + util_command = 'vitis-run --mode hls --{op} --config {configPath} --work_dir vitis_unified_project' + + # command for each configuration + vitis_hls_dir = model.config.backend.writer.get_vitis_hls_dir(model) + package_cmd = util_command.format(op='package', configPath=hls_config_file) + cosim_cmd = util_command.format(op='cosim', configPath=hls_config_file) + csim_cmd = util_command.format(op='csim', configPath=hls_config_file) + + kerlink_cmd = './link_system.sh' + kerlink_cwd = model.config.backend.writer.get_vitis_linker_dir(model) + + commands = [] + if synth: + self.prepare_sim_config_file(model, True) + commands.append(('csynth', csynth_cmd, vitis_hls_dir)) + commands.append(('package', package_cmd, vitis_hls_dir)) + + if csim: + self.prepare_sim_config_file(model, True) + commands.append(('csim', csim_cmd, vitis_hls_dir)) + + if cosim or fifo_opt: + self.prepare_sim_config_file(model, False) + commands.append(('cosim', cosim_cmd, vitis_hls_dir)) + + if bitfile: + commands.append(('kerlink', kerlink_cmd, kerlink_cwd)) + + for task_name, command, cwd in commands: + stdout_log = os.path.join(output_dir, f'{task_name}_stdout.log') + stderr_log = os.path.join(output_dir, f'{task_name}_stderr.log') + stdout_target = None if log_to_stdout else open(stdout_log, 'w') + stderr_target = None if log_to_stdout else open(stderr_log, 'w') + + try: + process = subprocess.Popen( + command, shell=True, cwd=cwd, stdout=stdout_target, stderr=stderr_target, text=True + ) + process.communicate() + + if process.returncode != 0: + raise Exception(f'Build failed for {model.config.get_project_name()} during task "{task_name}".') + finally: + if not log_to_stdout: + stdout_target.close() + stderr_target.close() + + def prepare_sim_config_file(self, model, is_csim): + suffix = 'csim' if is_csim else 'cosim' + src = f'{model.config.get_output_dir()}/hls_kernel_config_{suffix}.cfg' + des = f'{model.config.get_output_dir()}/hls_kernel_config.cfg' + copy2(src, des) + return des + + def create_initial_config( + self, + board='zcu102', + part=None, + clock_period=5, + clock_uncertainty='12.5%', + io_type='io_stream', + driver='python', + input_type='float', + output_type='float', + in_stream_buf_size=128, + out_stream_buf_size=128, + axi_mode='axi_master', + **_, + ): + supported_boards_path = os.path.join(os.path.dirname(__file__), 'supported_boards.json') + if os.path.exists(supported_boards_path): + import json + + with open(supported_boards_path) as f: + supported_boards = json.load(f) + if board in supported_boards: + part = part or supported_boards[board]['part'] + if part is None: + part = 'xczu9eg-ffvb1156-2-e' + + config = super().create_initial_config(part, clock_period, clock_uncertainty, io_type) + + config['VitisUnifiedConfig'] = {} + config['VitisUnifiedConfig']['Board'] = board + config['VitisUnifiedConfig']['axi_mode'] = axi_mode + config['VitisUnifiedConfig']['in_stream_buf_size'] = in_stream_buf_size + config['VitisUnifiedConfig']['out_stream_buf_size'] = out_stream_buf_size + + config['VitisUnifiedConfig']['Driver'] = driver + config['VitisUnifiedConfig']['InputDtype'] = input_type # float, double or ap_fixed + config['VitisUnifiedConfig']['OutputDtype'] = output_type # float, double or ap_fixed + + if io_type != 'io_stream': + raise Exception('io_type must be io_stream') + if input_type not in ['double', 'float']: + raise Exception('input_type must be float or double') + if output_type not in ['double', 'float']: + raise Exception('output_type must be float or double') + + return config + + def get_default_flow(self): + return self._default_flow + + def get_writer_flow(self): + return self._writer_flow + + def _register_flows(self): + vitis_ip = 'vitis:ip' + writer_passes = ['make_stamp', 'vitisunified:write_hls'] + self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name) + self._default_flow = vitis_ip + + # register fifo depth optimization + fifo_depth_opt_passes = ['vitisunified:fifo_depth_optimization'] + writer_passes + + register_flow('fifo_depth_optimization', fifo_depth_opt_passes, requires=['vitis:ip'], backend=self.name) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py new file mode 100644 index 0000000000..f4ba068a8e --- /dev/null +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -0,0 +1,163 @@ +import json +import os + + +class VitisUnifiedConfig: + def __init__(self, config, model_inputs, model_outputs): + self.config = config.config + self.board = self.config.get('VitisUnifiedConfig', {}).get('Board', 'zcu102') + self.supported_boards = self._load_supported_boards() + + if self.board not in self.supported_boards: + raise Exception( + f'Board "{self.board}" does not appear in supported_boards.json. ' + f'Available boards: {list(self.supported_boards.keys())}' + ) + + self.axi_mode = self.config['VitisUnifiedConfig']['axi_mode'] + + if self.axi_mode not in ['axi_stream', 'axi_master']: + raise Exception('AXIMode must be either axi_stream or axi_master') + + # axi master buffer size + # before first and after last layer we have the configurable buffer + # [platform]<-->[in_stream_buf_size]<-->[hls]<-->[out_stream_buf_size]<-->[platform] + self.in_stream_buf_size = self.config['VitisUnifiedConfig']['in_stream_buf_size'] + self.out_stream_buf_size = self.config['VitisUnifiedConfig']['out_stream_buf_size'] + # Platform is resolved from supported_boards.json based on board + axi_mode + board_info = self.supported_boards.get(self.board, {}) + mode_config = board_info.get(self.axi_mode, {}) + if not isinstance(mode_config, dict): + mode_config = {} + + tcl_rel = mode_config.get('platform_generator_tcl') or ( + board_info.get('platform_generator_tcl', {}).get(self.axi_mode) + if isinstance(board_info.get('platform_generator_tcl'), dict) + else board_info.get('platform_generator_tcl') + ) + + if tcl_rel: + out_rel = mode_config.get('platform_output') or board_info.get('platform_output', 'output/platform.xsa') + output_dir = config.get_output_dir() + workspace_root = os.path.join(output_dir, 'vitis_workspace') + tcl_path = tcl_rel if os.path.isabs(tcl_rel) else os.path.join(workspace_root, tcl_rel) + self._platform_generator_tcl = os.path.abspath(os.path.expanduser(tcl_path)) + if not os.path.isabs(out_rel): + out_path = os.path.join(workspace_root, out_rel) + else: + out_path = out_rel + self._platform_output_path = os.path.abspath(out_path) + self._platform_path = self._platform_output_path + elif mode_config.get('platform_file') or ( + board_info.get('platform_file') and board_info['platform_file'].get(self.axi_mode) + ): + self._platform_path = self._get_xpfm_path_from_board() + self._platform_generator_tcl = None + self._platform_output_path = None + else: + raise Exception(f'Board "{self.board}" has no platform for axi_mode "{self.axi_mode}" in supported_boards.json.') + + self.driver = self.config['VitisUnifiedConfig']['Driver'] + assert self.driver == 'python', 'we currently only support python drivers' + + # c++ type for input and output of the hls kernel it must be str (float/double) + self.input_type = self.config['VitisUnifiedConfig']['InputDtype'] + self.output_type = self.config['VitisUnifiedConfig']['OutputDtype'] + + assert self.input_type == self.output_type, 'Input and Output data types must be the same type different' + assert len(model_inputs) >= 1, 'Only models with at least one input tensor are currently supported by VitisUnified' + assert len(model_outputs) >= 1, 'Only models with one output tensor are currently supported by VitisUnified' + self.inps = model_inputs.copy() + self.outs = model_outputs.copy() + + def _load_supported_boards(self): + path = os.path.join(os.path.dirname(__file__), 'supported_boards.json') + with open(path) as f: + return json.load(f) + + def _get_xpfm_path_from_board(self): + board_info = self.supported_boards[self.board] + mode_config = board_info.get(self.axi_mode, {}) + if isinstance(mode_config, dict) and mode_config.get('platform_file'): + platform_rel = mode_config['platform_file'] + else: + platform_file = board_info.get('platform_file') + if not platform_file: + raise Exception(f'No platform_file definition for board "{self.board}" in supported_boards.json') + platform_rel = platform_file.get(self.axi_mode) if isinstance(platform_file, dict) else platform_file + if not platform_rel: + raise Exception( + f'No platform file for axi_mode "{self.axi_mode}" in supported_boards.json for board "{self.board}"' + ) + # Resolve relative to XILINX_VITIS if path is relative + if not os.path.isabs(platform_rel): + xilinx_vitis = os.environ.get('XILINX_VITIS', '/opt/Xilinx/Vitis/2023.2') + return os.path.join(xilinx_vitis, platform_rel) + return platform_rel + + def get_board_info(self, board=None): + board = board or self.board + if board not in self.supported_boards: + raise Exception(f'Board "{board}" is not supported') + return self.supported_boards[board] + + def get_part(self): + return self.get_board_info()['part'] + + # main driver generation + def get_driver_file(self): + """Return driver filename for current settings""" + board_info = self.get_board_info() + driver_file = board_info.get(self.axi_mode, {}).get('python_driver') + if not driver_file: + raise Exception( + f'No python_driver for axi_mode "{self.axi_mode}" in supported_boards.json for board "{self.board}"' + ) + return driver_file + + def get_driver_template_path(self): + """Return absolute path to main driver template for current board. + Derives path from python_drivers in supported_boards: {board}/python_drivers/{driver_file}.hls4ml + """ + driver_file = self.get_driver_file() + template_rel = f'{self.board}/python_drivers/{driver_file}.hls4ml' + return os.path.join(os.path.dirname(__file__), '../../templates/vitis_unified', template_rel) + + def get_corrected_types(self): + return self.input_type, self.output_type, self.inps, self.outs + + def get_driver(self): + return self.driver + + def get_board(self): + return self.board + + def get_axi_mode(self): + return self.axi_mode + + def get_input_type(self): + return self.input_type + + def get_output_type(self): + return self.output_type + + def get_in_stream_buf_size(self): + return self.in_stream_buf_size + + def get_out_stream_buf_size(self): + return self.out_stream_buf_size + + def get_XPFMPath(self): + return self._platform_path + + def get_platform_path(self): + """Path to platform (.xpfm or .xsa). Alias for get_XPFMPath for backward compatibility.""" + return self._platform_path + + def get_platform_generator_tcl(self): + """Path to TCL script that generates platform, or None if using pre-built platform.""" + return getattr(self, '_platform_generator_tcl', None) + + def get_platform_output_path(self): + """Path where platform generator writes output, or None if not using generator.""" + return getattr(self, '_platform_output_path', None) diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh new file mode 100644 index 0000000000..2645804f90 --- /dev/null +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +CC=g++ +if [[ "$OSTYPE" == "linux-gnu" ]]; then + CFLAGS="-O3 -fPIC -std=c++11 -fno-gnu-unique" +elif [[ "$OSTYPE" == "darwin"* ]]; then + CFLAGS="-O3 -fPIC -std=c++11" +fi +VITIS_UNIFIED_FLAGS="VITIS_UNIFIED" +CFLAGS="$CFLAGS -D$VITIS_UNIFIED_FLAGS" + +INCFLAGS="-Ifirmware/ap_types/" + +PROJECT=myprojectBaseName +WRAPPER_NAME=myprojectWrapName +LIB_STAMP=mystamp +BASEDIR="$(cd "$(dirname "$0")" && pwd)" +WEIGHTS_DIR="\"${BASEDIR}/firmware/weights\"" + +echo "------------- This is build_lib.sh debug message ----------------" +echo "Compiling for OSTYPE: $OSTYPE" +echo "CFLAGS: $CFLAGS" +echo "Include Flags: $INCFLAGS" +echo "Weights directory: $WEIGHTS_DIR" +echo "-----------------------------------------------------------------" + +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c firmware/${PROJECT}.cpp -o ${PROJECT}.o +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c firmware/${WRAPPER_NAME}.cpp -o ${WRAPPER_NAME}.o +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${WRAPPER_NAME}.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so +rm -f *.o diff --git a/hls4ml/templates/vitis_unified/build_lib_multigraph.sh b/hls4ml/templates/vitis_unified/build_lib_multigraph.sh new file mode 100644 index 0000000000..9dcd85f7d1 --- /dev/null +++ b/hls4ml/templates/vitis_unified/build_lib_multigraph.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +CC=g++ +if [[ "$OSTYPE" == "linux-gnu" ]]; then + CFLAGS="-O3 -fPIC -std=c++11 -fno-gnu-unique" +elif [[ "$OSTYPE" == "darwin"* ]]; then + CFLAGS="-O3 -fPIC -std=c++11" +fi + +graph_project_names=(mygraph_name_list) + +LDFLAGS= +VITIS_UNIFIED_FLAGS="VITIS_UNIFIED" +CFLAGS="$CFLAGS -D$VITIS_UNIFIED_FLAGS" + +ORIGINAL_PROJECT=myproject +PROJECT=myproject_stitched +LIB_STAMP=mystamp +BASEDIR="$(cd "$(dirname "$0")" && cd .. && pwd)" +INCFLAGS="" +OUTPUT_DIR="${BASEDIR}/stitched/firmware" +WEIGHTS_DIR="\"${BASEDIR}/stitched/firmware/weights\"" + +mkdir -p "${OUTPUT_DIR}" + +# Compile all graphs in parallel +OBJECT_FILES=() +PIDS=() + +for g in "${graph_project_names[@]}"; do + SRC_FILE="${g}/firmware/${ORIGINAL_PROJECT}_${g}.cpp" + OBJ_FILE="${ORIGINAL_PROJECT}_${g}.o" + AP_TYPES_PATH="-I${BASEDIR}/${g}/firmware/ap_types/" + ( + ${CC} ${CFLAGS} ${AP_TYPES_PATH} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c "${BASEDIR}/${SRC_FILE}" -o "${OBJ_FILE}" + ) & + PIDS+=($!) + OBJECT_FILES+=("${OBJ_FILE}") + INCFLAGS+="-I${BASEDIR}/${g}/ " +done + +# compile axi_stream as well + +for g in "${graph_project_names[@]}"; do + SRC_FILE="${g}/firmware/${ORIGINAL_PROJECT}_${g}_axi.cpp" + OBJ_FILE="${ORIGINAL_PROJECT}_${g}_axi.o" + AP_TYPES_PATH="-I${BASEDIR}/${g}/firmware/ap_types/" + ( + ${CC} ${CFLAGS} ${AP_TYPES_PATH} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c "${BASEDIR}/${SRC_FILE}" -o "${OBJ_FILE}" + ) & + PIDS+=($!) + OBJECT_FILES+=("${OBJ_FILE}") + #INCFLAGS+="-I${BASEDIR}/${g}/ " +done + + + +for pid in "${PIDS[@]}"; do + wait $pid +done + +AP_TYPES_PATH="-I${BASEDIR}/${graph_project_names[@]: -1}/firmware/ap_types/" + +${CC} ${CFLAGS} ${INCFLAGS} ${AP_TYPES_PATH} -c "${PROJECT}_bridge.cpp" -o ${PROJECT}_bridge.o +${CC} ${CFLAGS} ${INCFLAGS} ${AP_TYPES_PATH} -shared "${OBJECT_FILES[@]}" ${PROJECT}_bridge.o -o "${OUTPUT_DIR}/${PROJECT}-${LIB_STAMP}.so" + +rm -f "${OBJECT_FILES[@]}" +rm -f ${PROJECT}_bridge.o diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg new file mode 100644 index 0000000000..c1d12a0c18 --- /dev/null +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -0,0 +1,24 @@ +part={PART} + +[hls] +clock={CLK} +clock_uncertainty={CLK_UC} +flow_target=vivado +syn.file={OUTDIR}/firmware/{FILE_NAME_WRAP}.cpp +syn.file={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp +syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_WRAP}.cpp,-std=c++0x +syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp,-std=c++0x + +syn.top={TOP_NAME} + +tb.file={OUTDIR}/{SIM_FILE_NAME}.cpp +tb.file={OUTDIR}/firmware/weights +tb.file={OUTDIR}/tb_data +tb.file_cflags={OUTDIR}/{SIM_FILE_NAME}.cpp,-std=c++0x +tb.file_cflags={OUTDIR}/{SIM_FILE_NAME}.cpp,-DRTL_SIM +package.ip.version=1.0.0 +package.output.format={OUTPUT_KERNEL_TYPE} +syn.compile.name_max_length=80 +syn.schedule.enable_dsp_full_reg=0 +package.output.syn=1 +cosim.enable_fifo_sizing=true diff --git a/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_master_driver.py.hls4ml b/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_master_driver.py.hls4ml new file mode 100644 index 0000000000..bf18e7cd10 --- /dev/null +++ b/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_master_driver.py.hls4ml @@ -0,0 +1,213 @@ +from datetime import datetime + +# import the library +from pynq import Overlay # import the overlay +from pynq import allocate # import for CMA (contingeous memory allocation) +from pynq import DefaultIP # import the ip connector library for extension +from pynq import Interrupt +from pynq import PL + +import asyncio +import numpy as np +import os +import subprocess +import re +import time + +class NeuralNetworkOverlay(Overlay): + def __init__( + self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, device=None + ): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def calculate_performance(self, N, execution_time): + rate = N / execution_time if execution_time > 0 else float('inf') + print( + f"Processed elements: {N}, Execution time: {execution_time:.4f} seconds, Performance rate: {rate:.2f} inferences/second") + return rate + + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + + # reset the PL + PL.reset() + # set interrupt controller + my_interrupt = Interrupt("/interrupt") + ip = self. + + if encode is not None: + X = encode(X) + np.copyto(self.input_buffer, X) + exec_time = ip.transfer(self.input_buffer, self.output_buffer, my_interrupt, profile) + # exec_time will valid only when the profile is enabled + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + performance = self.calculate_performance(len(X), exec_time) + return self.output_buffer, exec_time, performance + return self.output_buffer + +class HLS4ML_IP(DefaultIP): + def __init__(self, description): + super().__init__(description=description) + + self.REG_ADDR_AP_CTRL = 0x00 + self.REG_ADDR_BATCH_SIZE = VAL + + self.REG_ADDR_GIE = 0x04 + self.REG_ADDR_IER = 0x08 + self.REG_ADDR_ISR = 0x0C + + self.INP_PORT_NAMEs = [ + # hls-driver-input-dbg-name + ] + + self.REG_ADDR_INP_PTRs = [ + # hls-driver-input-ptr + ] + + self.OUT_PORT_NAMEs = [ + # hls-driver-output-dbg-name + ] + + self.REG_ADDR_OUT_PTRs = [ + # hls-driver-output-ptr + ] + + bindto = ['xilinx.com:hls::1.0'] + + def enable_gie(self): + print("global interrupt enable register") + self.write(self.REG_ADDR_GIE, 0x01) + print("enable gie successful") + + def disable_gie(self): + print("global interrupt enable register") + self.write(self.REG_ADDR_GIE, 0x01) + print("disable gie successful") + + def enable_done_intr(self): + print("ap_done interrupt enable register") + self.write(self.REG_ADDR_IER, 0x01) + print("enable ap_done interrupt successful") + + def clear_done_status(self): + print("ap_done register clear") + self.write(self.REG_ADDR_ISR, 0x01) + print("clear ap_done interrupt successful") + + def set_single_bit(self, addr, idx): + self.write(addr, 1 << idx) + + def ctrl_start(self): + self.write(0x00, 0x01) # ap_start = 1 + + def wait_until_done(self): + while (self.read(0x00) & 0x2) == 0: # Wait for ap_done + time.sleep(0.001) + + def set_input(self, idx, buffer): + + print( + f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {hex(buffer.physical_address)} with elements: {buffer.size}" + ) + self.write(self.REG_ADDR_INP_PTRs[idx], buffer.physical_address) + self.write(self.REG_ADDR_INP_PTRs[idx] + 4, 0) + buffer.flush() + + def set_output(self, idx, buffer): + + print( + f"output {self.OUT_PORT_NAMEs[idx]} will be set to addr: {hex(buffer.physical_address)} with elements: {buffer.size}" + ) + self.write(self.REG_ADDR_OUT_PTRs[idx], buffer.physical_address) + self.write(self.REG_ADDR_OUT_PTRs[idx] + 4, 0) + + def set_amt_query(self, val): + print(f"amount of queries will be set to: {val} at address: {hex(self.REG_ADDR_BATCH_SIZE)}") + self.write(self.REG_ADDR_BATCH_SIZE, val) + + def prepare_intr(self): + print("prepare your interrupt") + self.enable_gie() + self.enable_done_intr() + self.clear_done_status() + print("----------------------") + + def build_event_and_run(self, intr, profile): + + async def wait_for_acc(): + exec_time = 0 + print("starting the accelerator") + if profile: + t_start = time.perf_counter() + + # Start receive (PL → PS) + # Start send (PS → PL) + self.ctrl_start() + + # Wait for complete + await intr.wait() + + # print porfile data + if profile: + t_end = time.perf_counter() + exec_time = t_end - t_start + print(f"Accelerator execution time: \ + {(exec_time) * 1e3:.3f} ms") + + print("accelerator has finished") + + return exec_time if profile else None + + # get event loop from asyncio + loop = asyncio.get_event_loop() + # build task + task = loop.create_task(wait_for_acc()) + # run and return whatever inside the wait_for_acc return + return loop.run_until_complete(task) + + def transfer(self, input_buffer, output_buffer, intr, profile = True): + + # flush the buffer first + input_buffer.flush() + # prepare the data + self.set_input(0, input_buffer) + self.set_output(0, output_buffer) + self.set_amt_query(input_buffer.shape[0]) + self.prepare_intr() + # run and get the profile data + exec_time = self.build_event_and_run(intr, profile) + # invalidate the output buffer + output_buffer.invalidate() + # it will return 0 if the profile is not enable + return exec_time diff --git a/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_stream_driver.py.hls4ml b/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_stream_driver.py.hls4ml new file mode 100644 index 0000000000..a0a32187d2 --- /dev/null +++ b/hls4ml/templates/vitis_unified/kv260/python_drivers/axi_stream_driver.py.hls4ml @@ -0,0 +1,145 @@ +from datetime import datetime + +# import the library +from pynq import Overlay # import the overlay +from pynq import allocate # import for CMA (contingeous memory allocation) +from pynq import DefaultIP # import the ip connector library for extension +from pynq import Interrupt +from pynq import PL + +import asyncio +import numpy as np +import os +import subprocess +import re +import time + + +class NeuralNetworkOverlay(Overlay): + def __init__( + self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, device=None + ): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def calculate_performance(self, N, execution_time): + rate = N / execution_time if execution_time > 0 else float('inf') + print( + f"Processed elements: {N}, Execution time: {execution_time:.4f} seconds, Performance rate: {rate:.2f} inferences/second") + return rate + + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + + PL.reset() + my_interrupt = Interrupt("axi_dma_0/s2mm_introut") + + dma = self.axi_dma_0 + ip = self. + ip.assign_dma(dma) + + + if encode is not None: + X = encode(X) + np.copyto(self.input_buffer, X) + exec_time = ip.transfer(self.input_buffer, self.output_buffer, my_interrupt, profile) + # exec_time will valid only when the profile is enabled + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + performance = self.calculate_performance(len(X), exec_time) + return self.output_buffer, exec_time, performance + return self.output_buffer + +class HLS4ML_IP(DefaultIP): + + def __init__(self, description): + super().__init__(description) + self.dma = None + self.REG_ADDR_BATCH_SIZE = 0x10 + + bindto = ['xilinx.com:hls::1.0'] + + def assign_dma(self, dma): + self.dma = dma + + def set_amt_query(self, val): + print(f"amount of queries will be set to: {val} at address: {hex(self.REG_ADDR_BATCH_SIZE)}") + self.write(self.REG_ADDR_BATCH_SIZE, val) + + def ctrl_start(self): + # auto_restart + ap_start + self.write(0x00, 1 << 0) + + def transfer(self, input_buffer, output_buffer, intr, profile = True): + + # check availability of dma + assert self.dma is not None, "dma is not assigned" + # flush the buffer first + input_buffer.flush() + # initialize the batch tracker and ip control + self.set_amt_query(input_buffer.shape[0]) + self.ctrl_start() + + async def wait_for_acc(): + exec_time = 0 + print("starting the accelerator") + # Start receive (PL → PS) + if profile: + t_start = time.perf_counter() + self.dma.recvchannel.transfer(output_buffer) + + # Start send (PS → PL) + self.dma.sendchannel.transfer(input_buffer) + + # Wait for complete + await intr.wait() + + # print porfile data + if profile: + t_end = time.perf_counter() + exec_time = t_end - t_start + print(f"Accelerator execution time: \ + {(t_end - t_start) * 1e3:.3f} ms") + + + print("accelerator has finished") + return exec_time if profile else None + + # get event loop from asyncio + loop = asyncio.get_event_loop() + task = loop.create_task(wait_for_acc()) + # loop until end + exec_time = loop.run_until_complete(task) + # invalidate the output buffer + output_buffer.invalidate() + # it will return 0 if the profile is not enable + return exec_time diff --git a/hls4ml/templates/vitis_unified/kv260/tcl_scripts/create_xsa.tcl b/hls4ml/templates/vitis_unified/kv260/tcl_scripts/create_xsa.tcl new file mode 100644 index 0000000000..a43eb88684 --- /dev/null +++ b/hls4ml/templates/vitis_unified/kv260/tcl_scripts/create_xsa.tcl @@ -0,0 +1,67 @@ +################################################################ +# create_xsa.tcl +# +# Sources kv260_axi_all_platform.tcl to build the block design, then creates +# the HDL wrapper and exports the XSA hardware description file. +# +# Usage: +# cd +# vivado -mode batch -source create_xsa.tcl +# +# Output: +# output/kv260_axi_all_platform.xsa +# +# Requirements: +# Vivado 2023.2 with KV260 board files installed +# +# Note: For a clean run, remove the myproj/ directory first if it +# exists from a previous run. +################################################################ + +set script_dir [file dirname [file normalize [info script]]] +set output_dir [file join $script_dir "output"] +set xsa_path [file join $output_dir "kv260_axi_all_platform.xsa"] + +file mkdir $output_dir + +# Change to script directory so kv260_axi_all_platform.tcl is found +cd $script_dir + +# ---------------------------------------------------------------- +# Build block design (creates project + BD via kv260_axi_all_platform.tcl) +# ---------------------------------------------------------------- +source [file join $script_dir "kv260_axi_all_platform.tcl"] + +# ---------------------------------------------------------------- +# Create HDL wrapper +# ---------------------------------------------------------------- +set bd_file [get_files -norecurse "vitis_design.bd"] +make_wrapper -files $bd_file -top + +# make_wrapper creates {bd_base_name}_wrapper.v for vitis_design.bd +set wrapper_name "vitis_design_wrapper" +set proj_dir [get_property directory [current_project]] +add_files -norecurse [file join $proj_dir "project_1.gen" "sources_1" "bd" "vitis_design" "hdl" "${wrapper_name}.v"] +set_property top $wrapper_name [current_fileset] +update_compile_order -fileset sources_1 + +# ---------------------------------------------------------------- +# Generate block design outputs (required before write_hw_platform) +# ---------------------------------------------------------------- +generate_target all [get_files vitis_design.bd] + +# ---------------------------------------------------------------- +# Platform design intent (required for v++ accelerated platform) +# ---------------------------------------------------------------- +set_property platform.default_output_type "sd_card" [current_project] +set_property platform.design_intent.embedded "true" [current_project] +set_property platform.design_intent.server_managed "false" [current_project] +set_property platform.design_intent.external_host "false" [current_project] +set_property platform.design_intent.datacenter "false" [current_project] + +# ---------------------------------------------------------------- +# Export XSA as extensible pre-synthesis platform (for v++ link) +# ---------------------------------------------------------------- +write_hw_platform -hw -force -file $xsa_path + +puts "INFO: XSA written to $xsa_path" diff --git a/hls4ml/templates/vitis_unified/kv260/tcl_scripts/kv260_axi_all_platform.tcl b/hls4ml/templates/vitis_unified/kv260/tcl_scripts/kv260_axi_all_platform.tcl new file mode 100644 index 0000000000..d248c0a395 --- /dev/null +++ b/hls4ml/templates/vitis_unified/kv260/tcl_scripts/kv260_axi_all_platform.tcl @@ -0,0 +1,1338 @@ + +################################################################ +# This is a generated script based on design: vitis_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2023.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + if { [string compare $scripts_vivado_version $current_vivado_version] > 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2042 -severity "ERROR" " This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Sourcing the script failed since it was created with a future version of Vivado."} + + } else { + catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + } + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source vitis_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xck26-sfvc784-2LV-c + set_property board_part xilinx.com:kv260_som:part0:1.4 [current_project] + set_property board_connections {som240_1_connector xilinx.com:kv260_carrier:som240_1_connector:1.3} [current_project] +} +set_property platform.extensible true [current_project] + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name vitis_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_dma:7.1\ +xilinx.com:ip:axi_intc:4.1\ +xilinx.com:ip:smartconnect:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:zynq_ultra_ps_e:3.5\ +xilinx.com:ip:xlconcat:2.1\ +" + + set list_ips_missing "" + common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + + # Create ports + + # Create instance: axi_dma_0, and set properties + set axi_dma_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 ] + set_property -dict [list \ + CONFIG.c_include_sg {0} \ + CONFIG.c_sg_length_width {26} \ + ] $axi_dma_0 + + + # Create instance: axi_intc_0, and set properties + set axi_intc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_intc:4.1 axi_intc_0 ] + set_property CONFIG.C_IRQ_CONNECTION {1} $axi_intc_0 + + + # Create instance: axi_interconnect_0, and set properties + set axi_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_0 ] + set_property -dict [list \ + CONFIG.NUM_MI {2} \ + CONFIG.NUM_SI {1} \ + ] $axi_interconnect_0 + + + # Create instance: axi_smc, and set properties + set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] + set_property CONFIG.NUM_SI {2} $axi_smc + + + # Create instance: rst_ps8_0_99M, and set properties + set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] + + # Create instance: zynq_ultra_ps_e_0, and set properties + set zynq_ultra_ps_e_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.5 zynq_ultra_ps_e_0 ] + set_property -dict [list \ + CONFIG.CAN0_BOARD_INTERFACE {custom} \ + CONFIG.CAN1_BOARD_INTERFACE {custom} \ + CONFIG.CSU_BOARD_INTERFACE {custom} \ + CONFIG.DP_BOARD_INTERFACE {custom} \ + CONFIG.GEM0_BOARD_INTERFACE {custom} \ + CONFIG.GEM1_BOARD_INTERFACE {custom} \ + CONFIG.GEM2_BOARD_INTERFACE {custom} \ + CONFIG.GEM3_BOARD_INTERFACE {custom} \ + CONFIG.GPIO_BOARD_INTERFACE {custom} \ + CONFIG.IIC0_BOARD_INTERFACE {custom} \ + CONFIG.IIC1_BOARD_INTERFACE {custom} \ + CONFIG.NAND_BOARD_INTERFACE {custom} \ + CONFIG.PCIE_BOARD_INTERFACE {custom} \ + CONFIG.PJTAG_BOARD_INTERFACE {custom} \ + CONFIG.PMU_BOARD_INTERFACE {custom} \ + CONFIG.PSU_BANK_0_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_1_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_2_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_3_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_DDR_RAM_HIGHADDR {0xFFFFFFFF} \ + CONFIG.PSU_DDR_RAM_HIGHADDR_OFFSET {0x800000000} \ + CONFIG.PSU_DDR_RAM_LOWADDR_OFFSET {0x80000000} \ + CONFIG.PSU_IMPORT_BOARD_PRESET {} \ + CONFIG.PSU_MIO_0_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_0_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_0_SLEW {slow} \ + CONFIG.PSU_MIO_10_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_10_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_10_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_10_SLEW {slow} \ + CONFIG.PSU_MIO_11_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_11_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_11_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_11_SLEW {slow} \ + CONFIG.PSU_MIO_12_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_12_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_12_POLARITY {Default} \ + CONFIG.PSU_MIO_12_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_12_SLEW {slow} \ + CONFIG.PSU_MIO_13_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_13_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_13_POLARITY {Default} \ + CONFIG.PSU_MIO_13_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_13_SLEW {slow} \ + CONFIG.PSU_MIO_14_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_14_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_14_POLARITY {Default} \ + CONFIG.PSU_MIO_14_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_14_SLEW {slow} \ + CONFIG.PSU_MIO_15_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_15_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_15_POLARITY {Default} \ + CONFIG.PSU_MIO_15_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_15_SLEW {slow} \ + CONFIG.PSU_MIO_16_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_16_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_16_POLARITY {Default} \ + CONFIG.PSU_MIO_16_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_16_SLEW {slow} \ + CONFIG.PSU_MIO_17_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_17_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_17_POLARITY {Default} \ + CONFIG.PSU_MIO_17_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_17_SLEW {slow} \ + CONFIG.PSU_MIO_18_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_18_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_18_POLARITY {Default} \ + CONFIG.PSU_MIO_18_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_18_SLEW {slow} \ + CONFIG.PSU_MIO_19_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_19_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_19_POLARITY {Default} \ + CONFIG.PSU_MIO_19_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_19_SLEW {slow} \ + CONFIG.PSU_MIO_1_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_1_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_1_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_1_SLEW {slow} \ + CONFIG.PSU_MIO_20_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_20_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_20_POLARITY {Default} \ + CONFIG.PSU_MIO_20_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_20_SLEW {slow} \ + CONFIG.PSU_MIO_21_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_21_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_21_POLARITY {Default} \ + CONFIG.PSU_MIO_21_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_21_SLEW {slow} \ + CONFIG.PSU_MIO_22_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_22_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_22_POLARITY {Default} \ + CONFIG.PSU_MIO_22_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_22_SLEW {slow} \ + CONFIG.PSU_MIO_23_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_23_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_23_POLARITY {Default} \ + CONFIG.PSU_MIO_23_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_23_SLEW {slow} \ + CONFIG.PSU_MIO_24_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_24_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_24_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_24_SLEW {slow} \ + CONFIG.PSU_MIO_25_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_25_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_25_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_25_SLEW {slow} \ + CONFIG.PSU_MIO_26_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_26_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_27_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_27_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_27_SLEW {slow} \ + CONFIG.PSU_MIO_28_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_28_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_29_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_29_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_29_SLEW {slow} \ + CONFIG.PSU_MIO_2_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_2_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_2_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_2_SLEW {slow} \ + CONFIG.PSU_MIO_30_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_30_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_31_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_31_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_32_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_32_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_32_POLARITY {Default} \ + CONFIG.PSU_MIO_32_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_32_SLEW {slow} \ + CONFIG.PSU_MIO_33_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_33_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_33_POLARITY {Default} \ + CONFIG.PSU_MIO_33_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_33_SLEW {slow} \ + CONFIG.PSU_MIO_34_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_34_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_34_POLARITY {Default} \ + CONFIG.PSU_MIO_34_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_34_SLEW {slow} \ + CONFIG.PSU_MIO_35_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_35_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_35_SLEW {slow} \ + CONFIG.PSU_MIO_36_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_36_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_36_SLEW {slow} \ + CONFIG.PSU_MIO_37_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_37_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_38_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_38_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_38_POLARITY {Default} \ + CONFIG.PSU_MIO_38_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_38_SLEW {slow} \ + CONFIG.PSU_MIO_39_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_39_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_39_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_39_SLEW {slow} \ + CONFIG.PSU_MIO_3_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_3_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_3_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_3_SLEW {slow} \ + CONFIG.PSU_MIO_40_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_40_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_40_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_40_SLEW {slow} \ + CONFIG.PSU_MIO_41_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_41_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_41_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_41_SLEW {slow} \ + CONFIG.PSU_MIO_42_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_42_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_42_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_42_SLEW {slow} \ + CONFIG.PSU_MIO_43_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_43_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_43_SLEW {slow} \ + CONFIG.PSU_MIO_44_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_44_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_44_POLARITY {Default} \ + CONFIG.PSU_MIO_44_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_44_SLEW {slow} \ + CONFIG.PSU_MIO_45_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_45_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_46_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_46_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_46_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_46_SLEW {slow} \ + CONFIG.PSU_MIO_47_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_47_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_47_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_47_SLEW {slow} \ + CONFIG.PSU_MIO_48_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_48_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_48_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_48_SLEW {slow} \ + CONFIG.PSU_MIO_49_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_49_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_49_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_49_SLEW {slow} \ + CONFIG.PSU_MIO_4_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_4_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_4_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_4_SLEW {slow} \ + CONFIG.PSU_MIO_50_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_50_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_50_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_50_SLEW {slow} \ + CONFIG.PSU_MIO_51_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_51_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_51_SLEW {slow} \ + CONFIG.PSU_MIO_52_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_52_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_53_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_53_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_54_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_54_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_54_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_54_SLEW {slow} \ + CONFIG.PSU_MIO_55_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_55_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_56_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_56_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_56_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_56_SLEW {slow} \ + CONFIG.PSU_MIO_57_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_57_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_57_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_57_SLEW {slow} \ + CONFIG.PSU_MIO_58_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_58_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_58_SLEW {slow} \ + CONFIG.PSU_MIO_59_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_59_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_59_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_59_SLEW {slow} \ + CONFIG.PSU_MIO_5_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_5_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_5_SLEW {slow} \ + CONFIG.PSU_MIO_60_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_60_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_60_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_60_SLEW {slow} \ + CONFIG.PSU_MIO_61_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_61_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_61_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_61_SLEW {slow} \ + CONFIG.PSU_MIO_62_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_62_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_62_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_62_SLEW {slow} \ + CONFIG.PSU_MIO_63_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_63_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_63_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_63_SLEW {slow} \ + CONFIG.PSU_MIO_64_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_64_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_64_SLEW {slow} \ + CONFIG.PSU_MIO_65_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_65_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_65_SLEW {slow} \ + CONFIG.PSU_MIO_66_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_66_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_66_SLEW {slow} \ + CONFIG.PSU_MIO_67_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_67_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_67_SLEW {slow} \ + CONFIG.PSU_MIO_68_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_68_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_68_SLEW {slow} \ + CONFIG.PSU_MIO_69_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_69_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_69_SLEW {slow} \ + CONFIG.PSU_MIO_6_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_6_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_6_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_6_SLEW {slow} \ + CONFIG.PSU_MIO_70_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_70_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_71_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_71_PULLUPDOWN {disable} \ + CONFIG.PSU_MIO_72_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_72_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_73_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_73_PULLUPDOWN {disable} \ + CONFIG.PSU_MIO_74_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_74_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_75_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_75_PULLUPDOWN {disable} \ + CONFIG.PSU_MIO_76_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_76_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_76_SLEW {slow} \ + CONFIG.PSU_MIO_77_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_77_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_77_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_77_SLEW {slow} \ + CONFIG.PSU_MIO_7_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_7_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_7_POLARITY {Default} \ + CONFIG.PSU_MIO_7_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_7_SLEW {slow} \ + CONFIG.PSU_MIO_8_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_8_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_8_POLARITY {Default} \ + CONFIG.PSU_MIO_8_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_8_SLEW {slow} \ + CONFIG.PSU_MIO_9_DRIVE_STRENGTH {4} \ + CONFIG.PSU_MIO_9_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_9_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_9_SLEW {slow} \ + CONFIG.PSU_MIO_TREE_PERIPHERALS {Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#SPI 1#GPIO0 MIO#GPIO0 MIO#SPI 1#SPI 1#SPI 1#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0\ +MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#GPIO0 MIO#I2C 1#I2C 1#PMU GPI 0#DPAUX#DPAUX#DPAUX#DPAUX#PMU GPI 5#GPIO1 MIO#GPIO1 MIO#GPIO1 MIO#PMU GPO 3#UART 1#UART 1#GPIO1 MIO#SD\ +1#SD 1#SD 1#SD 1#SD 1#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem\ +3#Gem 3#MDIO 3#MDIO 3} \ + CONFIG.PSU_MIO_TREE_SIGNALS {sclk_out#miso_mo1#mo2#mo3#mosi_mi0#n_ss_out#sclk_out#gpio0[7]#gpio0[8]#n_ss_out[0]#miso#mosi#gpio0[12]#gpio0[13]#gpio0[14]#gpio0[15]#gpio0[16]#gpio0[17]#gpio0[18]#gpio0[19]#gpio0[20]#gpio0[21]#gpio0[22]#gpio0[23]#scl_out#sda_out#gpi[0]#dp_aux_data_out#dp_hot_plug_detect#dp_aux_data_oe#dp_aux_data_in#gpi[5]#gpio1[32]#gpio1[33]#gpio1[34]#gpo[3]#txd#rxd#gpio1[38]#sdio1_data_out[4]#sdio1_data_out[5]#sdio1_data_out[6]#sdio1_data_out[7]#sdio1_bus_pow#gpio1[44]#sdio1_cd_n#sdio1_data_out[0]#sdio1_data_out[1]#sdio1_data_out[2]#sdio1_data_out[3]#sdio1_cmd_out#sdio1_clk_out#ulpi_clk_in#ulpi_dir#ulpi_tx_data[2]#ulpi_nxt#ulpi_tx_data[0]#ulpi_tx_data[1]#ulpi_stp#ulpi_tx_data[3]#ulpi_tx_data[4]#ulpi_tx_data[5]#ulpi_tx_data[6]#ulpi_tx_data[7]#rgmii_tx_clk#rgmii_txd[0]#rgmii_txd[1]#rgmii_txd[2]#rgmii_txd[3]#rgmii_tx_ctl#rgmii_rx_clk#rgmii_rxd[0]#rgmii_rxd[1]#rgmii_rxd[2]#rgmii_rxd[3]#rgmii_rx_ctl#gem3_mdc#gem3_mdio_out}\ +\ + CONFIG.PSU_PERIPHERAL_BOARD_PRESET {} \ + CONFIG.PSU_SD0_INTERNAL_BUS_WIDTH {8} \ + CONFIG.PSU_SD1_INTERNAL_BUS_WIDTH {8} \ + CONFIG.PSU_SMC_CYCLE_T0 {NA} \ + CONFIG.PSU_SMC_CYCLE_T1 {NA} \ + CONFIG.PSU_SMC_CYCLE_T2 {NA} \ + CONFIG.PSU_SMC_CYCLE_T3 {NA} \ + CONFIG.PSU_SMC_CYCLE_T4 {NA} \ + CONFIG.PSU_SMC_CYCLE_T5 {NA} \ + CONFIG.PSU_SMC_CYCLE_T6 {NA} \ + CONFIG.PSU_USB3__DUAL_CLOCK_ENABLE {1} \ + CONFIG.PSU_VALUE_SILVERSION {3} \ + CONFIG.PSU__ACPU0__POWER__ON {1} \ + CONFIG.PSU__ACPU1__POWER__ON {1} \ + CONFIG.PSU__ACPU2__POWER__ON {1} \ + CONFIG.PSU__ACPU3__POWER__ON {1} \ + CONFIG.PSU__ACTUAL__IP {1} \ + CONFIG.PSU__ACT_DDR_FREQ_MHZ {1066.656006} \ + CONFIG.PSU__AFI0_COHERENCY {0} \ + CONFIG.PSU__AUX_REF_CLK__FREQMHZ {33.333} \ + CONFIG.PSU__CAN0_LOOP_CAN1__ENABLE {0} \ + CONFIG.PSU__CAN0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__CAN1__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__ACT_FREQMHZ {1333.333008} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__FREQMHZ {1333.333} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__ACPU__FRAC_ENABLED {1} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI0_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI1_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI2_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI3_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI4_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI5_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FRACFREQ {1333.333} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__APLL_FRAC_CFG__ENABLED {1} \ + CONFIG.PSU__CRF_APB__APM_CTRL__ACT_FREQMHZ {1} \ + CONFIG.PSU__CRF_APB__APM_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__APM_CTRL__FREQMHZ {1} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__ACT_FREQMHZ {533.328003} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__FREQMHZ {1200} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__ACT_FREQMHZ {444.444336} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__ACT_FREQMHZ {24.242182} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__FREQMHZ {25} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_AUDIO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__ACT_FREQMHZ {26.666401} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__FREQMHZ {27} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__ACT_FREQMHZ {299.997009} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__FREQMHZ {300} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__ACT_FREQMHZ {533.328003} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__ACT_FREQMHZ {499.994995} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__ACT_FREQMHZ {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__DIVISOR0 {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__FREQMHZ {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__SRCSEL {NA} \ + CONFIG.PSU__CRF_APB__GTGREF0__ENABLE {NA} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__ACT_FREQMHZ {533.328003} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__FREQMHZ {533.33} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__ACT_FREQMHZ {499.994995} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__ACT_FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AFI6__ENABLE {0} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__ACT_FREQMHZ {49.999500} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__FREQMHZ {50} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__ACT_FREQMHZ {533.328003} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__FREQMHZ {533.333} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__ACT_FREQMHZ {180} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__SRCSEL {SysOsc} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__ACT_FREQMHZ {1000} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__FREQMHZ {1000} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__ACT_FREQMHZ {1499.984985} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__FREQMHZ {1500} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__ACT_FREQMHZ {124.998749} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__ACT_FREQMHZ {499.994995} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__ACT_FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__ACT_FREQMHZ {187.498123} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__ACT_FREQMHZ {124.998749} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__ACT_FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__ACT_FREQMHZ {187.498123} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__ACT_FREQMHZ {214} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__ACT_FREQMHZ {187.498123} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__ACT_FREQMHZ {249.997498} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__ACT_FREQMHZ {19.999800} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__FREQMHZ {20} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3__ENABLE {1} \ + CONFIG.PSU__CSUPMU__PERIPHERAL__VALID {1} \ + CONFIG.PSU__CSU__CSU_TAMPER_0__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_10__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_11__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_12__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_1__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_2__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_3__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_4__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_5__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_6__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_7__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_8__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_9__ENABLE {0} \ + CONFIG.PSU__CSU__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__DDRC__AL {0} \ + CONFIG.PSU__DDRC__BG_ADDR_COUNT {1} \ + CONFIG.PSU__DDRC__BRC_MAPPING {ROW_BANK_COL} \ + CONFIG.PSU__DDRC__BUS_WIDTH {64 Bit} \ + CONFIG.PSU__DDRC__CL {16} \ + CONFIG.PSU__DDRC__CLOCK_STOP_EN {0} \ + CONFIG.PSU__DDRC__COMPONENTS {Components} \ + CONFIG.PSU__DDRC__CWL {14} \ + CONFIG.PSU__DDRC__DDR4_ADDR_MAPPING {0} \ + CONFIG.PSU__DDRC__DDR4_CAL_MODE_ENABLE {0} \ + CONFIG.PSU__DDRC__DDR4_CRC_CONTROL {0} \ + CONFIG.PSU__DDRC__DDR4_MAXPWR_SAVING_EN {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_MODE {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_RANGE {Normal (0-85)} \ + CONFIG.PSU__DDRC__DEVICE_CAPACITY {8192 MBits} \ + CONFIG.PSU__DDRC__DM_DBI {DM_NO_DBI} \ + CONFIG.PSU__DDRC__DRAM_WIDTH {16 Bits} \ + CONFIG.PSU__DDRC__ECC {Disabled} \ + CONFIG.PSU__DDRC__ECC_SCRUB {0} \ + CONFIG.PSU__DDRC__ENABLE {1} \ + CONFIG.PSU__DDRC__ENABLE_2T_TIMING {0} \ + CONFIG.PSU__DDRC__ENABLE_DP_SWITCH {0} \ + CONFIG.PSU__DDRC__EN_2ND_CLK {0} \ + CONFIG.PSU__DDRC__FGRM {1X} \ + CONFIG.PSU__DDRC__FREQ_MHZ {1} \ + CONFIG.PSU__DDRC__LPDDR3_DUALRANK_SDP {0} \ + CONFIG.PSU__DDRC__LP_ASR {manual normal} \ + CONFIG.PSU__DDRC__MEMORY_TYPE {DDR 4} \ + CONFIG.PSU__DDRC__PARITY_ENABLE {0} \ + CONFIG.PSU__DDRC__PER_BANK_REFRESH {0} \ + CONFIG.PSU__DDRC__PHY_DBI_MODE {0} \ + CONFIG.PSU__DDRC__PLL_BYPASS {0} \ + CONFIG.PSU__DDRC__PWR_DOWN_EN {0} \ + CONFIG.PSU__DDRC__RANK_ADDR_COUNT {0} \ + CONFIG.PSU__DDRC__RD_DQS_CENTER {0} \ + CONFIG.PSU__DDRC__ROW_ADDR_COUNT {16} \ + CONFIG.PSU__DDRC__SELF_REF_ABORT {0} \ + CONFIG.PSU__DDRC__SPEED_BIN {DDR4_2400R} \ + CONFIG.PSU__DDRC__STATIC_RD_MODE {0} \ + CONFIG.PSU__DDRC__TRAIN_DATA_EYE {1} \ + CONFIG.PSU__DDRC__TRAIN_READ_GATE {1} \ + CONFIG.PSU__DDRC__TRAIN_WRITE_LEVEL {1} \ + CONFIG.PSU__DDRC__T_FAW {30.0} \ + CONFIG.PSU__DDRC__T_RAS_MIN {33} \ + CONFIG.PSU__DDRC__T_RC {47.06} \ + CONFIG.PSU__DDRC__T_RCD {16} \ + CONFIG.PSU__DDRC__T_RP {16} \ + CONFIG.PSU__DDRC__VIDEO_BUFFER_SIZE {0} \ + CONFIG.PSU__DDRC__VREF {1} \ + CONFIG.PSU__DDR_HIGH_ADDRESS_GUI_ENABLE {1} \ + CONFIG.PSU__DDR_QOS_ENABLE {0} \ + CONFIG.PSU__DDR_QOS_HP0_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP0_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP1_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP1_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP2_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP2_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP3_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP3_WRQOS {} \ + CONFIG.PSU__DDR_SW_REFRESH_ENABLED {1} \ + CONFIG.PSU__DDR__INTERFACE__FREQMHZ {600.000} \ + CONFIG.PSU__DEVICE_TYPE {EV} \ + CONFIG.PSU__DISPLAYPORT__LANE0__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE0__IO {GT Lane1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__IO {GT Lane0} \ + CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DLL__ISUSED {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \ + CONFIG.PSU__DP__LANE_SEL {Dual Lower} \ + CONFIG.PSU__DP__REF_CLK_FREQ {27} \ + CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk0} \ + CONFIG.PSU__ENABLE__DDR__REFRESH__SIGNALS {0} \ + CONFIG.PSU__ENET0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET1__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET2__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET3__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET3__GRP_MDIO__ENABLE {1} \ + CONFIG.PSU__ENET3__GRP_MDIO__IO {MIO 76 .. 77} \ + CONFIG.PSU__ENET3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__ENET3__PERIPHERAL__IO {MIO 64 .. 75} \ + CONFIG.PSU__ENET3__PTP__ENABLE {0} \ + CONFIG.PSU__ENET3__TSU__ENABLE {0} \ + CONFIG.PSU__EN_AXI_STATUS_PORTS {0} \ + CONFIG.PSU__EN_EMIO_TRACE {0} \ + CONFIG.PSU__EP__IP {0} \ + CONFIG.PSU__EXPAND__CORESIGHT {0} \ + CONFIG.PSU__EXPAND__FPD_SLAVES {0} \ + CONFIG.PSU__EXPAND__GIC {0} \ + CONFIG.PSU__EXPAND__LOWER_LPS_SLAVES {0} \ + CONFIG.PSU__EXPAND__UPPER_LPS_SLAVES {0} \ + CONFIG.PSU__FPD_SLCR__WDT1__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__FPGA_PL0_ENABLE {1} \ + CONFIG.PSU__FPGA_PL1_ENABLE {1} \ + CONFIG.PSU__FPGA_PL2_ENABLE {0} \ + CONFIG.PSU__FPGA_PL3_ENABLE {0} \ + CONFIG.PSU__FP__POWER__ON {1} \ + CONFIG.PSU__FTM__CTI_IN_0 {0} \ + CONFIG.PSU__FTM__CTI_IN_1 {0} \ + CONFIG.PSU__FTM__CTI_IN_2 {0} \ + CONFIG.PSU__FTM__CTI_IN_3 {0} \ + CONFIG.PSU__FTM__CTI_OUT_0 {0} \ + CONFIG.PSU__FTM__CTI_OUT_1 {0} \ + CONFIG.PSU__FTM__CTI_OUT_2 {0} \ + CONFIG.PSU__FTM__CTI_OUT_3 {0} \ + CONFIG.PSU__FTM__GPI {0} \ + CONFIG.PSU__FTM__GPO {0} \ + CONFIG.PSU__GEM3_COHERENCY {0} \ + CONFIG.PSU__GEM3_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM__TSU__ENABLE {0} \ + CONFIG.PSU__GEN_IPI_0__MASTER {APU} \ + CONFIG.PSU__GEN_IPI_10__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_1__MASTER {RPU0} \ + CONFIG.PSU__GEN_IPI_2__MASTER {RPU1} \ + CONFIG.PSU__GEN_IPI_3__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_4__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_5__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_6__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_7__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_8__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_9__MASTER {NONE} \ + CONFIG.PSU__GPIO0_MIO__IO {MIO 0 .. 25} \ + CONFIG.PSU__GPIO0_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO1_MIO__IO {MIO 26 .. 51} \ + CONFIG.PSU__GPIO1_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO2_MIO__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__GPIO_EMIO_WIDTH {1} \ + CONFIG.PSU__GPIO_EMIO__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__GPIO_EMIO__WIDTH {[94:0]} \ + CONFIG.PSU__GPU_PP0__POWER__ON {1} \ + CONFIG.PSU__GPU_PP1__POWER__ON {1} \ + CONFIG.PSU__GT_REF_CLK__FREQMHZ {33.333} \ + CONFIG.PSU__GT__LINK_SPEED {HBR} \ + CONFIG.PSU__GT__PRE_EMPH_LVL_4 {0} \ + CONFIG.PSU__GT__VLT_SWNG_LVL_4 {0} \ + CONFIG.PSU__HPM0_FPD__NUM_READ_THREADS {4} \ + CONFIG.PSU__HPM0_FPD__NUM_WRITE_THREADS {4} \ + CONFIG.PSU__HPM0_LPD__NUM_READ_THREADS {4} \ + CONFIG.PSU__HPM0_LPD__NUM_WRITE_THREADS {4} \ + CONFIG.PSU__HPM1_FPD__NUM_READ_THREADS {4} \ + CONFIG.PSU__HPM1_FPD__NUM_WRITE_THREADS {4} \ + CONFIG.PSU__I2C0_LOOP_I2C1__ENABLE {0} \ + CONFIG.PSU__I2C0__GRP_INT__ENABLE {0} \ + CONFIG.PSU__I2C0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__I2C1__GRP_INT__ENABLE {0} \ + CONFIG.PSU__I2C1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__I2C1__PERIPHERAL__IO {MIO 24 .. 25} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC0_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC1_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC2_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC3_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__TTC0__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC1__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC2__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC3__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__WDT0__ACT_FREQMHZ {99.999001} \ + CONFIG.PSU__IRQ_P2F_ADMA_CHAN__INT {0} \ + CONFIG.PSU__IRQ_P2F_AIB_AXI__INT {0} \ + CONFIG.PSU__IRQ_P2F_AMS__INT {0} \ + CONFIG.PSU__IRQ_P2F_APM_FPD__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_COMM__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_CPUMNT__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_CTI__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_EXTERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_IPI__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_L2ERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_PMU__INT {0} \ + CONFIG.PSU__IRQ_P2F_APU_REGS__INT {0} \ + CONFIG.PSU__IRQ_P2F_ATB_LPD__INT {0} \ + CONFIG.PSU__IRQ_P2F_CLKMON__INT {0} \ + CONFIG.PSU__IRQ_P2F_CSUPMU_WDT__INT {0} \ + CONFIG.PSU__IRQ_P2F_DDR_SS__INT {0} \ + CONFIG.PSU__IRQ_P2F_DPDMA__INT {0} \ + CONFIG.PSU__IRQ_P2F_DPORT__INT {0} \ + CONFIG.PSU__IRQ_P2F_EFUSE__INT {0} \ + CONFIG.PSU__IRQ_P2F_ENT3_WAKEUP__INT {0} \ + CONFIG.PSU__IRQ_P2F_ENT3__INT {0} \ + CONFIG.PSU__IRQ_P2F_FPD_APB__INT {0} \ + CONFIG.PSU__IRQ_P2F_FPD_ATB_ERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_FP_WDT__INT {0} \ + CONFIG.PSU__IRQ_P2F_GDMA_CHAN__INT {0} \ + CONFIG.PSU__IRQ_P2F_GPIO__INT {0} \ + CONFIG.PSU__IRQ_P2F_GPU__INT {0} \ + CONFIG.PSU__IRQ_P2F_I2C1__INT {0} \ + CONFIG.PSU__IRQ_P2F_LPD_APB__INT {0} \ + CONFIG.PSU__IRQ_P2F_LPD_APM__INT {0} \ + CONFIG.PSU__IRQ_P2F_LP_WDT__INT {0} \ + CONFIG.PSU__IRQ_P2F_OCM_ERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_PCIE_DMA__INT {0} \ + CONFIG.PSU__IRQ_P2F_PCIE_LEGACY__INT {0} \ + CONFIG.PSU__IRQ_P2F_PCIE_MSC__INT {0} \ + CONFIG.PSU__IRQ_P2F_PCIE_MSI__INT {0} \ + CONFIG.PSU__IRQ_P2F_PL_IPI__INT {0} \ + CONFIG.PSU__IRQ_P2F_QSPI__INT {0} \ + CONFIG.PSU__IRQ_P2F_R5_CORE0_ECC_ERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_R5_CORE1_ECC_ERR__INT {0} \ + CONFIG.PSU__IRQ_P2F_RPU_IPI__INT {0} \ + CONFIG.PSU__IRQ_P2F_RPU_PERMON__INT {0} \ + CONFIG.PSU__IRQ_P2F_RTC_ALARM__INT {0} \ + CONFIG.PSU__IRQ_P2F_RTC_SECONDS__INT {0} \ + CONFIG.PSU__IRQ_P2F_SATA__INT {0} \ + CONFIG.PSU__IRQ_P2F_SDIO1_WAKE__INT {0} \ + CONFIG.PSU__IRQ_P2F_SDIO1__INT {0} \ + CONFIG.PSU__IRQ_P2F_SPI1__INT {0} \ + CONFIG.PSU__IRQ_P2F_TTC0__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_TTC0__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_TTC0__INT2 {0} \ + CONFIG.PSU__IRQ_P2F_TTC1__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_TTC1__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_TTC1__INT2 {0} \ + CONFIG.PSU__IRQ_P2F_TTC2__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_TTC2__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_TTC2__INT2 {0} \ + CONFIG.PSU__IRQ_P2F_TTC3__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_TTC3__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_TTC3__INT2 {0} \ + CONFIG.PSU__IRQ_P2F_UART1__INT {0} \ + CONFIG.PSU__IRQ_P2F_USB3_ENDPOINT__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_USB3_ENDPOINT__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_USB3_OTG__INT0 {0} \ + CONFIG.PSU__IRQ_P2F_USB3_OTG__INT1 {0} \ + CONFIG.PSU__IRQ_P2F_USB3_PMU_WAKEUP__INT {0} \ + CONFIG.PSU__IRQ_P2F_XMPU_FPD__INT {0} \ + CONFIG.PSU__IRQ_P2F_XMPU_LPD__INT {0} \ + CONFIG.PSU__IRQ_P2F__INTF_FPD_SMMU__INT {0} \ + CONFIG.PSU__IRQ_P2F__INTF_PPD_CCI__INT {0} \ + CONFIG.PSU__L2_BANK0__POWER__ON {1} \ + CONFIG.PSU__LPDMA0_COHERENCY {0} \ + CONFIG.PSU__LPDMA1_COHERENCY {0} \ + CONFIG.PSU__LPDMA2_COHERENCY {0} \ + CONFIG.PSU__LPDMA3_COHERENCY {0} \ + CONFIG.PSU__LPDMA4_COHERENCY {0} \ + CONFIG.PSU__LPDMA5_COHERENCY {0} \ + CONFIG.PSU__LPDMA6_COHERENCY {0} \ + CONFIG.PSU__LPDMA7_COHERENCY {0} \ + CONFIG.PSU__LPD_SLCR__CSUPMU_WDT_CLK_SEL__SELECT {APB} \ + CONFIG.PSU__LPD_SLCR__CSUPMU__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__MAXIGP2__DATA_WIDTH {32} \ + CONFIG.PSU__M_AXI_GP0_SUPPORTS_NARROW_BURST {1} \ + CONFIG.PSU__M_AXI_GP1_SUPPORTS_NARROW_BURST {1} \ + CONFIG.PSU__M_AXI_GP2_SUPPORTS_NARROW_BURST {1} \ + CONFIG.PSU__NAND__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__NAND__READY_BUSY__ENABLE {0} \ + CONFIG.PSU__NUM_FABRIC_RESETS {1} \ + CONFIG.PSU__OCM_BANK0__POWER__ON {1} \ + CONFIG.PSU__OCM_BANK1__POWER__ON {1} \ + CONFIG.PSU__OCM_BANK2__POWER__ON {1} \ + CONFIG.PSU__OCM_BANK3__POWER__ON {1} \ + CONFIG.PSU__OVERRIDE_HPX_QOS {0} \ + CONFIG.PSU__OVERRIDE__BASIC_CLOCK {0} \ + CONFIG.PSU__PCIE__ACS_VIOLAION {0} \ + CONFIG.PSU__PCIE__AER_CAPABILITY {0} \ + CONFIG.PSU__PCIE__CLASS_CODE_BASE {} \ + CONFIG.PSU__PCIE__CLASS_CODE_INTERFACE {} \ + CONFIG.PSU__PCIE__CLASS_CODE_SUB {} \ + CONFIG.PSU__PCIE__DEVICE_ID {} \ + CONFIG.PSU__PCIE__INTX_GENERATION {0} \ + CONFIG.PSU__PCIE__MSIX_CAPABILITY {0} \ + CONFIG.PSU__PCIE__MSI_CAPABILITY {0} \ + CONFIG.PSU__PCIE__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__PCIE__PERIPHERAL__ENDPOINT_ENABLE {1} \ + CONFIG.PSU__PCIE__PERIPHERAL__ROOTPORT_ENABLE {0} \ + CONFIG.PSU__PCIE__RESET__POLARITY {Active Low} \ + CONFIG.PSU__PCIE__REVISION_ID {} \ + CONFIG.PSU__PCIE__SUBSYSTEM_ID {} \ + CONFIG.PSU__PCIE__SUBSYSTEM_VENDOR_ID {} \ + CONFIG.PSU__PCIE__VENDOR_ID {} \ + CONFIG.PSU__PJTAG__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__PL_CLK0_BUF {TRUE} \ + CONFIG.PSU__PL_CLK1_BUF {TRUE} \ + CONFIG.PSU__PL__POWER__ON {1} \ + CONFIG.PSU__PMU_COHERENCY {0} \ + CONFIG.PSU__PMU__AIBACK__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPI__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPO__ENABLE {0} \ + CONFIG.PSU__PMU__GPI0__ENABLE {1} \ + CONFIG.PSU__PMU__GPI0__IO {MIO 26} \ + CONFIG.PSU__PMU__GPI1__ENABLE {0} \ + CONFIG.PSU__PMU__GPI2__ENABLE {0} \ + CONFIG.PSU__PMU__GPI3__ENABLE {0} \ + CONFIG.PSU__PMU__GPI4__ENABLE {0} \ + CONFIG.PSU__PMU__GPI5__ENABLE {1} \ + CONFIG.PSU__PMU__GPI5__IO {MIO 31} \ + CONFIG.PSU__PMU__GPO0__ENABLE {0} \ + CONFIG.PSU__PMU__GPO1__ENABLE {0} \ + CONFIG.PSU__PMU__GPO2__ENABLE {0} \ + CONFIG.PSU__PMU__GPO3__ENABLE {1} \ + CONFIG.PSU__PMU__GPO3__IO {MIO 35} \ + CONFIG.PSU__PMU__GPO3__POLARITY {low} \ + CONFIG.PSU__PMU__GPO4__ENABLE {0} \ + CONFIG.PSU__PMU__GPO5__ENABLE {0} \ + CONFIG.PSU__PMU__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__PMU__PLERROR__ENABLE {0} \ + CONFIG.PSU__PRESET_APPLIED {1} \ + CONFIG.PSU__PROTECTION__DDR_SEGMENTS {NONE} \ + CONFIG.PSU__PROTECTION__ENABLE {0} \ + CONFIG.PSU__PROTECTION__FPD_SEGMENTS {SA:0xFD1A0000; SIZE:1280; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFD000000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write;\ +subsystemId:PMU Firmware| SA:0xFD010000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFD020000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU\ +Firmware| SA:0xFD030000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFD040000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware|\ +SA:0xFD050000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFD610000; SIZE:512; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFD5D0000;\ +SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware|SA:0xFD1A0000 ; SIZE:1280; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem} \ + CONFIG.PSU__PROTECTION__LPD_SEGMENTS {SA:0xFF980000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF5E0000; SIZE:2560; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write;\ +subsystemId:PMU Firmware| SA:0xFFCC0000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF180000; SIZE:768; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU\ +Firmware| SA:0xFF410000; SIZE:640; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFFA70000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware|\ +SA:0xFF9A0000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware|SA:0xFF5E0000 ; SIZE:2560; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFFCC0000\ +; SIZE:64; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFF180000 ; SIZE:768; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFF9A0000\ +; SIZE:64; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem} \ + CONFIG.PSU__PROTECTION__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;0|S_AXI_HPC0_FPD:NA;1|S_AXI_HP3_FPD:NA;0|S_AXI_HP2_FPD:NA;0|S_AXI_HP1_FPD:NA;0|S_AXI_HP0_FPD:NA;0|S_AXI_ACP:NA;0|S_AXI_ACE:NA;0|SD1:NonSecure;1|SD0:NonSecure;0|SATA1:NonSecure;0|SATA0:NonSecure;0|RPU1:Secure;1|RPU0:Secure;1|QSPI:NonSecure;1|PMU:NA;1|PCIe:NonSecure;0|NAND:NonSecure;0|LDMA:NonSecure;1|GPU:NonSecure;1|GEM3:NonSecure;1|GEM2:NonSecure;0|GEM1:NonSecure;0|GEM0:NonSecure;0|FDMA:NonSecure;1|DP:NonSecure;1|DAP:NA;1|Coresight:NA;1|CSU:NA;1|APU:NA;1}\ +\ + CONFIG.PSU__PROTECTION__MASTERS_TZ {GEM0:NonSecure|SD1:NonSecure|GEM2:NonSecure|GEM1:NonSecure|GEM3:NonSecure|PCIe:NonSecure|DP:NonSecure|NAND:NonSecure|GPU:NonSecure|USB1:NonSecure|USB0:NonSecure|LDMA:NonSecure|FDMA:NonSecure|QSPI:NonSecure|SD0:NonSecure}\ +\ + CONFIG.PSU__PROTECTION__OCM_SEGMENTS {NONE} \ + CONFIG.PSU__PROTECTION__PRESUBSYSTEMS {NONE} \ + CONFIG.PSU__PROTECTION__SLAVES {LPD;USB3_1_XHCI;FE300000;FE3FFFFF;0|LPD;USB3_1;FF9E0000;FF9EFFFF;0|LPD;USB3_0_XHCI;FE200000;FE2FFFFF;1|LPD;USB3_0;FF9D0000;FF9DFFFF;1|LPD;UART1;FF010000;FF01FFFF;1|LPD;UART0;FF000000;FF00FFFF;0|LPD;TTC3;FF140000;FF14FFFF;1|LPD;TTC2;FF130000;FF13FFFF;1|LPD;TTC1;FF120000;FF12FFFF;1|LPD;TTC0;FF110000;FF11FFFF;1|FPD;SWDT1;FD4D0000;FD4DFFFF;1|LPD;SWDT0;FF150000;FF15FFFF;1|LPD;SPI1;FF050000;FF05FFFF;1|LPD;SPI0;FF040000;FF04FFFF;0|FPD;SMMU_REG;FD5F0000;FD5FFFFF;1|FPD;SMMU;FD800000;FDFFFFFF;1|FPD;SIOU;FD3D0000;FD3DFFFF;1|FPD;SERDES;FD400000;FD47FFFF;1|LPD;SD1;FF170000;FF17FFFF;1|LPD;SD0;FF160000;FF16FFFF;0|FPD;SATA;FD0C0000;FD0CFFFF;0|LPD;RTC;FFA60000;FFA6FFFF;1|LPD;RSA_CORE;FFCE0000;FFCEFFFF;1|LPD;RPU;FF9A0000;FF9AFFFF;1|LPD;R5_TCM_RAM_GLOBAL;FFE00000;FFE3FFFF;1|LPD;R5_1_Instruction_Cache;FFEC0000;FFECFFFF;1|LPD;R5_1_Data_Cache;FFED0000;FFEDFFFF;1|LPD;R5_1_BTCM_GLOBAL;FFEB0000;FFEBFFFF;1|LPD;R5_1_ATCM_GLOBAL;FFE90000;FFE9FFFF;1|LPD;R5_0_Instruction_Cache;FFE40000;FFE4FFFF;1|LPD;R5_0_Data_Cache;FFE50000;FFE5FFFF;1|LPD;R5_0_BTCM_GLOBAL;FFE20000;FFE2FFFF;1|LPD;R5_0_ATCM_GLOBAL;FFE00000;FFE0FFFF;1|LPD;QSPI_Linear_Address;C0000000;DFFFFFFF;1|LPD;QSPI;FF0F0000;FF0FFFFF;1|LPD;PMU_RAM;FFDC0000;FFDDFFFF;1|LPD;PMU_GLOBAL;FFD80000;FFDBFFFF;1|FPD;PCIE_MAIN;FD0E0000;FD0EFFFF;0|FPD;PCIE_LOW;E0000000;EFFFFFFF;0|FPD;PCIE_HIGH2;8000000000;BFFFFFFFFF;0|FPD;PCIE_HIGH1;600000000;7FFFFFFFF;0|FPD;PCIE_DMA;FD0F0000;FD0FFFFF;0|FPD;PCIE_ATTRIB;FD480000;FD48FFFF;0|LPD;OCM_XMPU_CFG;FFA70000;FFA7FFFF;1|LPD;OCM_SLCR;FF960000;FF96FFFF;1|OCM;OCM;FFFC0000;FFFFFFFF;1|LPD;NAND;FF100000;FF10FFFF;0|LPD;MBISTJTAG;FFCF0000;FFCFFFFF;1|LPD;LPD_XPPU_SINK;FF9C0000;FF9CFFFF;1|LPD;LPD_XPPU;FF980000;FF98FFFF;1|LPD;LPD_SLCR_SECURE;FF4B0000;FF4DFFFF;1|LPD;LPD_SLCR;FF410000;FF4AFFFF;1|LPD;LPD_GPV;FE100000;FE1FFFFF;1|LPD;LPD_DMA_7;FFAF0000;FFAFFFFF;1|LPD;LPD_DMA_6;FFAE0000;FFAEFFFF;1|LPD;LPD_DMA_5;FFAD0000;FFADFFFF;1|LPD;LPD_DMA_4;FFAC0000;FFACFFFF;1|LPD;LPD_DMA_3;FFAB0000;FFABFFFF;1|LPD;LPD_DMA_2;FFAA0000;FFAAFFFF;1|LPD;LPD_DMA_1;FFA90000;FFA9FFFF;1|LPD;LPD_DMA_0;FFA80000;FFA8FFFF;1|LPD;IPI_CTRL;FF380000;FF3FFFFF;1|LPD;IOU_SLCR;FF180000;FF23FFFF;1|LPD;IOU_SECURE_SLCR;FF240000;FF24FFFF;1|LPD;IOU_SCNTRS;FF260000;FF26FFFF;1|LPD;IOU_SCNTR;FF250000;FF25FFFF;1|LPD;IOU_GPV;FE000000;FE0FFFFF;1|LPD;I2C1;FF030000;FF03FFFF;1|LPD;I2C0;FF020000;FF02FFFF;0|FPD;GPU;FD4B0000;FD4BFFFF;1|LPD;GPIO;FF0A0000;FF0AFFFF;1|LPD;GEM3;FF0E0000;FF0EFFFF;1|LPD;GEM2;FF0D0000;FF0DFFFF;0|LPD;GEM1;FF0C0000;FF0CFFFF;0|LPD;GEM0;FF0B0000;FF0BFFFF;0|FPD;FPD_XMPU_SINK;FD4F0000;FD4FFFFF;1|FPD;FPD_XMPU_CFG;FD5D0000;FD5DFFFF;1|FPD;FPD_SLCR_SECURE;FD690000;FD6CFFFF;1|FPD;FPD_SLCR;FD610000;FD68FFFF;1|FPD;FPD_DMA_CH7;FD570000;FD57FFFF;1|FPD;FPD_DMA_CH6;FD560000;FD56FFFF;1|FPD;FPD_DMA_CH5;FD550000;FD55FFFF;1|FPD;FPD_DMA_CH4;FD540000;FD54FFFF;1|FPD;FPD_DMA_CH3;FD530000;FD53FFFF;1|FPD;FPD_DMA_CH2;FD520000;FD52FFFF;1|FPD;FPD_DMA_CH1;FD510000;FD51FFFF;1|FPD;FPD_DMA_CH0;FD500000;FD50FFFF;1|LPD;EFUSE;FFCC0000;FFCCFFFF;1|FPD;Display\ +Port;FD4A0000;FD4AFFFF;1|FPD;DPDMA;FD4C0000;FD4CFFFF;1|FPD;DDR_XMPU5_CFG;FD050000;FD05FFFF;1|FPD;DDR_XMPU4_CFG;FD040000;FD04FFFF;1|FPD;DDR_XMPU3_CFG;FD030000;FD03FFFF;1|FPD;DDR_XMPU2_CFG;FD020000;FD02FFFF;1|FPD;DDR_XMPU1_CFG;FD010000;FD01FFFF;1|FPD;DDR_XMPU0_CFG;FD000000;FD00FFFF;1|FPD;DDR_QOS_CTRL;FD090000;FD09FFFF;1|FPD;DDR_PHY;FD080000;FD08FFFF;1|DDR;DDR_LOW;0;7FFFFFFF;1|DDR;DDR_HIGH;800000000;87FFFFFFF;1|FPD;DDDR_CTRL;FD070000;FD070FFF;1|LPD;Coresight;FE800000;FEFFFFFF;1|LPD;CSU_DMA;FFC80000;FFC9FFFF;1|LPD;CSU;FFCA0000;FFCAFFFF;1|LPD;CRL_APB;FF5E0000;FF85FFFF;1|FPD;CRF_APB;FD1A0000;FD2DFFFF;1|FPD;CCI_REG;FD5E0000;FD5EFFFF;1|LPD;CAN1;FF070000;FF07FFFF;0|LPD;CAN0;FF060000;FF06FFFF;0|FPD;APU;FD5C0000;FD5CFFFF;1|LPD;APM_INTC_IOU;FFA20000;FFA2FFFF;1|LPD;APM_FPD_LPD;FFA30000;FFA3FFFF;1|FPD;APM_5;FD490000;FD49FFFF;1|FPD;APM_0;FD0B0000;FD0BFFFF;1|LPD;APM2;FFA10000;FFA1FFFF;1|LPD;APM1;FFA00000;FFA0FFFF;1|LPD;AMS;FFA50000;FFA5FFFF;1|FPD;AFI_5;FD3B0000;FD3BFFFF;1|FPD;AFI_4;FD3A0000;FD3AFFFF;1|FPD;AFI_3;FD390000;FD39FFFF;1|FPD;AFI_2;FD380000;FD38FFFF;1|FPD;AFI_1;FD370000;FD37FFFF;1|FPD;AFI_0;FD360000;FD36FFFF;1|LPD;AFIFM6;FF9B0000;FF9BFFFF;1|FPD;ACPU_GIC;F9010000;F907FFFF;1}\ +\ + CONFIG.PSU__PROTECTION__SUBSYSTEMS {PMU Firmware:PMU|Secure Subsystem:} \ + CONFIG.PSU__PSS_ALT_REF_CLK__ENABLE {0} \ + CONFIG.PSU__PSS_ALT_REF_CLK__FREQMHZ {33.333} \ + CONFIG.PSU__PSS_REF_CLK__FREQMHZ {33.333} \ + CONFIG.PSU__QSPI_COHERENCY {0} \ + CONFIG.PSU__QSPI_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__QSPI__GRP_FBCLK__ENABLE {0} \ + CONFIG.PSU__QSPI__PERIPHERAL__DATA_MODE {x4} \ + CONFIG.PSU__QSPI__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__QSPI__PERIPHERAL__IO {MIO 0 .. 5} \ + CONFIG.PSU__QSPI__PERIPHERAL__MODE {Single} \ + CONFIG.PSU__REPORT__DBGLOG {0} \ + CONFIG.PSU__RPU_COHERENCY {0} \ + CONFIG.PSU__RPU__POWER__ON {1} \ + CONFIG.PSU__SATA__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__SAXIGP0__DATA_WIDTH {128} \ + CONFIG.PSU__SD0__CLK_100_SDR_OTAP_DLY {0x00} \ + CONFIG.PSU__SD0__CLK_200_SDR_OTAP_DLY {0x00} \ + CONFIG.PSU__SD0__CLK_50_DDR_ITAP_DLY {0x00} \ + CONFIG.PSU__SD0__CLK_50_DDR_OTAP_DLY {0x00} \ + CONFIG.PSU__SD0__CLK_50_SDR_ITAP_DLY {0x00} \ + CONFIG.PSU__SD0__CLK_50_SDR_OTAP_DLY {0x00} \ + CONFIG.PSU__SD0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__SD0__RESET__ENABLE {0} \ + CONFIG.PSU__SD1_COHERENCY {0} \ + CONFIG.PSU__SD1_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__SD1__CLK_100_SDR_OTAP_DLY {0x3} \ + CONFIG.PSU__SD1__CLK_200_SDR_OTAP_DLY {0x3} \ + CONFIG.PSU__SD1__CLK_50_DDR_ITAP_DLY {0x3D} \ + CONFIG.PSU__SD1__CLK_50_DDR_OTAP_DLY {0x4} \ + CONFIG.PSU__SD1__CLK_50_SDR_ITAP_DLY {0x15} \ + CONFIG.PSU__SD1__CLK_50_SDR_OTAP_DLY {0x5} \ + CONFIG.PSU__SD1__DATA_TRANSFER_MODE {8Bit} \ + CONFIG.PSU__SD1__GRP_CD__ENABLE {1} \ + CONFIG.PSU__SD1__GRP_CD__IO {MIO 45} \ + CONFIG.PSU__SD1__GRP_POW__ENABLE {1} \ + CONFIG.PSU__SD1__GRP_POW__IO {MIO 43} \ + CONFIG.PSU__SD1__GRP_WP__ENABLE {0} \ + CONFIG.PSU__SD1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SD1__PERIPHERAL__IO {MIO 39 .. 51} \ + CONFIG.PSU__SD1__SLOT_TYPE {SD 3.0} \ + CONFIG.PSU__SPI0_LOOP_SPI1__ENABLE {0} \ + CONFIG.PSU__SPI0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__SPI1__GRP_SS0__IO {MIO 9} \ + CONFIG.PSU__SPI1__GRP_SS1__ENABLE {0} \ + CONFIG.PSU__SPI1__GRP_SS2__ENABLE {0} \ + CONFIG.PSU__SPI1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SPI1__PERIPHERAL__IO {MIO 6 .. 11} \ + CONFIG.PSU__SWDT0__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT0__PERIPHERAL__IO {NA} \ + CONFIG.PSU__SWDT0__RESET__ENABLE {0} \ + CONFIG.PSU__SWDT1__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT1__PERIPHERAL__IO {NA} \ + CONFIG.PSU__SWDT1__RESET__ENABLE {0} \ + CONFIG.PSU__TCM0A__POWER__ON {1} \ + CONFIG.PSU__TCM0B__POWER__ON {1} \ + CONFIG.PSU__TCM1A__POWER__ON {1} \ + CONFIG.PSU__TCM1B__POWER__ON {1} \ + CONFIG.PSU__TESTSCAN__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__TRACE__INTERNAL_WIDTH {32} \ + CONFIG.PSU__TRACE__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__TRISTATE__INVERTED {1} \ + CONFIG.PSU__TSU__BUFG_PORT_PAIR {0} \ + CONFIG.PSU__TTC0__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC0__PERIPHERAL__IO {NA} \ + CONFIG.PSU__TTC0__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC1__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC1__PERIPHERAL__IO {NA} \ + CONFIG.PSU__TTC1__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC2__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC2__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC2__PERIPHERAL__IO {NA} \ + CONFIG.PSU__TTC2__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC3__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC3__PERIPHERAL__IO {NA} \ + CONFIG.PSU__TTC3__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__UART0_LOOP_UART1__ENABLE {0} \ + CONFIG.PSU__UART0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__UART1__BAUD_RATE {115200} \ + CONFIG.PSU__UART1__MODEM__ENABLE {0} \ + CONFIG.PSU__UART1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__UART1__PERIPHERAL__IO {MIO 36 .. 37} \ + CONFIG.PSU__USB0_COHERENCY {0} \ + CONFIG.PSU__USB0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB0__PERIPHERAL__IO {MIO 52 .. 63} \ + CONFIG.PSU__USB0__REF_CLK_FREQ {26} \ + CONFIG.PSU__USB0__REF_CLK_SEL {Ref Clk1} \ + CONFIG.PSU__USB1__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__USB2_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB3_0__PERIPHERAL__IO {GT Lane2} \ + CONFIG.PSU__USB__RESET__MODE {Boot Pin} \ + CONFIG.PSU__USB__RESET__POLARITY {Active Low} \ + CONFIG.PSU__USE_DIFF_RW_CLK_GP0 {0} \ + CONFIG.PSU__USE__ADMA {0} \ + CONFIG.PSU__USE__APU_LEGACY_INTERRUPT {0} \ + CONFIG.PSU__USE__AUDIO {0} \ + CONFIG.PSU__USE__CLK {0} \ + CONFIG.PSU__USE__CLK0 {0} \ + CONFIG.PSU__USE__CLK1 {0} \ + CONFIG.PSU__USE__CLK2 {0} \ + CONFIG.PSU__USE__CLK3 {0} \ + CONFIG.PSU__USE__CROSS_TRIGGER {0} \ + CONFIG.PSU__USE__DDR_INTF_REQUESTED {0} \ + CONFIG.PSU__USE__DEBUG__TEST {0} \ + CONFIG.PSU__USE__EVENT_RPU {0} \ + CONFIG.PSU__USE__FABRIC__RST {1} \ + CONFIG.PSU__USE__FTM {0} \ + CONFIG.PSU__USE__GDMA {0} \ + CONFIG.PSU__USE__IRQ {0} \ + CONFIG.PSU__USE__IRQ0 {1} \ + CONFIG.PSU__USE__IRQ1 {0} \ + CONFIG.PSU__USE__M_AXI_GP0 {0} \ + CONFIG.PSU__USE__M_AXI_GP1 {0} \ + CONFIG.PSU__USE__M_AXI_GP2 {1} \ + CONFIG.PSU__USE__PROC_EVENT_BUS {0} \ + CONFIG.PSU__USE__RPU_LEGACY_INTERRUPT {0} \ + CONFIG.PSU__USE__RST0 {0} \ + CONFIG.PSU__USE__RST1 {0} \ + CONFIG.PSU__USE__RST2 {0} \ + CONFIG.PSU__USE__RST3 {0} \ + CONFIG.PSU__USE__RTC {0} \ + CONFIG.PSU__USE__STM {0} \ + CONFIG.PSU__USE__S_AXI_ACE {0} \ + CONFIG.PSU__USE__S_AXI_ACP {0} \ + CONFIG.PSU__USE__S_AXI_GP0 {1} \ + CONFIG.PSU__USE__S_AXI_GP1 {0} \ + CONFIG.PSU__USE__S_AXI_GP2 {0} \ + CONFIG.PSU__USE__S_AXI_GP3 {0} \ + CONFIG.PSU__USE__S_AXI_GP4 {0} \ + CONFIG.PSU__USE__S_AXI_GP5 {0} \ + CONFIG.PSU__USE__S_AXI_GP6 {0} \ + CONFIG.PSU__USE__USB3_0_HUB {0} \ + CONFIG.PSU__USE__USB3_1_HUB {0} \ + CONFIG.PSU__USE__VIDEO {0} \ + CONFIG.PSU__VIDEO_REF_CLK__ENABLE {0} \ + CONFIG.PSU__VIDEO_REF_CLK__FREQMHZ {33.333} \ + CONFIG.QSPI_BOARD_INTERFACE {custom} \ + CONFIG.SATA_BOARD_INTERFACE {custom} \ + CONFIG.SD0_BOARD_INTERFACE {custom} \ + CONFIG.SD1_BOARD_INTERFACE {custom} \ + CONFIG.SPI0_BOARD_INTERFACE {custom} \ + CONFIG.SPI1_BOARD_INTERFACE {custom} \ + CONFIG.SUBPRESET1 {Custom} \ + CONFIG.SUBPRESET2 {Custom} \ + CONFIG.SWDT0_BOARD_INTERFACE {custom} \ + CONFIG.SWDT1_BOARD_INTERFACE {custom} \ + CONFIG.TRACE_BOARD_INTERFACE {custom} \ + CONFIG.TTC0_BOARD_INTERFACE {custom} \ + CONFIG.TTC1_BOARD_INTERFACE {custom} \ + CONFIG.TTC2_BOARD_INTERFACE {custom} \ + CONFIG.TTC3_BOARD_INTERFACE {custom} \ + CONFIG.UART0_BOARD_INTERFACE {custom} \ + CONFIG.UART1_BOARD_INTERFACE {custom} \ + CONFIG.USB0_BOARD_INTERFACE {custom} \ + CONFIG.USB1_BOARD_INTERFACE {custom} \ + ] $zynq_ultra_ps_e_0 + + + # Create instance: customIntr_0, and set properties + set customIntr_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 customIntr_0 ] + + # Create interface connections + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] [get_bd_intf_pins axi_smc/S00_AXI] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] [get_bd_intf_pins axi_smc/S01_AXI] + connect_bd_intf_net -intf_net axi_interconnect_0_M00_AXI [get_bd_intf_pins axi_intc_0/s_axi] [get_bd_intf_pins axi_interconnect_0/M00_AXI] + connect_bd_intf_net -intf_net axi_interconnect_0_M01_AXI [get_bd_intf_pins axi_interconnect_0/M01_AXI] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + connect_bd_intf_net -intf_net axi_smc_M00_AXI [get_bd_intf_pins axi_smc/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] + connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM0_LPD [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM0_LPD] [get_bd_intf_pins axi_interconnect_0/S00_AXI] + + # Create port connections + connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins customIntr_0/In0] + connect_bd_net -net axi_intc_0_irq [get_bd_pins axi_intc_0/irq] [get_bd_pins zynq_ultra_ps_e_0/pl_ps_irq0] + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins rst_ps8_0_99M/peripheral_aresetn] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_interconnect_0/ARESETN] [get_bd_pins axi_interconnect_0/S00_ARESETN] [get_bd_pins axi_interconnect_0/M00_ARESETN] [get_bd_pins axi_dma_0/axi_resetn] [get_bd_pins axi_interconnect_0/M01_ARESETN] [get_bd_pins axi_smc/aresetn] + connect_bd_net -net xlconcat_0_dout [get_bd_pins customIntr_0/dout] [get_bd_pins axi_intc_0/intr] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins zynq_ultra_ps_e_0/pl_clk0] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins rst_ps8_0_99M/slowest_sync_clk] [get_bd_pins axi_interconnect_0/ACLK] [get_bd_pins axi_interconnect_0/S00_ACLK] [get_bd_pins axi_interconnect_0/M00_ACLK] [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_lpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc0_fpd_aclk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] [get_bd_pins axi_interconnect_0/M01_ACLK] [get_bd_pins axi_smc/aclk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] + connect_bd_net -net zynq_ultra_ps_e_0_pl_resetn0 [get_bd_pins zynq_ultra_ps_e_0/pl_resetn0] [get_bd_pins rst_ps8_0_99M/ext_reset_in] + + # Create address segments + assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force + assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force + assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force + assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force + assign_bd_address -offset 0x80000000 -range 0x00010000 -target_address_space [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs axi_dma_0/S_AXI_LITE/Reg] -force + assign_bd_address -offset 0x80010000 -range 0x00010000 -target_address_space [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs axi_intc_0/S_AXI/Reg] -force + + # Exclude Address Segments + exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] + exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] + exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] + exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] + + + # Restore current instance + current_bd_instance $oldCurInst + + # Create PFM attributes + set_property PFM_NAME {vendor:kv260_som_som240_1_connector_kv260_carrier_som240_1_connector:kv260pf:0.0} [get_files [current_bd_design].bd] + set_property PFM.AXIS_PORT {M_AXIS_MM2S {type "M_AXIS" sptag "DMA_MM2S" is_range "false"} S_AXIS_S2MM {type "S_AXIS" sptag "DMA_S2MM" is_range "false"}} [get_bd_cells /axi_dma_0] + set_property PFM.AXI_PORT {M02_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } M03_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } M04_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } M05_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } M06_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } M07_AXI { memport "M_AXI_GP" sptag "" memory "" is_range "false" } } [get_bd_cells /axi_interconnect_0] + set_property PFM.AXI_PORT {M_AXI_HPM0_FPD { memport "M_AXI_GP" sptag "HPM0" memory "" is_range "false" } M_AXI_HPM1_FPD { memport "M_AXI_GP" sptag "HPM1" memory "" is_range "false" } S_AXI_HP0_FPD { memport "S_AXI_HP" sptag "HP0" memory "" is_range "false" } S_AXI_HP1_FPD { memport "S_AXI_HP" sptag "HP1" memory "" is_range "false" } S_AXI_HP2_FPD { memport "S_AXI_HP" sptag "HP2" memory "" is_range "false" } S_AXI_HP3_FPD { memport "S_AXI_HP" sptag "HP3" memory "" is_range "false" } S_AXI_HPC1_FPD { memport "S_AXI_HPC" sptag "HPC1" memory "" is_range "false" } } [get_bd_cells /zynq_ultra_ps_e_0] + set_property PFM.CLOCK {pl_clk0 {id "0" is_default "true" proc_sys_reset "/rst_ps8_0_99M" status "fixed" freq_hz "99999001"}} [get_bd_cells /zynq_ultra_ps_e_0] + set_property PFM.IRQ {In1 {is_range "true"}} [get_bd_cells /customIntr_0] + + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + +common::send_gid_msg -ssname BD::TCL -id 2053 -severity "WARNING" "This Tcl script was generated from a block design that has not been validated. It is possible that design <$design_name> may result in errors during validation." diff --git a/hls4ml/templates/vitis_unified/myproject_axi_master.cpp b/hls4ml/templates/vitis_unified/myproject_axi_master.cpp new file mode 100644 index 0000000000..775ba6cbbf --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi_master.cpp @@ -0,0 +1,66 @@ +#include "MY_PROJECT_DM_INC.h" +#include +#include +#include + +#define STREAM_BUF_IN_SZ VAL +#define STREAM_BUF_OUT_SZ VAL + +template +void load_input(ATOMIC_TYPE *in, hls::stream &inStream, int batch_size, const int TENSOR_SIZE) { +mem_rd: + int baseQuery = 0; + for (int q = 0; q < batch_size; q++) { + for (int i = 0; i < TENSOR_SIZE / INPUT_LAYER_ARR::size; i++) { + INPUT_LAYER_ARR tmp; + for (int j = 0; j < INPUT_LAYER_ARR::size; j++) { + tmp[j] = in[baseQuery]; + baseQuery++; + } + inStream.write(tmp); + } + } +} + +template +void store_result(ATOMIC_TYPE *out, hls::stream &out_stream, int batch_size, const int TENSOR_SIZE) { +mem_wr: + int baseQuery = 0; + for (int q = 0; q < batch_size; q++) { + for (int i = 0; i < TENSOR_SIZE / OUT_LAYER_ARR::size; i++) { + OUT_LAYER_ARR tmp = out_stream.read(); + for (int j = 0; j < OUT_LAYER_ARR::size; j++) { + out[baseQuery] = tmp[j]; + baseQuery++; + } + } + } +} + +// vitis-unified-wrapper-compute-func +void compute(// vitis-unified-wrapper-compute-signature) { + for (int q = 0; q < batch_size; q++) { + // vitis-unified-wrapper-compute-body + } +} + +void MY_PROJECT_TOP_FUNC( + // vitis-unified-wrapper-io + , int batch_size + +) { + + // vitis-unified-wrapper-interface + + // vitis-unified-wrapper-stream-dec + + // vitis-unified-wrapper-stream-config + + #pragma HLS dataflow + + // vitis-unified-wrapper-load + + compute(// vitis-unified-wrapper-compute-call-args); + + // vitis-unified-wrapper-store +} diff --git a/hls4ml/templates/vitis_unified/myproject_axi_master.h b/hls4ml/templates/vitis_unified/myproject_axi_master.h new file mode 100644 index 0000000000..2fd5bacf3c --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi_master.h @@ -0,0 +1,13 @@ +#ifndef FILENAME_H +#define FILENAME_H + +#include + +#include "MY_PROJECT_INC.h" + +void MY_PROJECT_TOP_FUNC( + + // vitis-unified-wrapper-io + , int batch_size); + +#endif diff --git a/hls4ml/templates/vitis_unified/myproject_axi_stream.cpp b/hls4ml/templates/vitis_unified/myproject_axi_stream.cpp new file mode 100644 index 0000000000..40251cf2a1 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi_stream.cpp @@ -0,0 +1,57 @@ +// hls-fpga-machine-learning insert include + +void load_input(hls::stream &axi_input_stream, hls::stream &model_input_stream, + int batch_size) { +load_input_loop: + // send the data to the stream + for (int q = 0; q < batch_size; q++) { + for (unsigned chunk_idx = 0; chunk_idx < N_IN / INPUT_LAYER_TYPE::size; ++chunk_idx) { + INPUT_LAYER_TYPE input_chunk; + for (unsigned elem_idx = 0; elem_idx < INPUT_LAYER_TYPE::size; elem_idx++) { + dma_data_packet axi_packet; + axi_input_stream.read(axi_packet); + input_chunk[elem_idx] = axi_packet.data; + } + model_input_stream.write(input_chunk); + } + } +} + +void store_result(hls::stream &model_output_stream, hls::stream &axi_output_stream, + int batch_size) { +store_result_loop: + // send back the data + for (int q = 0; q < batch_size; q++) { + for (unsigned chunk_idx = 0; chunk_idx < N_OUT / OUTPUT_LAYER_TYPE::size; ++chunk_idx) { + OUTPUT_LAYER_TYPE output_chunk = model_output_stream.read(); + for (unsigned elem_idx = 0; elem_idx < OUTPUT_LAYER_TYPE::size; elem_idx++) { + dma_data_packet axi_packet; + axi_packet.keep = -1; + axi_packet.data = (OUTPUT_GMEM_TYPE)(output_chunk[elem_idx]); + axi_packet.last = (q == (batch_size - 1)) && (((chunk_idx + 1) * (elem_idx + 1)) == N_OUT); + axi_output_stream.write(axi_packet); + } + } + } +} + +void compute( // hls-fpga-machine-learning insert stream parameter, + int batch_size) { + for (int q = 0; q < batch_size; q++) { + MY_PROJECT(model_input_stream, model_output_stream); + } +} + +void MY_PROJECT_TOP_FUNC(hls::stream &axi_input_stream, hls::stream &axi_output_stream, + int batch_size) { + + // hls-fpga-machine-learning insert interface + + // hls-fpga-machine-learning insert stream decl + + #pragma HLS DATAFLOW + + load_input(axi_input_stream, model_input_stream, batch_size); + compute(model_input_stream, model_output_stream, batch_size); + store_result(model_output_stream, axi_output_stream, batch_size); +} diff --git a/hls4ml/templates/vitis_unified/myproject_axi_stream.h b/hls4ml/templates/vitis_unified/myproject_axi_stream.h new file mode 100644 index 0000000000..c5be95f208 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi_stream.h @@ -0,0 +1,11 @@ +#ifndef MYPROJECT_AXI_H_ +#define MYPROJECT_AXI_H_ + +#include +// hls-fpga-machine-learning insert include + +// hls-fpga-machine-learning insert definitions + +void MY_PROJECT_TOP_FUNC(hls::stream &axi_input_stream, hls::stream &axi_output_stream, + int batch_size); +#endif diff --git a/hls4ml/templates/vitis_unified/myproject_bridge.cpp b/hls4ml/templates/vitis_unified/myproject_bridge.cpp new file mode 100644 index 0000000000..9a56f10d99 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_bridge.cpp @@ -0,0 +1,71 @@ +#ifndef MYPROJECT_BRIDGE_H_ +#define MYPROJECT_BRIDGE_H_ + +#include "firmware/PROJECT_FILE_NAME.h" +#include "firmware/nnet_utils/nnet_helpers.h" +#include +#include + +// hls-fpga-machine-learning insert bram + +namespace nnet { +bool trace_enabled = false; +std::map *trace_outputs = NULL; +size_t trace_type_size = sizeof(double); +} // namespace nnet + +extern "C" { + +struct trace_data { + const char *name; + void *data; +}; + +void allocate_trace_storage(size_t element_size) { + nnet::trace_enabled = true; + nnet::trace_outputs = new std::map; + nnet::trace_type_size = element_size; + // hls-fpga-machine-learning insert trace_outputs +} + +void free_trace_storage() { + for (std::map::iterator i = nnet::trace_outputs->begin(); i != nnet::trace_outputs->end(); i++) { + void *ptr = i->second; + free(ptr); + } + nnet::trace_outputs->clear(); + delete nnet::trace_outputs; + nnet::trace_outputs = NULL; + nnet::trace_enabled = false; +} + +void collect_trace_output(struct trace_data *c_trace_outputs) { + int ii = 0; + for (std::map::iterator i = nnet::trace_outputs->begin(); i != nnet::trace_outputs->end(); i++) { + c_trace_outputs[ii].name = i->first.c_str(); + c_trace_outputs[ii].data = i->second; + ii++; + } +} + +// hls-fpga-machine-learning insert tb_input_writer + +// Wrapper of top level function for Python bridge +void myproject_float( + // hls-fpga-machine-learning insert header #float +) { + // hls-fpga-machine-learning insert namespace + + // hls-fpga-machine-learning insert wrapper #float +} + +void myproject_double( + // hls-fpga-machine-learning insert header #double +) { + // hls-fpga-machine-learning insert namespace + + // hls-fpga-machine-learning insert wrapper #double +} +} + +#endif diff --git a/hls4ml/templates/vitis_unified/myproject_test.cpp b/hls4ml/templates/vitis_unified/myproject_test.cpp new file mode 100644 index 0000000000..a8d031e304 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_test.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// hls-fpga-machine-learning insert include + +#include "firmware/nnet_utils/nnet_helpers.h" + +// hls-fpga-machine-learning insert bram + +#define CHECKPOINT 5000 + +namespace nnet { +bool trace_enabled = true; +std::map *trace_outputs = NULL; +size_t trace_type_size = sizeof(double); +} // namespace nnet + +int main(int argc, char **argv) { + // hls-fpga-machine-learning insert namespace + + // load input data from text file + std::ifstream fin("tb_data/tb_input_features.dat"); + // load predictions from text file + std::ifstream fpr("tb_data/tb_output_predictions.dat"); + +#ifdef RTL_SIM + std::string RESULTS_LOG = "tb_data/rtl_cosim_results.log"; +#else + std::string RESULTS_LOG = "tb_data/csim_results.log"; +#endif + std::ofstream fout(RESULTS_LOG); + + std::string iline; + std::string pline; + int e = 0; + + if (fin.is_open() && fpr.is_open()) { + while (std::getline(fin, iline) && std::getline(fpr, pline)) { + if (e % CHECKPOINT == 0) + std::cout << "Processing input " << e << std::endl; + char *cstr = const_cast(iline.c_str()); + char *current; + std::vector in; + current = strtok(cstr, " "); + while (current != NULL) { + in.push_back(atof(current)); + current = strtok(NULL, " "); + } + cstr = const_cast(pline.c_str()); + std::vector pr; + current = strtok(cstr, " "); + while (current != NULL) { + pr.push_back(atof(current)); + current = strtok(NULL, " "); + } + + // hls-fpga-machine-learning insert data + + // hls-fpga-machine-learning insert top-level-function + + if (e % CHECKPOINT == 0) { + std::cout << "Predictions" << std::endl; + // hls-fpga-machine-learning insert predictions + std::cout << "Quantized predictions" << std::endl; + // hls-fpga-machine-learning insert quantized + } + e++; + + // hls-fpga-machine-learning insert tb-output + } + fin.close(); + fpr.close(); + } else { + std::cout << "INFO: Unable to open input/predictions file, using default input." << std::endl; + const unsigned NUM_TEST_SAMPLES = 5; + for (unsigned i = 0; i < NUM_TEST_SAMPLES; i++) { + // hls-fpga-machine-learning insert zero + + // hls-fpga-machine-learning insert top-level-function + + // hls-fpga-machine-learning insert output + + // hls-fpga-machine-learning insert tb-output + } + } + + fout.close(); + std::cout << "INFO: Saved inference results to file: " << RESULTS_LOG << std::endl; + + return 0; +} diff --git a/hls4ml/templates/vitis_unified/vitis_workspace/kernel_project/vitis-comp.json b/hls4ml/templates/vitis_unified/vitis_workspace/kernel_project/vitis-comp.json new file mode 100644 index 0000000000..02c6e626ca --- /dev/null +++ b/hls4ml/templates/vitis_unified/vitis_workspace/kernel_project/vitis-comp.json @@ -0,0 +1,9 @@ +{ + "name": "{HLS_NAME}", + "type": "HLS", + "configuration": { + "componentType": "HLS", + "configFiles": ["{CONFIG_FILE}"], + "work_dir": "vitis_unified_project" + } +} diff --git a/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.cfg b/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.cfg new file mode 100644 index 0000000000..37d5785ff7 --- /dev/null +++ b/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.cfg @@ -0,0 +1,2 @@ + +# hls-fpga-machine-learning insert custom connection diff --git a/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.sh b/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.sh new file mode 100644 index 0000000000..e7b1665b84 --- /dev/null +++ b/hls4ml/templates/vitis_unified/vitis_workspace/system_link/link_system.sh @@ -0,0 +1,14 @@ +# Generate XSA from TCL if platform source is a generator script +{XSA_GENERATOR_BLOCK} + +v++ -l -t hw --platform {PLATFORM_PATH} {KERNEL_XO} --config link_system.cfg -o {PROJECT_NAME}.xclbin --save-temps +[ -f ../../export/system.bit ] && rm -f ../../export/system.bit +[ -f ../../export/system.hwh ] && rm -f ../../export/system.hwh + +xclbinutil --dump-section BITSTREAM:RAW:../../export/system.bit --input {PROJECT_NAME}.xclbin +cp _x/link/vivado/vpl/prj/prj.gen/sources_1/bd/vitis_design/hw_handoff/vitis_design.hwh ../../export/system.hwh + +# Copy final reports (timing, clock, resource usage) to final_reports +mkdir -p ../../final_reports +[ -d _x/reports/link/imp ] && cp -p _x/reports/link/imp/*.rpt ../../final_reports/ 2>/dev/null || true +[ -f {PROJECT_NAME}.xclbin.link_summary ] && cp -p {PROJECT_NAME}.xclbin.link_summary ../../final_reports/ 2>/dev/null || true diff --git a/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_master_driver.py.hls4ml b/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_master_driver.py.hls4ml new file mode 100644 index 0000000000..bf18e7cd10 --- /dev/null +++ b/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_master_driver.py.hls4ml @@ -0,0 +1,213 @@ +from datetime import datetime + +# import the library +from pynq import Overlay # import the overlay +from pynq import allocate # import for CMA (contingeous memory allocation) +from pynq import DefaultIP # import the ip connector library for extension +from pynq import Interrupt +from pynq import PL + +import asyncio +import numpy as np +import os +import subprocess +import re +import time + +class NeuralNetworkOverlay(Overlay): + def __init__( + self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, device=None + ): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def calculate_performance(self, N, execution_time): + rate = N / execution_time if execution_time > 0 else float('inf') + print( + f"Processed elements: {N}, Execution time: {execution_time:.4f} seconds, Performance rate: {rate:.2f} inferences/second") + return rate + + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + + # reset the PL + PL.reset() + # set interrupt controller + my_interrupt = Interrupt("/interrupt") + ip = self. + + if encode is not None: + X = encode(X) + np.copyto(self.input_buffer, X) + exec_time = ip.transfer(self.input_buffer, self.output_buffer, my_interrupt, profile) + # exec_time will valid only when the profile is enabled + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + performance = self.calculate_performance(len(X), exec_time) + return self.output_buffer, exec_time, performance + return self.output_buffer + +class HLS4ML_IP(DefaultIP): + def __init__(self, description): + super().__init__(description=description) + + self.REG_ADDR_AP_CTRL = 0x00 + self.REG_ADDR_BATCH_SIZE = VAL + + self.REG_ADDR_GIE = 0x04 + self.REG_ADDR_IER = 0x08 + self.REG_ADDR_ISR = 0x0C + + self.INP_PORT_NAMEs = [ + # hls-driver-input-dbg-name + ] + + self.REG_ADDR_INP_PTRs = [ + # hls-driver-input-ptr + ] + + self.OUT_PORT_NAMEs = [ + # hls-driver-output-dbg-name + ] + + self.REG_ADDR_OUT_PTRs = [ + # hls-driver-output-ptr + ] + + bindto = ['xilinx.com:hls::1.0'] + + def enable_gie(self): + print("global interrupt enable register") + self.write(self.REG_ADDR_GIE, 0x01) + print("enable gie successful") + + def disable_gie(self): + print("global interrupt enable register") + self.write(self.REG_ADDR_GIE, 0x01) + print("disable gie successful") + + def enable_done_intr(self): + print("ap_done interrupt enable register") + self.write(self.REG_ADDR_IER, 0x01) + print("enable ap_done interrupt successful") + + def clear_done_status(self): + print("ap_done register clear") + self.write(self.REG_ADDR_ISR, 0x01) + print("clear ap_done interrupt successful") + + def set_single_bit(self, addr, idx): + self.write(addr, 1 << idx) + + def ctrl_start(self): + self.write(0x00, 0x01) # ap_start = 1 + + def wait_until_done(self): + while (self.read(0x00) & 0x2) == 0: # Wait for ap_done + time.sleep(0.001) + + def set_input(self, idx, buffer): + + print( + f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {hex(buffer.physical_address)} with elements: {buffer.size}" + ) + self.write(self.REG_ADDR_INP_PTRs[idx], buffer.physical_address) + self.write(self.REG_ADDR_INP_PTRs[idx] + 4, 0) + buffer.flush() + + def set_output(self, idx, buffer): + + print( + f"output {self.OUT_PORT_NAMEs[idx]} will be set to addr: {hex(buffer.physical_address)} with elements: {buffer.size}" + ) + self.write(self.REG_ADDR_OUT_PTRs[idx], buffer.physical_address) + self.write(self.REG_ADDR_OUT_PTRs[idx] + 4, 0) + + def set_amt_query(self, val): + print(f"amount of queries will be set to: {val} at address: {hex(self.REG_ADDR_BATCH_SIZE)}") + self.write(self.REG_ADDR_BATCH_SIZE, val) + + def prepare_intr(self): + print("prepare your interrupt") + self.enable_gie() + self.enable_done_intr() + self.clear_done_status() + print("----------------------") + + def build_event_and_run(self, intr, profile): + + async def wait_for_acc(): + exec_time = 0 + print("starting the accelerator") + if profile: + t_start = time.perf_counter() + + # Start receive (PL → PS) + # Start send (PS → PL) + self.ctrl_start() + + # Wait for complete + await intr.wait() + + # print porfile data + if profile: + t_end = time.perf_counter() + exec_time = t_end - t_start + print(f"Accelerator execution time: \ + {(exec_time) * 1e3:.3f} ms") + + print("accelerator has finished") + + return exec_time if profile else None + + # get event loop from asyncio + loop = asyncio.get_event_loop() + # build task + task = loop.create_task(wait_for_acc()) + # run and return whatever inside the wait_for_acc return + return loop.run_until_complete(task) + + def transfer(self, input_buffer, output_buffer, intr, profile = True): + + # flush the buffer first + input_buffer.flush() + # prepare the data + self.set_input(0, input_buffer) + self.set_output(0, output_buffer) + self.set_amt_query(input_buffer.shape[0]) + self.prepare_intr() + # run and get the profile data + exec_time = self.build_event_and_run(intr, profile) + # invalidate the output buffer + output_buffer.invalidate() + # it will return 0 if the profile is not enable + return exec_time diff --git a/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_stream_driver.py.hls4ml b/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_stream_driver.py.hls4ml new file mode 100644 index 0000000000..a0a32187d2 --- /dev/null +++ b/hls4ml/templates/vitis_unified/zcu102/python_drivers/axi_stream_driver.py.hls4ml @@ -0,0 +1,145 @@ +from datetime import datetime + +# import the library +from pynq import Overlay # import the overlay +from pynq import allocate # import for CMA (contingeous memory allocation) +from pynq import DefaultIP # import the ip connector library for extension +from pynq import Interrupt +from pynq import PL + +import asyncio +import numpy as np +import os +import subprocess +import re +import time + + +class NeuralNetworkOverlay(Overlay): + def __init__( + self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, device=None + ): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def calculate_performance(self, N, execution_time): + rate = N / execution_time if execution_time > 0 else float('inf') + print( + f"Processed elements: {N}, Execution time: {execution_time:.4f} seconds, Performance rate: {rate:.2f} inferences/second") + return rate + + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + + PL.reset() + my_interrupt = Interrupt("axi_dma_0/s2mm_introut") + + dma = self.axi_dma_0 + ip = self. + ip.assign_dma(dma) + + + if encode is not None: + X = encode(X) + np.copyto(self.input_buffer, X) + exec_time = ip.transfer(self.input_buffer, self.output_buffer, my_interrupt, profile) + # exec_time will valid only when the profile is enabled + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + performance = self.calculate_performance(len(X), exec_time) + return self.output_buffer, exec_time, performance + return self.output_buffer + +class HLS4ML_IP(DefaultIP): + + def __init__(self, description): + super().__init__(description) + self.dma = None + self.REG_ADDR_BATCH_SIZE = 0x10 + + bindto = ['xilinx.com:hls::1.0'] + + def assign_dma(self, dma): + self.dma = dma + + def set_amt_query(self, val): + print(f"amount of queries will be set to: {val} at address: {hex(self.REG_ADDR_BATCH_SIZE)}") + self.write(self.REG_ADDR_BATCH_SIZE, val) + + def ctrl_start(self): + # auto_restart + ap_start + self.write(0x00, 1 << 0) + + def transfer(self, input_buffer, output_buffer, intr, profile = True): + + # check availability of dma + assert self.dma is not None, "dma is not assigned" + # flush the buffer first + input_buffer.flush() + # initialize the batch tracker and ip control + self.set_amt_query(input_buffer.shape[0]) + self.ctrl_start() + + async def wait_for_acc(): + exec_time = 0 + print("starting the accelerator") + # Start receive (PL → PS) + if profile: + t_start = time.perf_counter() + self.dma.recvchannel.transfer(output_buffer) + + # Start send (PS → PL) + self.dma.sendchannel.transfer(input_buffer) + + # Wait for complete + await intr.wait() + + # print porfile data + if profile: + t_end = time.perf_counter() + exec_time = t_end - t_start + print(f"Accelerator execution time: \ + {(t_end - t_start) * 1e3:.3f} ms") + + + print("accelerator has finished") + return exec_time if profile else None + + # get event loop from asyncio + loop = asyncio.get_event_loop() + task = loop.create_task(wait_for_acc()) + # loop until end + exec_time = loop.run_until_complete(task) + # invalidate the output buffer + output_buffer.invalidate() + # it will return 0 if the profile is not enable + return exec_time diff --git a/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/create_xsa.tcl b/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/create_xsa.tcl new file mode 100644 index 0000000000..cfd611b0e7 --- /dev/null +++ b/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/create_xsa.tcl @@ -0,0 +1,67 @@ +################################################################ +# create_xsa.tcl +# +# Sources zcu102_axi_stream_platform.tcl to build the block design, then creates +# the HDL wrapper and exports the XSA hardware description file. +# +# Usage: +# cd +# vivado -mode batch -source create_xsa.tcl +# +# Output: +# output/zcu102_axi_stream_platform.xsa +# +# Requirements: +# Vivado 2023.2 with ZCU102 board files installed +# +# Note: For a clean run, remove the myproj/ directory first if it +# exists from a previous run. +################################################################ + +set script_dir [file dirname [file normalize [info script]]] +set output_dir [file join $script_dir "output"] +set xsa_path [file join $output_dir "zcu102_axi_stream_platform.xsa"] + +file mkdir $output_dir + +# Change to script directory so zcu102_axi_stream_platform.tcl is found +cd $script_dir + +# ---------------------------------------------------------------- +# Build block design (creates project + BD via zcu102_axi_stream_platform.tcl) +# ---------------------------------------------------------------- +source [file join $script_dir "zcu102_axi_stream_platform.tcl"] + +# ---------------------------------------------------------------- +# Create HDL wrapper +# ---------------------------------------------------------------- +set bd_file [get_files -norecurse "vitis_design.bd"] +make_wrapper -files $bd_file -top + +# make_wrapper creates {bd_base_name}_wrapper.v for vitis_design.bd +set wrapper_name "vitis_design_wrapper" +set proj_dir [get_property directory [current_project]] +add_files -norecurse [file join $proj_dir "project_1.gen" "sources_1" "bd" "vitis_design" "hdl" "${wrapper_name}.v"] +set_property top $wrapper_name [current_fileset] +update_compile_order -fileset sources_1 + +# ---------------------------------------------------------------- +# Generate block design outputs (required before write_hw_platform) +# ---------------------------------------------------------------- +generate_target all [get_files vitis_design.bd] + +# ---------------------------------------------------------------- +# Platform design intent (required for v++ accelerated platform) +# ---------------------------------------------------------------- +set_property platform.default_output_type "sd_card" [current_project] +set_property platform.design_intent.embedded "true" [current_project] +set_property platform.design_intent.server_managed "false" [current_project] +set_property platform.design_intent.external_host "false" [current_project] +set_property platform.design_intent.datacenter "false" [current_project] + +# ---------------------------------------------------------------- +# Export XSA as extensible pre-synthesis platform (for v++ link) +# ---------------------------------------------------------------- +write_hw_platform -hw -force -file $xsa_path + +puts "INFO: XSA written to $xsa_path" diff --git a/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/zcu102_axi_stream_platform.tcl b/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/zcu102_axi_stream_platform.tcl new file mode 100644 index 0000000000..967ed111dd --- /dev/null +++ b/hls4ml/templates/vitis_unified/zcu102/tcl_scripts/zcu102_axi_stream_platform.tcl @@ -0,0 +1,665 @@ + +################################################################ +# This is a generated script based on design: vitis_design +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2023.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + if { [string compare $scripts_vivado_version $current_vivado_version] > 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2042 -severity "ERROR" " This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Sourcing the script failed since it was created with a future version of Vivado."} + + } else { + catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + } + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source vitis_design_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xczu9eg-ffvb1156-2-e + set_property BOARD_PART xilinx.com:zcu102:part0:3.4 [current_project] +} +set_property platform.extensible true [current_project] + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name vitis_design + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:zynq_ultra_ps_e:3.5\ +xilinx.com:ip:axi_dma:7.1\ +xilinx.com:ip:axi_intc:4.1\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:smartconnect:1.0\ +xilinx.com:ip:xlconcat:2.1\ +" + + set list_ips_missing "" + common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + + # Create ports + + # Create instance: zynq_ultra_ps_e_0, and set properties + set zynq_ultra_ps_e_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.5 zynq_ultra_ps_e_0 ] + set_property -dict [list \ + CONFIG.PSU_BANK_0_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_1_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_2_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_3_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_DDR_RAM_HIGHADDR {0xFFFFFFFF} \ + CONFIG.PSU_DDR_RAM_HIGHADDR_OFFSET {0x800000000} \ + CONFIG.PSU_DDR_RAM_LOWADDR_OFFSET {0x80000000} \ + CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN {1} \ + CONFIG.PSU_MIO_13_POLARITY {Default} \ + CONFIG.PSU_MIO_22_POLARITY {Default} \ + CONFIG.PSU_MIO_23_POLARITY {Default} \ + CONFIG.PSU_MIO_26_POLARITY {Default} \ + CONFIG.PSU_MIO_38_POLARITY {Default} \ + CONFIG.PSU_MIO_43_POLARITY {Default} \ + CONFIG.PSU_MIO_TREE_PERIPHERALS {Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Feedback Clk#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad\ +SPI Flash#Quad SPI Flash#GPIO0 MIO#I2C 0#I2C 0#I2C 1#I2C 1#UART 0#UART 0#UART 1#UART 1#GPIO0 MIO#GPIO0 MIO#CAN 1#CAN 1#GPIO1 MIO#DPAUX#DPAUX#DPAUX#DPAUX#PCIE#PMU GPO 0#PMU GPO 1#PMU GPO 2#PMU GPO 3#PMU\ +GPO 4#PMU GPO 5#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem\ +3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#MDIO 3#MDIO 3} \ + CONFIG.PSU_MIO_TREE_SIGNALS {sclk_out#miso_mo1#mo2#mo3#mosi_mi0#n_ss_out#clk_for_lpbk#n_ss_out_upper#mo_upper[0]#mo_upper[1]#mo_upper[2]#mo_upper[3]#sclk_out_upper#gpio0[13]#scl_out#sda_out#scl_out#sda_out#rxd#txd#txd#rxd#gpio0[22]#gpio0[23]#phy_tx#phy_rx#gpio1[26]#dp_aux_data_out#dp_hot_plug_detect#dp_aux_data_oe#dp_aux_data_in#reset_n#gpo[0]#gpo[1]#gpo[2]#gpo[3]#gpo[4]#gpo[5]#gpio1[38]#sdio1_data_out[4]#sdio1_data_out[5]#sdio1_data_out[6]#sdio1_data_out[7]#gpio1[43]#sdio1_wp#sdio1_cd_n#sdio1_data_out[0]#sdio1_data_out[1]#sdio1_data_out[2]#sdio1_data_out[3]#sdio1_cmd_out#sdio1_clk_out#ulpi_clk_in#ulpi_dir#ulpi_tx_data[2]#ulpi_nxt#ulpi_tx_data[0]#ulpi_tx_data[1]#ulpi_stp#ulpi_tx_data[3]#ulpi_tx_data[4]#ulpi_tx_data[5]#ulpi_tx_data[6]#ulpi_tx_data[7]#rgmii_tx_clk#rgmii_txd[0]#rgmii_txd[1]#rgmii_txd[2]#rgmii_txd[3]#rgmii_tx_ctl#rgmii_rx_clk#rgmii_rxd[0]#rgmii_rxd[1]#rgmii_rxd[2]#rgmii_rxd[3]#rgmii_rx_ctl#gem3_mdc#gem3_mdio_out}\ +\ + CONFIG.PSU_SD1_INTERNAL_BUS_WIDTH {8} \ + CONFIG.PSU_USB3__DUAL_CLOCK_ENABLE {1} \ + CONFIG.PSU__ACT_DDR_FREQ_MHZ {1066.560059} \ + CONFIG.PSU__AFI0_COHERENCY {0} \ + CONFIG.PSU__CAN1__GRP_CLK__ENABLE {0} \ + CONFIG.PSU__CAN1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__CAN1__PERIPHERAL__IO {MIO 24 .. 25} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__ACT_FREQMHZ {1199.880127} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__FREQMHZ {1200} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__ACT_FREQMHZ {533.280029} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__FREQMHZ {1067} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__ACT_FREQMHZ {599.940063} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__ACT_FREQMHZ {24.997501} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_AUDIO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__ACT_FREQMHZ {26.783037} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__ACT_FREQMHZ {299.970032} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__ACT_FREQMHZ {599.940063} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__ACT_FREQMHZ {533.280029} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__FREQMHZ {533.33} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__ACT_FREQMHZ {49.995003} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__ACT_FREQMHZ {1499.850098} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__ACT_FREQMHZ {124.987511} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__ACT_FREQMHZ {187.481262} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__ACT_FREQMHZ {124.987511} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__ACT_FREQMHZ {187.481262} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__ACT_FREQMHZ {19.998001} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__FREQMHZ {20} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3__ENABLE {1} \ + CONFIG.PSU__CSUPMU__PERIPHERAL__VALID {1} \ + CONFIG.PSU__DDRC__BG_ADDR_COUNT {2} \ + CONFIG.PSU__DDRC__BRC_MAPPING {ROW_BANK_COL} \ + CONFIG.PSU__DDRC__BUS_WIDTH {64 Bit} \ + CONFIG.PSU__DDRC__CL {15} \ + CONFIG.PSU__DDRC__CLOCK_STOP_EN {0} \ + CONFIG.PSU__DDRC__COMPONENTS {UDIMM} \ + CONFIG.PSU__DDRC__CWL {14} \ + CONFIG.PSU__DDRC__DDR4_ADDR_MAPPING {0} \ + CONFIG.PSU__DDRC__DDR4_CAL_MODE_ENABLE {0} \ + CONFIG.PSU__DDRC__DDR4_CRC_CONTROL {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_MODE {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_RANGE {Normal (0-85)} \ + CONFIG.PSU__DDRC__DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PSU__DDRC__DM_DBI {DM_NO_DBI} \ + CONFIG.PSU__DDRC__DRAM_WIDTH {8 Bits} \ + CONFIG.PSU__DDRC__ECC {Disabled} \ + CONFIG.PSU__DDRC__FGRM {1X} \ + CONFIG.PSU__DDRC__LP_ASR {manual normal} \ + CONFIG.PSU__DDRC__MEMORY_TYPE {DDR 4} \ + CONFIG.PSU__DDRC__PARITY_ENABLE {0} \ + CONFIG.PSU__DDRC__PER_BANK_REFRESH {0} \ + CONFIG.PSU__DDRC__PHY_DBI_MODE {0} \ + CONFIG.PSU__DDRC__RANK_ADDR_COUNT {0} \ + CONFIG.PSU__DDRC__ROW_ADDR_COUNT {15} \ + CONFIG.PSU__DDRC__SELF_REF_ABORT {0} \ + CONFIG.PSU__DDRC__SPEED_BIN {DDR4_2133P} \ + CONFIG.PSU__DDRC__STATIC_RD_MODE {0} \ + CONFIG.PSU__DDRC__TRAIN_DATA_EYE {1} \ + CONFIG.PSU__DDRC__TRAIN_READ_GATE {1} \ + CONFIG.PSU__DDRC__TRAIN_WRITE_LEVEL {1} \ + CONFIG.PSU__DDRC__T_FAW {30.0} \ + CONFIG.PSU__DDRC__T_RAS_MIN {33} \ + CONFIG.PSU__DDRC__T_RC {47.06} \ + CONFIG.PSU__DDRC__T_RCD {15} \ + CONFIG.PSU__DDRC__T_RP {15} \ + CONFIG.PSU__DDRC__VREF {1} \ + CONFIG.PSU__DDR_HIGH_ADDRESS_GUI_ENABLE {1} \ + CONFIG.PSU__DDR__INTERFACE__FREQMHZ {533.500} \ + CONFIG.PSU__DISPLAYPORT__LANE0__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE0__IO {GT Lane1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__ENABLE {0} \ + CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DLL__ISUSED {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \ + CONFIG.PSU__DP__LANE_SEL {Single Lower} \ + CONFIG.PSU__DP__REF_CLK_FREQ {27} \ + CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk3} \ + CONFIG.PSU__ENET3__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET3__GRP_MDIO__ENABLE {1} \ + CONFIG.PSU__ENET3__GRP_MDIO__IO {MIO 76 .. 77} \ + CONFIG.PSU__ENET3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__ENET3__PERIPHERAL__IO {MIO 64 .. 75} \ + CONFIG.PSU__ENET3__PTP__ENABLE {0} \ + CONFIG.PSU__ENET3__TSU__ENABLE {0} \ + CONFIG.PSU__FPDMASTERS_COHERENCY {0} \ + CONFIG.PSU__FPD_SLCR__WDT1__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__FPGA_PL0_ENABLE {1} \ + CONFIG.PSU__GEM3_COHERENCY {0} \ + CONFIG.PSU__GEM3_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM__TSU__ENABLE {0} \ + CONFIG.PSU__GPIO0_MIO__IO {MIO 0 .. 25} \ + CONFIG.PSU__GPIO0_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO1_MIO__IO {MIO 26 .. 51} \ + CONFIG.PSU__GPIO1_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GT__LINK_SPEED {HBR} \ + CONFIG.PSU__GT__PRE_EMPH_LVL_4 {0} \ + CONFIG.PSU__GT__VLT_SWNG_LVL_4 {0} \ + CONFIG.PSU__I2C0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__I2C0__PERIPHERAL__IO {MIO 14 .. 15} \ + CONFIG.PSU__I2C1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__I2C1__PERIPHERAL__IO {MIO 16 .. 17} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC0_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC1_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC2_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__IOU_TTC_APB_CLK__TTC3_SEL {APB} \ + CONFIG.PSU__IOU_SLCR__TTC0__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC1__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC2__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__TTC3__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__IOU_SLCR__WDT0__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__LPD_SLCR__CSUPMU__ACT_FREQMHZ {100.000000} \ + CONFIG.PSU__MAXIGP0__DATA_WIDTH {128} \ + CONFIG.PSU__OVERRIDE__BASIC_CLOCK {0} \ + CONFIG.PSU__PCIE__BAR0_ENABLE {0} \ + CONFIG.PSU__PCIE__BAR0_VAL {0x0} \ + CONFIG.PSU__PCIE__BAR1_ENABLE {0} \ + CONFIG.PSU__PCIE__BAR1_VAL {0x0} \ + CONFIG.PSU__PCIE__BAR2_VAL {0x0} \ + CONFIG.PSU__PCIE__BAR3_VAL {0x0} \ + CONFIG.PSU__PCIE__BAR4_VAL {0x0} \ + CONFIG.PSU__PCIE__BAR5_VAL {0x0} \ + CONFIG.PSU__PCIE__CLASS_CODE_BASE {0x06} \ + CONFIG.PSU__PCIE__CLASS_CODE_INTERFACE {0x0} \ + CONFIG.PSU__PCIE__CLASS_CODE_SUB {0x4} \ + CONFIG.PSU__PCIE__CLASS_CODE_VALUE {0x60400} \ + CONFIG.PSU__PCIE__CRS_SW_VISIBILITY {1} \ + CONFIG.PSU__PCIE__DEVICE_ID {0xD021} \ + CONFIG.PSU__PCIE__DEVICE_PORT_TYPE {Root Port} \ + CONFIG.PSU__PCIE__EROM_ENABLE {0} \ + CONFIG.PSU__PCIE__EROM_VAL {0x0} \ + CONFIG.PSU__PCIE__LANE0__ENABLE {1} \ + CONFIG.PSU__PCIE__LANE0__IO {GT Lane0} \ + CONFIG.PSU__PCIE__LANE1__ENABLE {0} \ + CONFIG.PSU__PCIE__LANE2__ENABLE {0} \ + CONFIG.PSU__PCIE__LANE3__ENABLE {0} \ + CONFIG.PSU__PCIE__LINK_SPEED {5.0 Gb/s} \ + CONFIG.PSU__PCIE__MAXIMUM_LINK_WIDTH {x1} \ + CONFIG.PSU__PCIE__MAX_PAYLOAD_SIZE {256 bytes} \ + CONFIG.PSU__PCIE__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__PCIE__PERIPHERAL__ENDPOINT_ENABLE {0} \ + CONFIG.PSU__PCIE__PERIPHERAL__ROOTPORT_ENABLE {1} \ + CONFIG.PSU__PCIE__PERIPHERAL__ROOTPORT_IO {MIO 31} \ + CONFIG.PSU__PCIE__REF_CLK_FREQ {100} \ + CONFIG.PSU__PCIE__REF_CLK_SEL {Ref Clk0} \ + CONFIG.PSU__PCIE__RESET__POLARITY {Active Low} \ + CONFIG.PSU__PCIE__REVISION_ID {0x0} \ + CONFIG.PSU__PCIE__SUBSYSTEM_ID {0x7} \ + CONFIG.PSU__PCIE__SUBSYSTEM_VENDOR_ID {0x10EE} \ + CONFIG.PSU__PCIE__VENDOR_ID {0x10EE} \ + CONFIG.PSU__PL_CLK0_BUF {TRUE} \ + CONFIG.PSU__PMU_COHERENCY {0} \ + CONFIG.PSU__PMU__AIBACK__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPI__ENABLE {0} \ + CONFIG.PSU__PMU__EMIO_GPO__ENABLE {0} \ + CONFIG.PSU__PMU__GPI0__ENABLE {0} \ + CONFIG.PSU__PMU__GPI1__ENABLE {0} \ + CONFIG.PSU__PMU__GPI2__ENABLE {0} \ + CONFIG.PSU__PMU__GPI3__ENABLE {0} \ + CONFIG.PSU__PMU__GPI4__ENABLE {0} \ + CONFIG.PSU__PMU__GPI5__ENABLE {0} \ + CONFIG.PSU__PMU__GPO0__ENABLE {1} \ + CONFIG.PSU__PMU__GPO0__IO {MIO 32} \ + CONFIG.PSU__PMU__GPO1__ENABLE {1} \ + CONFIG.PSU__PMU__GPO1__IO {MIO 33} \ + CONFIG.PSU__PMU__GPO2__ENABLE {1} \ + CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ + CONFIG.PSU__PMU__GPO2__POLARITY {high} \ + CONFIG.PSU__PMU__GPO3__ENABLE {1} \ + CONFIG.PSU__PMU__GPO3__IO {MIO 35} \ + CONFIG.PSU__PMU__GPO3__POLARITY {low} \ + CONFIG.PSU__PMU__GPO4__ENABLE {1} \ + CONFIG.PSU__PMU__GPO4__IO {MIO 36} \ + CONFIG.PSU__PMU__GPO4__POLARITY {low} \ + CONFIG.PSU__PMU__GPO5__ENABLE {1} \ + CONFIG.PSU__PMU__GPO5__IO {MIO 37} \ + CONFIG.PSU__PMU__GPO5__POLARITY {low} \ + CONFIG.PSU__PMU__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__PMU__PLERROR__ENABLE {0} \ + CONFIG.PSU__PRESET_APPLIED {1} \ + CONFIG.PSU__PROTECTION__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;0|S_AXI_HPC0_FPD:NA;1|S_AXI_HP3_FPD:NA;0|S_AXI_HP2_FPD:NA;0|S_AXI_HP1_FPD:NA;0|S_AXI_HP0_FPD:NA;0|S_AXI_ACP:NA;0|S_AXI_ACE:NA;0|SD1:NonSecure;1|SD0:NonSecure;0|SATA1:NonSecure;1|SATA0:NonSecure;1|RPU1:Secure;1|RPU0:Secure;1|QSPI:NonSecure;1|PMU:NA;1|PCIe:NonSecure;1|NAND:NonSecure;0|LDMA:NonSecure;1|GPU:NonSecure;1|GEM3:NonSecure;1|GEM2:NonSecure;0|GEM1:NonSecure;0|GEM0:NonSecure;0|FDMA:NonSecure;1|DP:NonSecure;1|DAP:NA;1|Coresight:NA;1|CSU:NA;1|APU:NA;1}\ +\ + CONFIG.PSU__PROTECTION__SLAVES {LPD;USB3_1_XHCI;FE300000;FE3FFFFF;0|LPD;USB3_1;FF9E0000;FF9EFFFF;0|LPD;USB3_0_XHCI;FE200000;FE2FFFFF;1|LPD;USB3_0;FF9D0000;FF9DFFFF;1|LPD;UART1;FF010000;FF01FFFF;1|LPD;UART0;FF000000;FF00FFFF;1|LPD;TTC3;FF140000;FF14FFFF;1|LPD;TTC2;FF130000;FF13FFFF;1|LPD;TTC1;FF120000;FF12FFFF;1|LPD;TTC0;FF110000;FF11FFFF;1|FPD;SWDT1;FD4D0000;FD4DFFFF;1|LPD;SWDT0;FF150000;FF15FFFF;1|LPD;SPI1;FF050000;FF05FFFF;0|LPD;SPI0;FF040000;FF04FFFF;0|FPD;SMMU_REG;FD5F0000;FD5FFFFF;1|FPD;SMMU;FD800000;FDFFFFFF;1|FPD;SIOU;FD3D0000;FD3DFFFF;1|FPD;SERDES;FD400000;FD47FFFF;1|LPD;SD1;FF170000;FF17FFFF;1|LPD;SD0;FF160000;FF16FFFF;0|FPD;SATA;FD0C0000;FD0CFFFF;1|LPD;RTC;FFA60000;FFA6FFFF;1|LPD;RSA_CORE;FFCE0000;FFCEFFFF;1|LPD;RPU;FF9A0000;FF9AFFFF;1|LPD;R5_TCM_RAM_GLOBAL;FFE00000;FFE3FFFF;1|LPD;R5_1_Instruction_Cache;FFEC0000;FFECFFFF;1|LPD;R5_1_Data_Cache;FFED0000;FFEDFFFF;1|LPD;R5_1_BTCM_GLOBAL;FFEB0000;FFEBFFFF;1|LPD;R5_1_ATCM_GLOBAL;FFE90000;FFE9FFFF;1|LPD;R5_0_Instruction_Cache;FFE40000;FFE4FFFF;1|LPD;R5_0_Data_Cache;FFE50000;FFE5FFFF;1|LPD;R5_0_BTCM_GLOBAL;FFE20000;FFE2FFFF;1|LPD;R5_0_ATCM_GLOBAL;FFE00000;FFE0FFFF;1|LPD;QSPI_Linear_Address;C0000000;DFFFFFFF;1|LPD;QSPI;FF0F0000;FF0FFFFF;1|LPD;PMU_RAM;FFDC0000;FFDDFFFF;1|LPD;PMU_GLOBAL;FFD80000;FFDBFFFF;1|FPD;PCIE_MAIN;FD0E0000;FD0EFFFF;1|FPD;PCIE_LOW;E0000000;EFFFFFFF;1|FPD;PCIE_HIGH2;8000000000;BFFFFFFFFF;1|FPD;PCIE_HIGH1;600000000;7FFFFFFFF;1|FPD;PCIE_DMA;FD0F0000;FD0FFFFF;1|FPD;PCIE_ATTRIB;FD480000;FD48FFFF;1|LPD;OCM_XMPU_CFG;FFA70000;FFA7FFFF;1|LPD;OCM_SLCR;FF960000;FF96FFFF;1|OCM;OCM;FFFC0000;FFFFFFFF;1|LPD;NAND;FF100000;FF10FFFF;0|LPD;MBISTJTAG;FFCF0000;FFCFFFFF;1|LPD;LPD_XPPU_SINK;FF9C0000;FF9CFFFF;1|LPD;LPD_XPPU;FF980000;FF98FFFF;1|LPD;LPD_SLCR_SECURE;FF4B0000;FF4DFFFF;1|LPD;LPD_SLCR;FF410000;FF4AFFFF;1|LPD;LPD_GPV;FE100000;FE1FFFFF;1|LPD;LPD_DMA_7;FFAF0000;FFAFFFFF;1|LPD;LPD_DMA_6;FFAE0000;FFAEFFFF;1|LPD;LPD_DMA_5;FFAD0000;FFADFFFF;1|LPD;LPD_DMA_4;FFAC0000;FFACFFFF;1|LPD;LPD_DMA_3;FFAB0000;FFABFFFF;1|LPD;LPD_DMA_2;FFAA0000;FFAAFFFF;1|LPD;LPD_DMA_1;FFA90000;FFA9FFFF;1|LPD;LPD_DMA_0;FFA80000;FFA8FFFF;1|LPD;IPI_CTRL;FF380000;FF3FFFFF;1|LPD;IOU_SLCR;FF180000;FF23FFFF;1|LPD;IOU_SECURE_SLCR;FF240000;FF24FFFF;1|LPD;IOU_SCNTRS;FF260000;FF26FFFF;1|LPD;IOU_SCNTR;FF250000;FF25FFFF;1|LPD;IOU_GPV;FE000000;FE0FFFFF;1|LPD;I2C1;FF030000;FF03FFFF;1|LPD;I2C0;FF020000;FF02FFFF;1|FPD;GPU;FD4B0000;FD4BFFFF;1|LPD;GPIO;FF0A0000;FF0AFFFF;1|LPD;GEM3;FF0E0000;FF0EFFFF;1|LPD;GEM2;FF0D0000;FF0DFFFF;0|LPD;GEM1;FF0C0000;FF0CFFFF;0|LPD;GEM0;FF0B0000;FF0BFFFF;0|FPD;FPD_XMPU_SINK;FD4F0000;FD4FFFFF;1|FPD;FPD_XMPU_CFG;FD5D0000;FD5DFFFF;1|FPD;FPD_SLCR_SECURE;FD690000;FD6CFFFF;1|FPD;FPD_SLCR;FD610000;FD68FFFF;1|FPD;FPD_DMA_CH7;FD570000;FD57FFFF;1|FPD;FPD_DMA_CH6;FD560000;FD56FFFF;1|FPD;FPD_DMA_CH5;FD550000;FD55FFFF;1|FPD;FPD_DMA_CH4;FD540000;FD54FFFF;1|FPD;FPD_DMA_CH3;FD530000;FD53FFFF;1|FPD;FPD_DMA_CH2;FD520000;FD52FFFF;1|FPD;FPD_DMA_CH1;FD510000;FD51FFFF;1|FPD;FPD_DMA_CH0;FD500000;FD50FFFF;1|LPD;EFUSE;FFCC0000;FFCCFFFF;1|FPD;Display\ +Port;FD4A0000;FD4AFFFF;1|FPD;DPDMA;FD4C0000;FD4CFFFF;1|FPD;DDR_XMPU5_CFG;FD050000;FD05FFFF;1|FPD;DDR_XMPU4_CFG;FD040000;FD04FFFF;1|FPD;DDR_XMPU3_CFG;FD030000;FD03FFFF;1|FPD;DDR_XMPU2_CFG;FD020000;FD02FFFF;1|FPD;DDR_XMPU1_CFG;FD010000;FD01FFFF;1|FPD;DDR_XMPU0_CFG;FD000000;FD00FFFF;1|FPD;DDR_QOS_CTRL;FD090000;FD09FFFF;1|FPD;DDR_PHY;FD080000;FD08FFFF;1|DDR;DDR_LOW;0;7FFFFFFF;1|DDR;DDR_HIGH;800000000;87FFFFFFF;1|FPD;DDDR_CTRL;FD070000;FD070FFF;1|LPD;Coresight;FE800000;FEFFFFFF;1|LPD;CSU_DMA;FFC80000;FFC9FFFF;1|LPD;CSU;FFCA0000;FFCAFFFF;1|LPD;CRL_APB;FF5E0000;FF85FFFF;1|FPD;CRF_APB;FD1A0000;FD2DFFFF;1|FPD;CCI_REG;FD5E0000;FD5EFFFF;1|LPD;CAN1;FF070000;FF07FFFF;1|LPD;CAN0;FF060000;FF06FFFF;0|FPD;APU;FD5C0000;FD5CFFFF;1|LPD;APM_INTC_IOU;FFA20000;FFA2FFFF;1|LPD;APM_FPD_LPD;FFA30000;FFA3FFFF;1|FPD;APM_5;FD490000;FD49FFFF;1|FPD;APM_0;FD0B0000;FD0BFFFF;1|LPD;APM2;FFA10000;FFA1FFFF;1|LPD;APM1;FFA00000;FFA0FFFF;1|LPD;AMS;FFA50000;FFA5FFFF;1|FPD;AFI_5;FD3B0000;FD3BFFFF;1|FPD;AFI_4;FD3A0000;FD3AFFFF;1|FPD;AFI_3;FD390000;FD39FFFF;1|FPD;AFI_2;FD380000;FD38FFFF;1|FPD;AFI_1;FD370000;FD37FFFF;1|FPD;AFI_0;FD360000;FD36FFFF;1|LPD;AFIFM6;FF9B0000;FF9BFFFF;1|FPD;ACPU_GIC;F9010000;F907FFFF;1}\ +\ + CONFIG.PSU__PSS_REF_CLK__FREQMHZ {33.330} \ + CONFIG.PSU__QSPI_COHERENCY {0} \ + CONFIG.PSU__QSPI_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__QSPI__GRP_FBCLK__ENABLE {1} \ + CONFIG.PSU__QSPI__GRP_FBCLK__IO {MIO 6} \ + CONFIG.PSU__QSPI__PERIPHERAL__DATA_MODE {x4} \ + CONFIG.PSU__QSPI__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__QSPI__PERIPHERAL__IO {MIO 0 .. 12} \ + CONFIG.PSU__QSPI__PERIPHERAL__MODE {Dual Parallel} \ + CONFIG.PSU__SATA__LANE0__ENABLE {0} \ + CONFIG.PSU__SATA__LANE1__IO {GT Lane3} \ + CONFIG.PSU__SATA__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SATA__REF_CLK_FREQ {125} \ + CONFIG.PSU__SATA__REF_CLK_SEL {Ref Clk1} \ + CONFIG.PSU__SAXIGP0__DATA_WIDTH {128} \ + CONFIG.PSU__SD1_COHERENCY {0} \ + CONFIG.PSU__SD1_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__SD1__CLK_100_SDR_OTAP_DLY {0x3} \ + CONFIG.PSU__SD1__CLK_200_SDR_OTAP_DLY {0x3} \ + CONFIG.PSU__SD1__CLK_50_DDR_ITAP_DLY {0x3D} \ + CONFIG.PSU__SD1__CLK_50_DDR_OTAP_DLY {0x4} \ + CONFIG.PSU__SD1__CLK_50_SDR_ITAP_DLY {0x15} \ + CONFIG.PSU__SD1__CLK_50_SDR_OTAP_DLY {0x5} \ + CONFIG.PSU__SD1__DATA_TRANSFER_MODE {8Bit} \ + CONFIG.PSU__SD1__GRP_CD__ENABLE {1} \ + CONFIG.PSU__SD1__GRP_CD__IO {MIO 45} \ + CONFIG.PSU__SD1__GRP_POW__ENABLE {0} \ + CONFIG.PSU__SD1__GRP_WP__ENABLE {1} \ + CONFIG.PSU__SD1__GRP_WP__IO {MIO 44} \ + CONFIG.PSU__SD1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SD1__PERIPHERAL__IO {MIO 39 .. 51} \ + CONFIG.PSU__SD1__SLOT_TYPE {SD 3.0} \ + CONFIG.PSU__SWDT0__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT0__RESET__ENABLE {0} \ + CONFIG.PSU__SWDT1__CLOCK__ENABLE {0} \ + CONFIG.PSU__SWDT1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__SWDT1__RESET__ENABLE {0} \ + CONFIG.PSU__TSU__BUFG_PORT_PAIR {0} \ + CONFIG.PSU__TTC0__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC0__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC1__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC1__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC2__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC2__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC2__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__TTC3__CLOCK__ENABLE {0} \ + CONFIG.PSU__TTC3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__TTC3__WAVEOUT__ENABLE {0} \ + CONFIG.PSU__UART0__BAUD_RATE {115200} \ + CONFIG.PSU__UART0__MODEM__ENABLE {0} \ + CONFIG.PSU__UART0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__UART0__PERIPHERAL__IO {MIO 18 .. 19} \ + CONFIG.PSU__UART1__BAUD_RATE {115200} \ + CONFIG.PSU__UART1__MODEM__ENABLE {0} \ + CONFIG.PSU__UART1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__UART1__PERIPHERAL__IO {MIO 20 .. 21} \ + CONFIG.PSU__USB0_COHERENCY {0} \ + CONFIG.PSU__USB0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB0__PERIPHERAL__IO {MIO 52 .. 63} \ + CONFIG.PSU__USB0__REF_CLK_FREQ {26} \ + CONFIG.PSU__USB0__REF_CLK_SEL {Ref Clk2} \ + CONFIG.PSU__USB2_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__EMIO__ENABLE {0} \ + CONFIG.PSU__USB3_0__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__USB3_0__PERIPHERAL__IO {GT Lane2} \ + CONFIG.PSU__USB__RESET__MODE {Boot Pin} \ + CONFIG.PSU__USB__RESET__POLARITY {Active Low} \ + CONFIG.PSU__USE__IRQ0 {1} \ + CONFIG.PSU__USE__M_AXI_GP0 {1} \ + CONFIG.PSU__USE__M_AXI_GP1 {0} \ + CONFIG.PSU__USE__M_AXI_GP2 {0} \ + CONFIG.PSU__USE__S_AXI_GP0 {1} \ + ] $zynq_ultra_ps_e_0 + + + # Create instance: axi_dma_0, and set properties + set axi_dma_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 ] + set_property -dict [list \ + CONFIG.c_include_sg {0} \ + CONFIG.c_sg_length_width {26} \ + ] $axi_dma_0 + + + # Create instance: axi_intc_0, and set properties + set axi_intc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_intc:4.1 axi_intc_0 ] + + # Create instance: ps8_0_axi_periph, and set properties + set ps8_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps8_0_axi_periph ] + set_property -dict [list \ + CONFIG.NUM_MI {2} \ + CONFIG.NUM_SI {1} \ + ] $ps8_0_axi_periph + + + # Create instance: rst_ps8_0_99M, and set properties + set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] + + # Create instance: axi_smc, and set properties + set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] + set_property CONFIG.NUM_SI {2} $axi_smc + + + # Create instance: xlconcat_0, and set properties + set xlconcat_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_0 ] + + # Create interface connections + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] [get_bd_intf_pins axi_smc/S00_AXI] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] [get_bd_intf_pins axi_smc/S01_AXI] + connect_bd_intf_net -intf_net axi_smc_M00_AXI [get_bd_intf_pins axi_smc/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] + connect_bd_intf_net -intf_net ps8_0_axi_periph_M00_AXI [get_bd_intf_pins ps8_0_axi_periph/M00_AXI] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + connect_bd_intf_net -intf_net ps8_0_axi_periph_M01_AXI [get_bd_intf_pins ps8_0_axi_periph/M01_AXI] [get_bd_intf_pins axi_intc_0/s_axi] + connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM0_FPD [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM0_FPD] [get_bd_intf_pins ps8_0_axi_periph/S00_AXI] + + # Create port connections + connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins xlconcat_0/In0] + connect_bd_net -net axi_intc_0_irq [get_bd_pins axi_intc_0/irq] [get_bd_pins zynq_ultra_ps_e_0/pl_ps_irq0] + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins rst_ps8_0_99M/peripheral_aresetn] [get_bd_pins axi_dma_0/axi_resetn] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_smc/aresetn] [get_bd_pins ps8_0_axi_periph/ARESETN] [get_bd_pins ps8_0_axi_periph/S00_ARESETN] [get_bd_pins ps8_0_axi_periph/M00_ARESETN] [get_bd_pins ps8_0_axi_periph/M01_ARESETN] + connect_bd_net -net xlconcat_0_dout [get_bd_pins xlconcat_0/dout] [get_bd_pins axi_intc_0/intr] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins zynq_ultra_ps_e_0/pl_clk0] [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_fpd_aclk] [get_bd_pins rst_ps8_0_99M/slowest_sync_clk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_smc/aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc0_fpd_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins ps8_0_axi_periph/ACLK] [get_bd_pins ps8_0_axi_periph/S00_ACLK] [get_bd_pins ps8_0_axi_periph/M00_ACLK] [get_bd_pins ps8_0_axi_periph/M01_ACLK] + connect_bd_net -net zynq_ultra_ps_e_0_pl_resetn0 [get_bd_pins zynq_ultra_ps_e_0/pl_resetn0] [get_bd_pins rst_ps8_0_99M/ext_reset_in] + + # Create address segments + assign_bd_address -offset 0xA0000000 -range 0x00010000 -target_address_space [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs axi_dma_0/S_AXI_LITE/Reg] -force + assign_bd_address -offset 0xA0010000 -range 0x00010000 -target_address_space [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs axi_intc_0/S_AXI/Reg] -force + assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force + assign_bd_address -offset 0xE0000000 -range 0x10000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] -force + assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force + assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force + assign_bd_address -offset 0xE0000000 -range 0x10000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] -force + assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force + + # Exclude Address Segments + exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] + exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] + exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] + exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] + + + # Restore current instance + current_bd_instance $oldCurInst + + # Create PFM attributes + set_property PFM_NAME {vendor:lib:zcu102pf:1.0} [get_files [current_bd_design].bd] + set_property PFM.AXI_PORT {M_AXI_HPM1_FPD {memport "M_AXI_GP" sptag "HPM1" memory "" is_range "false"} M_AXI_HPM0_LPD {memport "M_AXI_GP" sptag "HPM0" memory "" is_range "false"} S_AXI_HPC1_FPD {memport "S_AXI_HPC" sptag "HPC1" memory "" is_range "false"} S_AXI_HP0_FPD {memport "S_AXI_HP" sptag "HP0" memory "" is_range "false"} S_AXI_HP1_FPD {memport "S_AXI_HP" sptag "HP1" memory "" is_range "false"} S_AXI_HP2_FPD {memport "S_AXI_HP" sptag "HP2" memory "" is_range "false"} S_AXI_HP3_FPD {memport "S_AXI_HP" sptag "HP3" memory "" is_range "false"}} [get_bd_cells /zynq_ultra_ps_e_0] + set_property PFM.CLOCK {pl_clk0 {id "0" is_default "true" proc_sys_reset "/rst_ps8_0_99M" status "fixed" freq_hz "99990005"}} [get_bd_cells /zynq_ultra_ps_e_0] + set_property PFM.AXIS_PORT {M_AXIS_MM2S {type "M_AXIS" sptag "DMA_MM2S" is_range "false"} S_AXIS_S2MM {type "S_AXIS" sptag "DMA_S2MM" is_range "false"}} [get_bd_cells /axi_dma_0] + set_property PFM.AXI_PORT {M02_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"} M03_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"} M04_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"} M05_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"} M06_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"} M07_AXI {memport "M_AXI_GP" sptag "" memory "" is_range "false"}} [get_bd_cells /ps8_0_axi_periph] + set_property PFM.IRQ {In1 {is_range "true"}} [get_bd_cells /xlconcat_0] + + + validate_bd_design + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" diff --git a/hls4ml/templates/vivado/ap_types/ap_axi_sdata.h b/hls4ml/templates/vivado/ap_types/ap_axi_sdata.h new file mode 100755 index 0000000000..2913ce80a1 --- /dev/null +++ b/hls4ml/templates/vivado/ap_types/ap_axi_sdata.h @@ -0,0 +1,402 @@ +// Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. +// Copyright 2022-2023 Advanced Micro Devices, Inc. All Rights Reserved. + +// 67d7842dbbe25473c3c32b93c0da8047785f30d78e8a024de1b57352245f9689 + +/* + * This file contains the definition of the data types for AXI streaming. + * ap_axi_s is a signed interpretation of the AXI stream + * ap_axi_u is an unsigned interpretation of the AXI stream + */ + +#ifndef __AP__AXI_SDATA__ +#define __AP__AXI_SDATA__ + +#include "ap_int.h" +#include "hls_stream.h" +#include +#include +#include +#include +//#include "ap_fixed.h" +template +struct ap_fixed; +template +struct ap_ufixed; + +namespace hls { + +template constexpr std::size_t bitwidth = sizeof(T) * CHAR_BIT; +template <> constexpr std::size_t bitwidth = 1 * CHAR_BIT; + +template constexpr std::size_t bitwidth> = W; +template constexpr std::size_t bitwidth> = W; +template +constexpr std::size_t bitwidth> = + _AP_W; +template +constexpr std::size_t bitwidth> = + _AP_W; + +template +constexpr std::size_t bytewidth = (bitwidth + CHAR_BIT - 1) / CHAR_BIT; +template <> constexpr std::size_t bytewidth = 1; + +struct axis_disabled_signal {}; + +// Enablement for axis signals +#define AXIS_ENABLE_DATA 0b00000001 +#define AXIS_ENABLE_DEST 0b00000010 +#define AXIS_ENABLE_ID 0b00000100 +#define AXIS_ENABLE_KEEP 0b00001000 +#define AXIS_ENABLE_LAST 0b00010000 +#define AXIS_ENABLE_STRB 0b00100000 +#define AXIS_ENABLE_USER 0b01000000 + +// clang-format off +// Disablement mask for DATA axis signals +#define AXIS_DISABLE_DATA (0b11111111 ^ AXIS_ENABLE_DATA) & \ + (0b11111111 ^ AXIS_ENABLE_KEEP) & \ + (0b11111111 ^ AXIS_ENABLE_STRB) + +// Enablement/disablement of all axis signals +#define AXIS_ENABLE_ALL 0b01111111 +#define AXIS_DISABLE_ALL 0b00000000 + +// Struct: axis - struct that has one or more member 'signals' +// Signals: DATA, DEST, ID, KEEP, LAST, STRB, USER +// All signals are optional: +// LAST is enabled by default +// DEST, ID, & USER are disabled by default +// DATA, KEEP, & STRB are enabled by default for non-void DATA type +// Template parameters: +// T : type of the DATA signal +// WUser : size of the USER signal, if zero signal will be disabled +// WId : size of the ID signal, if zero signal will be disabled +// WDest : size of the DEST signal, if zero signal will be disabled +// EnableSignals : bit field to enable signals, see AXIS_ENABLE_* +// StrictEnablement : when true check that EnableSignals matches other parameters +// clang-format on +template +struct axis { + static_assert((EnableSignals & 0b10000000) == 0, + "Template parameter 'EnableSignals' is invalid only " + "low 7 bits can be set!"); + friend class stream< + axis>; + + static constexpr bool has_data = !std::is_void::value; + static constexpr bool has_user = WUser > 0; + static constexpr bool has_id = WId > 0; + static constexpr bool has_dest = WDest > 0; + static constexpr bool has_keep = EnableSignals & AXIS_ENABLE_KEEP; + static constexpr bool has_strb = EnableSignals & AXIS_ENABLE_STRB; + static constexpr bool has_last = EnableSignals & AXIS_ENABLE_LAST; + + static constexpr std::size_t width_user = has_user ? WUser : 1; + static constexpr std::size_t width_id = has_id ? WId : 1; + static constexpr std::size_t width_dest = has_dest ? WDest : 1; + static constexpr std::size_t width_keep = bytewidth; + static constexpr std::size_t width_strb = bytewidth; + static constexpr std::size_t width_last = 1; + + static_assert(has_data || has_user || has_id || has_dest || has_keep || + has_strb || has_last, + "No axis signals are enabled"); + + static_assert(StrictEnablement + ? has_data == (bool)(EnableSignals & AXIS_ENABLE_DATA) + : true, + "Found mismatched enablement for DATA signal"); + static_assert(StrictEnablement + ? has_user == (bool)(EnableSignals & AXIS_ENABLE_USER) + : true, + "Found mismatched enablement for USER signal"); + static_assert(StrictEnablement + ? has_id == (bool)(EnableSignals & AXIS_ENABLE_ID) + : true, + "Found mismatched enablement for ID signal"); + static_assert(StrictEnablement + ? has_dest == (bool)(EnableSignals & AXIS_ENABLE_DEST) + : true, + "Found mismatched enablement for DEST signal"); + + typedef typename std::conditional::type + Type_data; + Type_data data; + +#ifdef AESL_SYN + + NODEBUG Type_data get_data() const { +#pragma HLS inline + assert(has_data); + return data; + } + NODEBUG void set_data(Type_data d) { +#pragma HLS inline + assert(has_data); + data = d; + } + +#define _AXIS_CHANNEL_API(CHAN_NAME) \ + typedef \ + typename std::conditional, \ + axis_disabled_signal>::type Type_##CHAN_NAME; \ + Type_##CHAN_NAME CHAN_NAME; \ + __attribute__((nodebug)) __attribute__((always_inline)) \ + Type_##CHAN_NAME get_##CHAN_NAME() const { \ + assert(has_##CHAN_NAME); \ + return CHAN_NAME; \ + } \ + __attribute__((nodebug)) __attribute__( \ + (always_inline)) void set_##CHAN_NAME(Type_##CHAN_NAME value) { \ + assert(has_##CHAN_NAME); \ + CHAN_NAME = value; \ + } + +#else + + Type_data get_data() const { + if (!has_data) + throw std::runtime_error("CHAN_NAME is not enabled"); + return data; + } + void set_data(Type_data d) { + if (!has_data) + throw std::runtime_error("CHAN_NAME is not enabled"); + data = d; + } + +#define _AXIS_CHANNEL_API(CHAN_NAME) \ + typedef \ + typename std::conditional, \ + axis_disabled_signal>::type Type_##CHAN_NAME; \ + Type_##CHAN_NAME CHAN_NAME; \ + Type_##CHAN_NAME get_##CHAN_NAME() const { \ + if (!has_##CHAN_NAME) \ + throw std::runtime_error("CHAN_NAME is not enabled"); \ + return CHAN_NAME; \ + } \ + void set_##CHAN_NAME(Type_##CHAN_NAME value) { \ + if (!has_##CHAN_NAME) \ + throw std::runtime_error("CHAN_NAME is not enabled"); \ + CHAN_NAME = value; \ + } + +#endif + + _AXIS_CHANNEL_API(keep) + _AXIS_CHANNEL_API(strb) + _AXIS_CHANNEL_API(user) + _AXIS_CHANNEL_API(last) + _AXIS_CHANNEL_API(id) + _AXIS_CHANNEL_API(dest) +#undef _AXIS_CHANNEL_API + +// For original `qdma_axis` +#ifdef AESL_SYN + NODEBUG +#endif + void keep_all() { +#pragma HLS inline +#ifdef AESL_SYN + assert(has_keep); +#else + if (!has_data) + throw std::runtime_error("CHAN_NAME is not enabled"); +#endif + ap_uint k = 0; + keep = ~k; + } + +private: +#ifdef AESL_SYN +#define _AXIS_CHANNEL_INTERNAL_API(CHAN_NAME) \ + __attribute__((nodebug)) __attribute__((always_inline)) \ + Type_##CHAN_NAME *get_##CHAN_NAME##_ptr() { \ + return (!has_##CHAN_NAME) ? nullptr : &CHAN_NAME; \ + } + + _AXIS_CHANNEL_INTERNAL_API(data) + _AXIS_CHANNEL_INTERNAL_API(keep) + _AXIS_CHANNEL_INTERNAL_API(strb) + _AXIS_CHANNEL_INTERNAL_API(user) + _AXIS_CHANNEL_INTERNAL_API(last) + _AXIS_CHANNEL_INTERNAL_API(id) + _AXIS_CHANNEL_INTERNAL_API(dest) +#undef _AXIS_CHANNEL_INTERNAL_API +#endif +}; + +// clang-format off +// Struct: axis_data (alternative to axis) +// DATA signal always enabled +// All other signals are optional, disabled by default +// Example usage: +// hls::axis_data A; // DATA and LAST signals only +// hls::axis_data B; // DATA, LAST, and USER signals only (USER width is 32) +// hls::axis_data C; // All signals enabled +// hls::axis_data D; // All signals enabled, this throw an exception due to zero size for WUser/WId/WDest +// clang-format on +template +using axis_data = axis; + +// Struct: axis_user (alternative to axis) +// USER signal always enabled +// DATA signal always disabled +// All other signals are optional, disabled by default +// Example usage: +// hls::axis_user<32> C; // USER signal only +// hls::axis_user<32, AXIS_ENABLE_LAST> D; // USER and LAST signals only +template +using axis_user = axis; + +} // namespace hls + +template +using ap_axis = hls::axis, WUser, WId, WDest, EnableSignals, + StrictEnablement>; + +template +using ap_axiu = hls::axis, WUser, WId, WDest, EnableSignals, + StrictEnablement>; + +// original usage: qdma_axis, and TSTRB is omitted. +template +using qdma_axis = hls::axis, WUser, WId, WDest, + AXIS_ENABLE_ALL ^ AXIS_ENABLE_STRB, false>; + +#ifdef AESL_SYN +#if ((__clang_major__ != 3) || (__clang_minor__ != 1)) +namespace hls { + +template +class stream> + final { + typedef axis + __STREAM_T__; + +public: + /// Constructors + INLINE NODEBUG stream() {} + + INLINE NODEBUG stream(const char *name) { (void)name; } + + /// Make copy constructor and assignment operator private +private: + INLINE NODEBUG stream(const stream<__STREAM_T__> &chn) : V(chn.V) {} + +public: + /// Overload >> and << operators to implement read() and write() + INLINE NODEBUG void operator>>(__STREAM_T__ &rdata) { read(rdata); } + + INLINE NODEBUG void operator<<(const __STREAM_T__ &wdata) { write(wdata); } + + /// empty & full + NODEBUG bool empty() { +#pragma HLS inline + bool tmp = __fpga_axis_valid( + V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), V.get_user_ptr(), + V.get_last_ptr(), V.get_id_ptr(), V.get_dest_ptr()); + return !tmp; + } + + NODEBUG bool full() { +#pragma HLS inline + bool tmp = __fpga_axis_ready( + V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), V.get_user_ptr(), + V.get_last_ptr(), V.get_id_ptr(), V.get_dest_ptr()); + return !tmp; + } + + /// Blocking read + NODEBUG void read(__STREAM_T__ &dout) { +#pragma HLS inline + __STREAM_T__ tmp; + __fpga_axis_pop(V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), + V.get_user_ptr(), V.get_last_ptr(), V.get_id_ptr(), + V.get_dest_ptr(), tmp.get_data_ptr(), tmp.get_keep_ptr(), + tmp.get_strb_ptr(), tmp.get_user_ptr(), tmp.get_last_ptr(), + tmp.get_id_ptr(), tmp.get_dest_ptr()); + dout = tmp; + } + + NODEBUG __STREAM_T__ read() { +#pragma HLS inline + __STREAM_T__ tmp; + __fpga_axis_pop(V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), + V.get_user_ptr(), V.get_last_ptr(), V.get_id_ptr(), + V.get_dest_ptr(), tmp.get_data_ptr(), tmp.get_keep_ptr(), + tmp.get_strb_ptr(), tmp.get_user_ptr(), tmp.get_last_ptr(), + tmp.get_id_ptr(), tmp.get_dest_ptr()); + return tmp; + } + + /// Blocking write + NODEBUG void write(const __STREAM_T__ &din) { +#pragma HLS inline + __STREAM_T__ tmp = din; + __fpga_axis_push(V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), + V.get_user_ptr(), V.get_last_ptr(), V.get_id_ptr(), + V.get_dest_ptr(), tmp.get_data_ptr(), tmp.get_keep_ptr(), + tmp.get_strb_ptr(), tmp.get_user_ptr(), tmp.get_last_ptr(), + tmp.get_id_ptr(), tmp.get_dest_ptr()); + } + + /// Non-Blocking read + NODEBUG bool read_nb(__STREAM_T__ &dout) { +#pragma HLS inline + __STREAM_T__ tmp; + if (__fpga_axis_nb_pop(V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), + V.get_user_ptr(), V.get_last_ptr(), V.get_id_ptr(), + V.get_dest_ptr(), tmp.get_data_ptr(), + tmp.get_keep_ptr(), tmp.get_strb_ptr(), + tmp.get_user_ptr(), tmp.get_last_ptr(), + tmp.get_id_ptr(), tmp.get_dest_ptr())) { + dout = tmp; + return true; + } else { + return false; + } + } + + /// Non-Blocking write + NODEBUG bool write_nb(const __STREAM_T__ &in) { +#pragma HLS inline + __STREAM_T__ tmp = in; + bool full_n = __fpga_axis_nb_push( + V.get_data_ptr(), V.get_keep_ptr(), V.get_strb_ptr(), V.get_user_ptr(), + V.get_last_ptr(), V.get_id_ptr(), V.get_dest_ptr(), tmp.get_data_ptr(), + tmp.get_keep_ptr(), tmp.get_strb_ptr(), tmp.get_user_ptr(), + tmp.get_last_ptr(), tmp.get_id_ptr(), tmp.get_dest_ptr()); + return full_n; + } + +private: + __STREAM_T__ V NO_CTOR; +}; + +} // namespace hls +#endif +#endif +#endif diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h index 225bce181d..e5bd2da8f2 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h @@ -1,6 +1,7 @@ #ifndef NNET_HELPERS_H #define NNET_HELPERS_H +#include "ap_axi_sdata.h" #include "hls_stream.h" #include #include @@ -161,6 +162,37 @@ template void convert_data(hls::stre } } +template +void convert_data_axis(srcType *src, hls::stream> &dst) { + for (size_t i = 0; i < SIZE; i++) { + hls::axis ctype; + ctype.data = dstType(src[i]); + dst.write(ctype); + } +} + +template +void convert_data_axis(std::vector &src, hls::stream> &dst) { + for (auto i = 0; i < SIZE; i++) { + hls::axis pack; + pack.data = src[i]; + if (i == SIZE - 1) { + pack.last = 1; + } else { + pack.last = 0; + } + dst.write(pack); + } +} + +template +void convert_data_axis(hls::stream> &src, dstType *dst) { + for (size_t i = 0; i < SIZE; i++) { + hls::axis ctype = src.read(); + dst[i] = dstType(ctype.data); + } +} + extern bool trace_enabled; extern std::map *trace_outputs; extern size_t trace_type_size; @@ -282,6 +314,18 @@ template void copy_data_a } } +template +void print_result_axis(hls::stream &result, std::ostream &out, bool keep = false) { + std::cout << "from x" << std::endl; + for (int i = 0; i < SIZE; i++) { + res_T res_pack = result.read(); + out << res_pack.data << " "; + if (keep) + result.write(res_pack); + } + out << std::endl; +} + template void print_result(res_T result[SIZE], std::ostream &out, bool keep = false) { for (int i = 0; i < SIZE; i++) { out << result[i] << " "; @@ -313,6 +357,15 @@ template void fill_zero(hls::stream &data) { } } +template void fill_zero_axi(hls::stream &data, bool reqLast) { + for (int i = 0; i < SIZE; i++) { + data_T data_pack; + data_pack.data = 0; + data_pack.last = reqLast && (i == (SIZE - 1)) ? 1 : 0; + data.write(data_pack); + } +} + template int read_file_1D(const char *filename, dataType data[nrows]) { FILE *fp; fp = fopen(filename, "r"); diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 8c48f79d2d..108391c673 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -3,6 +3,7 @@ from hls4ml.writer.oneapi_writer import OneAPIWriter from hls4ml.writer.quartus_writer import QuartusWriter from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter +from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter from hls4ml.writer.vitis_writer import VitisWriter from hls4ml.writer.vivado_accelerator_writer import VivadoAcceleratorWriter from hls4ml.writer.vivado_writer import VivadoWriter @@ -11,6 +12,7 @@ register_writer('Vivado', VivadoWriter) register_writer('VivadoAccelerator', VivadoAcceleratorWriter) register_writer('Vitis', VitisWriter) +register_writer('VitisUnified', VitisUnifiedWriter) register_writer('Quartus', QuartusWriter) register_writer('oneAPI', OneAPIWriter) register_writer('Catapult', CatapultWriter) diff --git a/hls4ml/writer/vitis_unified_writer.py b/hls4ml/writer/vitis_unified_writer.py new file mode 100644 index 0000000000..4396e22ec0 --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer.py @@ -0,0 +1,764 @@ +import os +import stat +from pathlib import Path +from shutil import copytree + +from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig +from hls4ml.writer.vitis_writer import VitisWriter + + +class VitisUnifiedWriter(VitisWriter): + """Writer for Vitis Unified backend. + + This class follows the same pattern as Vivado/Vitis writers: + all generation logic is implemented as writer instance methods instead of + split helper generator classes. + """ + + def __init__(self): + super().__init__() + self.vitis_unified_config = None + + def write_tar(self, model): + super().write_tar(model) + + def write_board_script_override(self, model): + """No-op: Vitis Unified uses vitis-comp.json and hls_kernel_config, not project.tcl.""" + pass + + # ===== Public helpers used by backend/passes ===== + def get_vitis_unified_working_directory(self, model): + return os.path.join(model.config.get_output_dir(), 'vitis_workspace') + + def get_vitis_hls_dir(self, model): + return os.path.join(self.get_vitis_unified_working_directory(model), model.config.get_project_name()) + + def get_vitis_hls_exec_dir(self, model): + return os.path.join(self.get_vitis_hls_dir(model), 'vitis_unified_project') + + def get_vitis_linker_dir(self, model): + return os.path.join(self.get_vitis_unified_working_directory(model), 'system_link') + + # ===== Internal helpers ===== + def _set_unified_config(self, model): + self.vitis_unified_config = VitisUnifiedConfig( + model.config, model.get_input_variables(), model.get_output_variables() + ) + + def _is_axi_stream(self): + return self.vitis_unified_config.get_axi_mode() == 'axi_stream' + + def _is_axi_master(self): + return self.vitis_unified_config.get_axi_mode() == 'axi_master' + + def _get_project_name(self, model): + return model.config.get_project_name() + + def _get_wrapper_file_name(self, model, is_axi_master): + suffix = 'axi_master' if is_axi_master else 'axi_stream' + return f'{self._get_project_name(model)}_{suffix}' + + def _get_sim_file_name(self): + return 'myproject_test' + + def _get_top_wrap_func_name(self, model, is_axi_master): + return self._get_wrapper_file_name(model, is_axi_master) + + def _get_wrap_ip_name(self, model, is_axi_master): + return f'{self._get_top_wrap_func_name(model, is_axi_master)}_1' + + def _get_interrupt_pin_name(self, model, is_axi_master): + if is_axi_master: + return f'{self._get_wrap_ip_name(model, True)}/interrupt' + else: + return f'{self._get_wrap_ip_name(model, False)}/s2mm_introut' + + def _get_xo_file_path(self, model): + """Path to .xo relative to system_link (for link_system.sh).""" + xo_name = f'{self._get_top_wrap_func_name(model, self._is_axi_master())}.xo' + return os.path.join('..', model.config.get_project_name(), 'vitis_unified_project', xo_name) + + def _get_io_port_name(self, tensor_var, is_input, idx): + direction = 'in' if is_input else 'out' + return f'gmem_{direction}{idx}_ptr_{tensor_var.name}' + + def _get_local_stream_name(self, tensor_var, is_input, idx): + direction = 'in' if is_input else 'out' + return f'stream_{direction}{idx}_{tensor_var.name}' + + def _get_dma_type_name(self): + return 'dma_data_packet' + + @staticmethod + def _gen_hex_addr_list(start_addr, stride, size, indent): + return [f'{indent}{hex(start_addr + index * stride)}' for index in range(size)] + + def _gen_io_signature(self, indent, input_type, output_type, inputs, outputs): + input_ptrs = [f'{indent}{input_type}* {self._get_io_port_name(inp, True, idx)}' for idx, inp in enumerate(inputs)] + output_ptrs = [ + f'{indent}{output_type}* {self._get_io_port_name(out, False, idx)}' for idx, out in enumerate(outputs) + ] + return ', '.join(input_ptrs) + ',\n' + ', '.join(output_ptrs) + '\n' + + def _ensure_export_path(self, model): + export_path = Path(model.config.get_output_dir()) / 'export' + export_path.mkdir(parents=True, exist_ok=True) + + # ===== Build/config generation ===== + def write_build_script(self, model): + self._write_bridge_build_script(model) + self._build_unified_project_skeleton(model) + self._write_hls_kernel_config(model, is_csim=True) + self._write_hls_kernel_config(model, is_csim=False) + self._write_linker_dir(model) + self._write_linker_launcher(model) + self._write_linker_config(model) + + def _write_bridge_build_script(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + with ( + open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) as fin, + open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') as fout, + ): + for line in fin.readlines(): + if 'myprojectBaseName' in line: + line = line.replace('myprojectBaseName', self._get_project_name(model)) + if 'myprojectWrapName' in line: + line = line.replace('myprojectWrapName', self._get_wrapper_file_name(model, self._is_axi_master())) + if 'mystamp' in line: + line = line.replace('mystamp', model.config.get_config_value('Stamp')) + fout.write(line) + + build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve() + build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC) + + def _write_hls_kernel_config(self, model, is_csim=False): + filedir = os.path.dirname(os.path.abspath(__file__)) + suffix = 'csim' if is_csim else 'cosim' + with ( + open(os.path.join(filedir, '../templates/vitis_unified/hls_kernel_config.cfg')) as fin, + open(f'{model.config.get_output_dir()}/hls_kernel_config_{suffix}.cfg', 'w') as fout, + ): + for line in fin.readlines(): + if '{PART}' in line: + line = line.replace('{PART}', model.config.get_config_value('Part')) + if '{CLK}' in line: + line = line.replace('{CLK}', model.config.get_config_value('ClockPeriod')) + if '{CLK_UC}' in line: + line = line.replace('{CLK_UC}', model.config.get_config_value('ClockUncertainty')) + if '{OUTDIR}' in line: + line = line.replace('{OUTDIR}', model.config.get_output_dir()) + if '{TOP_NAME}' in line: + line = line.replace('{TOP_NAME}', self._get_top_wrap_func_name(model, self._is_axi_master())) + if '{FILE_NAME_WRAP}' in line: + line = line.replace('{FILE_NAME_WRAP}', self._get_wrapper_file_name(model, self._is_axi_master())) + if '{SIM_FILE_NAME}' in line: + line = line.replace('{SIM_FILE_NAME}', self._get_sim_file_name()) + if '{FILE_NAME_BASE}' in line: + line = line.replace('{FILE_NAME_BASE}', self._get_project_name(model)) + if '{OUTPUT_KERNEL_TYPE}' in line: + line = line.replace('{OUTPUT_KERNEL_TYPE}', 'xo') + if is_csim and (('enable_fifo_sizing' in line) or ('-DRTL_SIM' in line)): + line = '#' + line + fout.write(line) + + def _build_unified_project_skeleton(self, model): + workspace_dir = self.get_vitis_unified_working_directory(model) + hls_dir = self.get_vitis_hls_dir(model) + exec_dir = self.get_vitis_hls_dir(model) + vitis_comp = os.path.join(str(hls_dir), 'vitis-comp.json') + + os.makedirs(workspace_dir, exist_ok=True) + os.makedirs(hls_dir, exist_ok=True) + os.makedirs(exec_dir, exist_ok=True) + + filedir = os.path.dirname(os.path.abspath(__file__)) + with ( + open(os.path.join(filedir, '../templates/vitis_unified/vitis_workspace/kernel_project/vitis-comp.json')) as fin, + open(vitis_comp, 'w') as fout, + ): + for line in fin.readlines(): + if '{HLS_NAME}' in line: + line = line.replace('{HLS_NAME}', self._get_project_name(model)) + if '{CONFIG_FILE}' in line: + line = line.replace('{CONFIG_FILE}', f'{model.config.get_output_dir()}/hls_kernel_config.cfg') + fout.write(line) + + def _write_linker_dir(self, model): + os.makedirs(self.get_vitis_linker_dir(model), exist_ok=True) + # Copy board platform files (tcl_scripts, etc.) when using platform generator + platform_generator_tcl = self.vitis_unified_config.get_platform_generator_tcl() + if platform_generator_tcl: + self._copy_board_platform_files(model) + + def _copy_board_platform_files(self, model): + """Copy board folder (tcl_scripts, python_drivers, etc.) to vitis_workspace for local use.""" + filedir = os.path.dirname(os.path.abspath(__file__)) + board = self.vitis_unified_config.get_board() + src = os.path.join(filedir, '../templates/vitis_unified', board) + dst = os.path.join(model.config.get_output_dir(), 'vitis_workspace', board) + if os.path.isdir(src): + copytree(src, dst, dirs_exist_ok=True) + + def _write_linker_launcher(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + platform_generator_tcl = self.vitis_unified_config.get_platform_generator_tcl() + if platform_generator_tcl: + # Use local copy in vitis_workspace (relative to system_link) + board = self.vitis_unified_config.get_board() + tcl_name = os.path.basename(platform_generator_tcl) + xsa_basename = os.path.basename(self.vitis_unified_config.get_platform_output_path()) + local_tcl_dir = os.path.join('..', board, 'tcl_scripts') + local_xsa_path = os.path.join('..', board, 'tcl_scripts', 'output', xsa_basename) + platform_generator_block = f'''if [ ! -f "{local_xsa_path}" ] || \\ + [ "{local_tcl_dir}/{tcl_name}" -nt "{local_xsa_path}" ]; then + echo "Generating platform from {tcl_name}..." + (cd "{local_tcl_dir}" && vivado -mode batch -source "{tcl_name}") || \\ + {{ echo "ERROR: Platform generation failed"; exit 1; }} +fi +''' + platform_path_for_vpp = local_xsa_path + else: + platform_generator_block = '' + platform_path_for_vpp = self.vitis_unified_config.get_platform_path() + + with ( + open(os.path.join(filedir, '../templates/vitis_unified/vitis_workspace/system_link/link_system.sh')) as fin, + open(f'{self.get_vitis_linker_dir(model)}/link_system.sh', 'w') as fout, + ): + for line in fin.readlines(): + if '{XSA_GENERATOR_BLOCK}' in line: + line = line.replace('{XSA_GENERATOR_BLOCK}', platform_generator_block) + if '{PLATFORM_PATH}' in line: + line = line.replace('{PLATFORM_PATH}', platform_path_for_vpp) + if '{PLATFORM_XPFM}' in line: + line = line.replace('{PLATFORM_XPFM}', self.vitis_unified_config.get_platform_path()) + if '{KERNEL_XO}' in line: + line = line.replace('{KERNEL_XO}', self._get_xo_file_path(model)) + if '{PROJECT_NAME}' in line: + line = line.replace('{PROJECT_NAME}', self._get_project_name(model)) + fout.write(line) + + link_lib_dst = Path(f'{self.get_vitis_linker_dir(model)}/link_system.sh').resolve() + link_lib_dst.chmod(link_lib_dst.stat().st_mode | stat.S_IEXEC) + + def _write_linker_config(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + with ( + open(os.path.join(filedir, '../templates/vitis_unified/vitis_workspace/system_link/link_system.cfg')) as fin, + open(f'{self.get_vitis_linker_dir(model)}/link_system.cfg', 'w') as fout, + ): + for line in fin.readlines(): + if '{CLK}' in line: + line = line.replace('{CLK}', str(100_000_000)) + if '{KERNEL_NAME}' in line: + line = line.replace('{KERNEL_NAME}', self._get_top_wrap_func_name(model, self._is_axi_master())) + if '{GUI_STATUS}' in line: + line = line.replace('{GUI_STATUS}', 'true') + if '# hls-fpga-machine-learning insert custom connection' in line and self._is_axi_stream(): + top_module_name = self._get_top_wrap_func_name(model, False) + top_mod_inst_name = top_module_name + '_1' + line += '\n' + line += '[connectivity]\n' + line += f'nk={top_module_name}:1:{top_mod_inst_name}\n' + line += f'stream_connect=DMA_MM2S:{top_mod_inst_name}.axi_input_stream\n' + line += f'stream_connect={top_mod_inst_name}.axi_output_stream:DMA_S2MM\n' + fout.write(line) + + # ===== Bridge generation ===== + def write_bridge(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + with ( + open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) as fin, + open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') as fout, + ): + model_inputs = model.get_input_variables() + model_outputs = model.get_output_variables() + model_brams = [var for var in model.get_weight_variables() if var.storage.lower() == 'bram'] + indent = ' ' + + for line in fin.readlines(): + newline = '' + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', self._get_project_name(model).upper()) + elif 'myproject' in line: + newline = line.replace('myproject', self._get_project_name(model)) + elif 'PROJECT_FILE_NAME' in line: + newline = line.replace('PROJECT_FILE_NAME', self._get_wrapper_file_name(model, self._is_axi_master())) + elif '// hls-fpga-machine-learning insert bram' in line: + newline = line + for bram in model_brams: + newline += f'#include "firmware/weights/{bram.name}.h"\n' + elif '// hls-fpga-machine-learning insert header' in line: + dtype = line.split('#', 1)[1].strip() + input_ios = [ + f'{dtype} {self._get_io_port_name(inp, True, idx)}[{inp.size_cpp()}]' + for idx, inp in enumerate(model_inputs) + ] + output_ios = [ + f'{dtype} {self._get_io_port_name(out, False, idx)}[{out.size_cpp()}]' + for idx, out in enumerate(model_outputs) + ] + newline = indent + ', '.join(input_ios) + ',\n' + newline += indent + ', '.join(output_ios) + '\n' + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + newline = '' + if dtype == self.vitis_unified_config.get_input_type(): + if self._is_axi_master(): + input_vars = [self._get_io_port_name(inp, True, idx) for idx, inp in enumerate(model_inputs)] + output_vars = [self._get_io_port_name(out, False, idx) for idx, out in enumerate(model_outputs)] + newline += indent + self._get_top_wrap_func_name(model, True) + '(\n' + newline += indent + ', '.join(input_vars) + ',\n' + newline += indent + ', '.join(output_vars) + ',\n' + newline += indent + '1);\n' + else: + assert len(model_inputs) == 1 + assert len(model_outputs) == 1 + inp = model_inputs[0] + out = model_outputs[0] + inp_func = self._get_io_port_name(inp, True, 0) + inp_stream = inp_func + '_ap' + out_func = self._get_io_port_name(out, False, 0) + out_stream = out_func + '_ap' + newline = indent + f'hls::stream<{self._get_dma_type_name()}> {inp_stream};\n' + newline += ( + indent + f'nnet::convert_data_axis<{dtype},{dtype}, N_IN>({inp_func}, {inp_stream});\n' + ) + newline += indent + f'hls::stream<{self._get_dma_type_name()}> {out_stream};\n' + newline += indent + self._get_top_wrap_func_name(model, False) + '(' + newline += inp_stream + ', ' + out_stream + ', 1);\n' + newline += ( + indent + f'nnet::convert_data_axis<{dtype},{dtype}, N_OUT>({out_stream}, {out_func});\n' + ) + elif '// hls-fpga-machine-learning insert trace_outputs' in line: + newline = '' + for layer in model.get_layers(): + func = layer.get_attr('function_cpp', None) + if func and model.config.trace_output and layer.get_attr('trace', False): + for var in layer.get_variables(): + newline += ( + indent + + 'nnet::trace_outputs->insert(std::pair(' + + f'"{layer.name}", (void *) malloc({var.size_cpp()} * element_size)));\n' + ) + elif '// hls-fpga-machine-learning insert namespace' in line: + newline = '' + namespace = model.config.get_writer_config().get('Namespace', None) + if namespace is not None: + newline += indent + f'using namespace {namespace};\n' + else: + newline = line + fout.write(newline) + + # ===== Wrapper generation ===== + def write_wrapper(self, model): + if self._is_axi_master(): + self._write_wrapper_axim(model) + else: + self._write_wrapper_axis(model) + + def _write_wrapper_axis(self, model): + inp_gmem_t, out_gmem_t, inputs, outputs = self.vitis_unified_config.get_corrected_types() + if len(inputs) != 1 or len(outputs) != 1: + raise ValueError( + 'AXIS wrapper requires exactly 1 input and 1 output port. ' + f'Found {len(inputs)} inputs and {len(outputs)} outputs.' + ) + + inp, out = inputs[0], outputs[0] + indent = ' ' + filedir = os.path.dirname(os.path.abspath(__file__)) + + with ( + open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi_stream.cpp')) as fin, + open(f'{model.config.get_output_dir()}/firmware/{self._get_project_name(model)}_axi_stream.cpp', 'w') as fout, + ): + for line in fin.readlines(): + if 'MY_PROJECT_TOP_FUNC' in line: + newline = line.replace('MY_PROJECT_TOP_FUNC', self._get_top_wrap_func_name(model, False)) + elif 'MY_PROJECT(' in line: + newline = line.replace('MY_PROJECT', self._get_project_name(model)) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{self._get_project_name(model)}_axi_stream.h"\n' + elif '// hls-fpga-machine-learning insert interface' in line: + newline = ( + indent + + '#pragma HLS INTERFACE axis port=axi_input_stream\n' + + indent + + '#pragma HLS INTERFACE axis port=axi_output_stream\n' + + indent + + '#pragma HLS INTERFACE s_axilite port=return bundle=control\n' + + indent + + '#pragma HLS INTERFACE s_axilite port=batch_size bundle=control\n' + ) + elif '// hls-fpga-machine-learning insert stream decl' in line: + in_depth = model.get_input_variables()[0].pragma[1] + out_depth = model.get_output_variables()[0].pragma[1] + newline = '' + newline += indent + f'static hls::stream<{inp.type.name}> model_input_stream("model_input");\n' + newline += indent + f'static hls::stream<{out.type.name}> model_output_stream("model_output");\n\n' + newline += indent + f'#pragma HLS STREAM variable=model_input_stream depth={in_depth}\n' + newline += indent + f'#pragma HLS STREAM variable=model_output_stream depth={out_depth}\n' + elif '// hls-fpga-machine-learning insert stream parameter' in line: + newline = line.replace( + '// hls-fpga-machine-learning insert stream parameter', + f'hls::stream<{inp.type.name}> &model_input_stream, ' + f'hls::stream<{out.type.name}> &model_output_stream', + ) + + elif 'INPUT_LAYER_TYPE' in line: + newline = line.replace('INPUT_LAYER_TYPE', inp.type.name) + elif 'OUTPUT_LAYER_TYPE' in line: + newline = line.replace('OUTPUT_LAYER_TYPE', out.type.name) + elif 'OUTPUT_GMEM_TYPE' in line: + newline = line.replace('OUTPUT_GMEM_TYPE', out_gmem_t) + else: + newline = line + fout.write(newline) + + with ( + open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi_stream.h')) as fin, + open(f'{model.config.get_output_dir()}/firmware/{self._get_project_name(model)}_axi_stream.h', 'w') as fout, + ): + for line in fin.readlines(): + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', self._get_project_name(model).upper()) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{self._get_project_name(model)}.h"\n#include "ap_axi_sdata.h"\n' + elif 'MY_PROJECT_TOP_FUNC' in line: + newline = line.replace('MY_PROJECT_TOP_FUNC', self._get_top_wrap_func_name(model, False)) + elif '// hls-fpga-machine-learning insert definitions' in line: + newline = '' + newline += f'static const unsigned N_IN = {inp.size()};\n' + newline += f'static const unsigned N_OUT = {out.size()};\n' + newline += f'typedef hls::axis<{inp_gmem_t}, 0, 0, 0> {self._get_dma_type_name()};\n' + else: + newline = line + fout.write(newline) + + def _write_wrapper_axim(self, model): + inp_gmem_t, out_gmem_t, inputs, outputs = self.vitis_unified_config.get_corrected_types() + indent = ' ' + filedir = os.path.dirname(os.path.abspath(__file__)) + + with ( + open(os.path.join(filedir, f'../templates/vitis_unified/{self._get_project_name(model)}_axi_master.cpp')) as fin, + open(f'{model.config.get_output_dir()}/firmware/{self._get_wrapper_file_name(model, True)}.cpp', 'w') as fout, + ): + for line in fin.readlines(): + if 'MY_PROJECT_DM_INC' in line: + line = line.replace('MY_PROJECT_DM_INC', self._get_wrapper_file_name(model, True)) + elif 'MY_PROJECT_TOP_FUNC' in line: + line = line.replace('MY_PROJECT_TOP_FUNC', self._get_top_wrap_func_name(model, True)) + elif 'STREAM_BUF_IN_SZ' in line: + line = line.replace('VAL', str(self.vitis_unified_config.get_in_stream_buf_size())) + elif 'STREAM_BUF_OUT_SZ' in line: + line = line.replace('VAL', str(self.vitis_unified_config.get_out_stream_buf_size())) + elif '// vitis-unified-wrapper-io' in line: + line = self._gen_io_signature(indent, inp_gmem_t, out_gmem_t, inputs, outputs) + '\n' + elif '// vitis-unified-wrapper-interface' in line: + line = '' + for input_idx, inp in enumerate(inputs): + line += ( + f'{indent}#pragma HLS INTERFACE m_axi port={self._get_io_port_name(inp, True, input_idx)} ' + f'bundle=gmem_in{input_idx} depth={inp.size()}\n' + ) + for output_idx, out in enumerate(outputs): + line += ( + f'{indent}#pragma HLS INTERFACE m_axi port={self._get_io_port_name(out, False, output_idx)} ' + f'bundle=gmem_out{output_idx} depth={out.size()}\n' + ) + line += ( + f'{indent}#pragma HLS INTERFACE s_axilite port=batch_size bundle=control\n' + f'{indent}#pragma HLS INTERFACE s_axilite port=return bundle=control\n' + ) + elif '// vitis-unified-wrapper-stream-dec' in line: + line = '' + for input_idx, inp in enumerate(inputs): + line += ( + f'{indent}static hls::stream<{inp.type.name}> ' + f'{self._get_local_stream_name(inp, True, input_idx)};\n' + ) + for output_idx, out in enumerate(outputs): + line += ( + f'{indent}static hls::stream<{out.type.name}> ' + f'{self._get_local_stream_name(out, False, output_idx)};\n' + ) + elif '// vitis-unified-wrapper-stream-config' in line: + line = '' + for input_idx, inp in enumerate(inputs): + line += ( + f'{indent}#pragma HLS STREAM variable={self._get_local_stream_name(inp, True, input_idx)} ' + f'depth=STREAM_BUF_IN_SZ\n' + ) + for output_idx, out in enumerate(outputs): + line += ( + f'{indent}#pragma HLS STREAM variable={self._get_local_stream_name(out, False, output_idx)} ' + f'depth=STREAM_BUF_OUT_SZ\n' + ) + elif '// vitis-unified-wrapper-load' in line: + line = '' + for input_idx, inp in enumerate(inputs): + line += ( + f'{indent}load_input({self._get_io_port_name(inp, True, input_idx)}, ' + f'{self._get_local_stream_name(inp, True, input_idx)}, batch_size, {inp.size()});\n' + ) + elif '// vitis-unified-wrapper-compute-signature' in line: + sig_parts = [] + for idx, inp in enumerate(inputs): + sig_parts.append(f'hls::stream<{inp.type.name}>& {self._get_local_stream_name(inp, True, idx)}') + for idx, out in enumerate(outputs): + sig_parts.append(f'hls::stream<{out.type.name}>& {self._get_local_stream_name(out, False, idx)}') + sig_parts.append('int batch_size') + line = line.replace('// vitis-unified-wrapper-compute-signature', ', '.join(sig_parts)) + elif '// vitis-unified-wrapper-compute-body' in line: + pool_list = [self._get_local_stream_name(inp, True, idx) for idx, inp in enumerate(inputs)] + pool_list.extend([self._get_local_stream_name(out, False, idx) for idx, out in enumerate(outputs)]) + joined_io = ', '.join(pool_list) + # Template already provides for-loop body indent; only add the call + line = line.replace( + '// vitis-unified-wrapper-compute-body', f'{self._get_project_name(model)}({joined_io});' + ) + elif '// vitis-unified-wrapper-compute-call-args' in line: + pool_list = [self._get_local_stream_name(inp, True, idx) for idx, inp in enumerate(inputs)] + pool_list.extend([self._get_local_stream_name(out, False, idx) for idx, out in enumerate(outputs)]) + pool_list.append('batch_size') + joined_args = ', '.join(pool_list) + line = line.replace('// vitis-unified-wrapper-compute-call-args', joined_args) + elif '// vitis-unified-wrapper-store' in line: + line = '' + for output_idx, out in enumerate(outputs): + line += ( + f'{indent}store_result({self._get_io_port_name(out, False, output_idx)}, ' + f'{self._get_local_stream_name(out, False, output_idx)}, batch_size, {out.size()});\n' + ) + fout.write(line) + + with ( + open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi_master.h')) as fin, + open(f'{model.config.get_output_dir()}/firmware/{self._get_wrapper_file_name(model, True)}.h', 'w') as fout, + ): + for line in fin.readlines(): + if 'FILENAME' in line: + line = line.replace('FILENAME', self._get_wrapper_file_name(model, True).upper()) + elif 'MY_PROJECT_INC.h' in line: + line = line.replace('MY_PROJECT_INC', self._get_project_name(model)) + elif 'MY_PROJECT_TOP_FUNC' in line: + line = line.replace('MY_PROJECT_TOP_FUNC', self._get_top_wrap_func_name(model, True)) + elif '// vitis-unified-wrapper-io' in line: + line += self._gen_io_signature(indent, inp_gmem_t, out_gmem_t, inputs, outputs) + '\n' + fout.write(line) + + # ===== Driver generation ===== + def write_driver(self, model): + # write the ip driver + if self._is_axi_master(): + self._write_driver_axi_master(model) + else: + self._write_driver_axi_stream(model) + + def _write_driver_axi_stream(self, model): + driver_template_path = self.vitis_unified_config.get_driver_template_path() + driver_file = self.vitis_unified_config.get_driver_file() + with ( + open(driver_template_path) as fin, + open(f'{model.config.get_output_dir()}/export/{driver_file}', 'w') as fout, + ): + for line in fin.readlines(): + if '' in line: + line = line.replace('', self._get_wrap_ip_name(model, False)) + if '' in line: + line = line.replace('', self._get_top_wrap_func_name(model, False)) + fout.write(line) + + def _write_driver_axi_master(self, model): + driver_template_path = self.vitis_unified_config.get_driver_template_path() + driver_file = self.vitis_unified_config.get_driver_file() + with ( + open(driver_template_path) as fin, + open(f'{model.config.get_output_dir()}/export/{driver_file}', 'w') as fout, + ): + _, _, inputs, outputs = self.vitis_unified_config.get_corrected_types() + stride_in_ptr_addr = 4 * 3 + stride_out_ptr_addr = 4 * 3 + start_in_ptr_addr = 0x10 + start_out_ptr_addr = start_in_ptr_addr + stride_in_ptr_addr * len(inputs) + start_batch_size_addr = start_out_ptr_addr + stride_out_ptr_addr * len(outputs) + indent = ' ' * 12 + + for line in fin.readlines(): + if 'REG_ADDR_BATCH_SIZE' in line: + line = line.replace('VAL', str(hex(start_batch_size_addr))) + if '# hls-driver-input-dbg-name' in line: + names = [f'{indent}"{self._get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inputs)] + line += ',\n'.join(names) + '\n' + if '# hls-driver-input-ptr' in line: + line += ( + ',\n'.join(self._gen_hex_addr_list(start_in_ptr_addr, stride_in_ptr_addr, len(inputs), indent)) + + '\n' + ) + if '# hls-driver-output-dbg-name' in line: + names = [f'{indent}"{self._get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outputs)] + line += ',\n'.join(names) + '\n' + if '# hls-driver-output-ptr' in line: + line += ( + ',\n'.join(self._gen_hex_addr_list(start_out_ptr_addr, stride_out_ptr_addr, len(outputs), indent)) + + '\n' + ) + if '' in line: + line = line.replace('', self._get_wrap_ip_name(model, True)) + if '' in line: + line = line.replace('', self._get_top_wrap_func_name(model, True)) + fout.write(line) + + # ===== Test generation ===== + def write_wrapper_test(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + with ( + open(os.path.join(filedir, '../templates/vitis_unified/myproject_test.cpp')) as fin, + open(f'{model.config.get_output_dir()}/{self._get_sim_file_name()}.cpp', 'w') as fout, + ): + _, _, _, _ = self.vitis_unified_config.get_corrected_types() + model_inputs = model.get_input_variables() + model_outputs = model.get_output_variables() + model_brams = [var for var in model.get_weight_variables() if var.storage.lower() == 'bram'] + + fout.write('//// generated by Vitis Unified Backend\n') + + for line in fin.readlines(): + indent = ' ' * (len(line) - len(line.lstrip(' '))) + + if 'myproject' in line: + newline = line.replace('myproject', self._get_project_name(model)) + elif '// hls-fpga-machine-learning insert include' in line: + newline = line + f'#include "firmware/{self._get_wrapper_file_name(model, self._is_axi_master())}.h"\n' + elif '// hls-fpga-machine-learning insert bram' in line: + newline = line + for bram in model_brams: + newline += f'#include "firmware/weights/{bram.name}.h"\n' + elif '// hls-fpga-machine-learning insert data' in line: + newline = line + if self._is_axi_master(): + offset = 0 + for input_idx, inp in enumerate(model_inputs): + newline += indent + 'float* {input_port_name} = &in[{start_idx}];\n'.format( + input_port_name=self._get_io_port_name(inp, True, input_idx), start_idx=str(offset) + ) + offset += inp.size() + for output_idx, out in enumerate(model_outputs): + newline += indent + f'float {self._get_io_port_name(out, False, output_idx)}[{out.size()}];\n' + else: + assert len(model_inputs) == 1, 'Only support one input for axi stream' + assert len(model_outputs) == 1, 'Only support one output for axi stream' + newline += 3 * indent + f'hls::stream<{self._get_dma_type_name()}> inputs;\n' + newline += 3 * indent + 'nnet::convert_data_axis(in, inputs);\n' + newline += 3 * indent + 'std::cout << "input size inputs: " << inputs.size() << std::endl;\n' + newline += 3 * indent + f'hls::stream<{self._get_dma_type_name()}> outputs;\n\n' + elif '// hls-fpga-machine-learning insert top-level-function' in line: + newline = line + input_ios = [] + output_ios = [] + bram_ios = [b.name for b in model_brams] + constant_ios = [] + + if self._is_axi_master(): + input_ios.extend(self._get_io_port_name(inp, True, idx) for idx, inp in enumerate(model_inputs)) + output_ios.extend(self._get_io_port_name(out, False, idx) for idx, out in enumerate(model_outputs)) + constant_ios.append('1') + else: + input_ios.append('inputs') + output_ios.append('outputs') + constant_ios.append('1') + + all_vars = ' ,'.join(filter(None, [*input_ios, *output_ios, *bram_ios, *constant_ios])) + top_level = indent + f'{self._get_top_wrap_func_name(model, self._is_axi_master())}({all_vars});\n' + newline += top_level + elif '// hls-fpga-machine-learning insert predictions' in line: + newline = line + for out in model_outputs: + newline += indent + f'for(int i = 0; i < {out.size()}; i++) {{\n' + newline += indent + ' std::cout << pr[i] << " ";\n' + newline += indent + '}\n' + newline += indent + 'std::cout << std::endl;\n' + elif '// hls-fpga-machine-learning insert zero' in line: + newline = line + if self._is_axi_master(): + for input_idx, inp in enumerate(model_inputs): + newline += ( + indent + f'float {self._get_io_port_name(inp, True, input_idx)}[{inp.size()}] = {{}};\n' + ) + for output_idx, out in enumerate(model_outputs): + newline += ( + indent + f'float {self._get_io_port_name(out, False, output_idx)}[{out.size()}] = {{}};\n' + ) + else: + newline += 3 * indent + f'hls::stream<{self._get_dma_type_name()}> inputs;\n' + newline += 3 * indent + f'nnet::fill_zero_axi<{self._get_dma_type_name()}, N_IN>(inputs, false);\n' + newline += 3 * indent + 'std::cout << "input size inputs: " << inputs.size() << std::endl;\n' + newline += 3 * indent + f'hls::stream<{self._get_dma_type_name()}> outputs;\n\n' + elif '// hls-fpga-machine-learning insert tb-output' in line: + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + if tb_stream != 'stdout': + if self._is_axi_master(): + for output_idx, out in enumerate(model_outputs): + newline += indent + ( + 'nnet::print_result<{actual_type}, {copy_size}>({port_name}, {dest}, {keep_output});\n' + ).format( + actual_type='float', + copy_size=out.size(), + port_name=self._get_io_port_name(out, False, output_idx), + dest='fout', + keep_output='false', + ) + else: + newline += ( + indent + + f'nnet::print_result_axis<{self._get_dma_type_name()}, N_OUT>(outputs, fout, false);\n' + ) + elif ('// hls-fpga-machine-learning insert output' in line) or ( + '// hls-fpga-machine-learning insert quantized' in line + ): + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + keep_output = str(tb_stream != 'stdout').lower() + if tb_stream != 'file': + if self._is_axi_master(): + for output_idx, out in enumerate(model_outputs): + newline += indent + ( + 'nnet::print_result<{actual_type}, {copy_size}>({port_name}, {dest}, {keep_output});\n' + ).format( + actual_type='float', + copy_size=out.size(), + port_name=self._get_io_port_name(out, False, output_idx), + dest='std::cout', + keep_output=keep_output, + ) + else: + newline += indent + ( + f'nnet::print_result_axis<{self._get_dma_type_name()}, N_OUT>(' + f'outputs, std::cout, {keep_output});\n' + ) + elif '// hls-fpga-machine-learning insert namespace' in line: + newline = '' + namespace = model.config.get_writer_config().get('Namespace', None) + if namespace is not None: + newline += indent + f'using namespace {namespace};\n' + else: + newline = line + + fout.write(newline) + + # ===== Main entrypoint ===== + def write_hls(self, model, is_multigraph=False): + if is_multigraph: + raise Exception('Vitis Unified does not support multigraphs.') + + self._set_unified_config(model) + super().write_hls(model, is_multigraph=False) + self.write_wrapper(model) + self._ensure_export_path(model) + self.write_driver(model) + self.write_wrapper_test(model) + self.write_tar(model) diff --git a/hls4ml/writer/vitis_writer.py b/hls4ml/writer/vitis_writer.py index 505e87b6e9..fc221cc1fc 100644 --- a/hls4ml/writer/vitis_writer.py +++ b/hls4ml/writer/vitis_writer.py @@ -64,11 +64,14 @@ def write_build_prj_override(self, model): dstpath = f'{model.config.get_output_dir()}/build_prj.tcl' copyfile(srcpath, dstpath) - def write_hls(self, model): + def write_hls(self, model, is_multigraph=False): """ Write the HLS project. Calls the steps from VivadoWriter, adapted for Vitis """ - super().write_hls(model) + if is_multigraph: + super().write_hls(model, is_multigraph=True) + return + super().write_hls(model, is_multigraph=False) self.write_nnet_utils_overrides(model) self.write_board_script_override(model) self.write_build_prj_override(model) diff --git a/test/pytest/test_vitis_unified.py b/test/pytest/test_vitis_unified.py new file mode 100644 index 0000000000..952e452003 --- /dev/null +++ b/test/pytest/test_vitis_unified.py @@ -0,0 +1,265 @@ +import os +from pathlib import Path + +import numpy as np +import pytest +from tensorflow.keras.layers import ( + Concatenate, + Conv2D, + Input, + MaxPooling2D, + UpSampling2D, +) +from tensorflow.keras.models import Model + +import hls4ml + +test_root_path = Path(__file__).parent +# 1. For who installed the xilinx tool chain in /opt +# os.environ['XILINX_VITIS'] = '/opt/Xilinx/Vitis/2023.2' + +# 2. For who installed the xilinx tool chain in /tools (both vitis and vivado are mandatory) +os.environ['XILINX_VITIS'] = '/tools/Xilinx/Vitis/2023.2' +os.environ['XILINX_VIVADO'] = '/tools/Xilinx/Vivado/2023.2' + +os.environ['PATH'] = os.environ['XILINX_VITIS'] + '/bin:' + os.environ['XILINX_VIVADO'] + '/bin:' + os.environ['PATH'] + + +@pytest.fixture(scope='module') +def simple_unet(): + """Simple U-Net model for Vitis Unified tests.""" + inputs = Input((4, 4, 1)) + c1 = Conv2D(2, (3, 3), activation='relu', padding='same')(inputs) + p1 = MaxPooling2D((2, 2))(c1) + bn = Conv2D(4, (3, 3), activation='relu', padding='same')(p1) + u1 = UpSampling2D((2, 2))(bn) + concat1 = Concatenate()([u1, c1]) + c2 = Conv2D(2, (3, 3), activation='relu', padding='same')(concat1) + outputs = Conv2D(1, (1, 1), activation='sigmoid')(c2) + model = Model(inputs, outputs) + model.compile(optimizer='adam', loss='binary_crossentropy') + return model + + +part_map = {'zcu102': 'xczu9eg-ffvb1156-2-e', 'kv260': 'xck26-sfvc784-2LV-c'} + + +def _vitis_unified_convert_kwargs(io_type, axi_mode, board='zcu102', **extra): + """Shared backend kwargs for VitisUnified conversion. + Platform is resolved from supported_boards.json by board + axi_mode. + """ + part = part_map[board] + return { + 'backend': 'VitisUnified', + 'io_type': io_type, + 'board': board, + 'part': part, + 'clock_period': '10ns', + 'input_type': 'float', + 'output_type': 'float', + 'axi_mode': axi_mode, + **extra, + } + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('batch_size', [10]) +@pytest.mark.parametrize('axi_mode', ['axi_stream', 'axi_master']) +def test_backend_predict(test_case_id, simple_unet, io_type, strategy, granularity, batch_size, axi_mode): + model = simple_unet + X_input = np.random.rand(batch_size, 4, 4, 1).astype(np.float32) + + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + config['Model']['Strategy'] = strategy + output_dir_unified = str(test_root_path / test_case_id) + output_dir_vitis = str(test_root_path / (test_case_id + '_vitis_ref')) + + vitis_unified_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir_unified, + **_vitis_unified_convert_kwargs(io_type, axi_mode), + ) + vitis_unified_model.compile() + vitis_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir_vitis, + backend='Vitis', + io_type=io_type, + part='xczu9eg-ffvb1156-2-e', + clock_period='10ns', + ) + vitis_model.compile() + + hls_unified_prediction = vitis_unified_model.predict(X_input) + hls_vitis_prediction = vitis_model.predict(X_input) + + np.testing.assert_array_equal(hls_unified_prediction, hls_vitis_prediction) + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('batch_size', [10]) +@pytest.mark.parametrize('axi_mode', ['axi_stream', 'axi_master']) +def test_cosimulation(test_case_id, simple_unet, tmp_path, io_type, strategy, granularity, batch_size, axi_mode): + model = simple_unet + X_input = np.random.rand(batch_size, 4, 4, 1).astype(np.float32) + np.save(tmp_path / 'input.npy', X_input) + + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + config['Model']['Strategy'] = strategy + output_dir = str(test_root_path / test_case_id) + + vitis_unified_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode), + ) + vitis_unified_model.compile() + y_pred = vitis_unified_model.predict(X_input) + np.save(tmp_path / 'output.npy', y_pred) + + input_data_tb = str(tmp_path / 'input.npy') + output_data_tb = str(tmp_path / 'output.npy') + + vitis_unified_model_cosim = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode, input_data_tb=input_data_tb, output_data_tb=output_data_tb), + ) + vitis_unified_model_cosim.compile() + vitis_unified_model_cosim.build(synth=True, cosim=True, log_to_stdout=True) + + bridge_result = np.loadtxt(os.path.join(output_dir, 'tb_data', 'tb_output_predictions.dat')) + cosim_result = np.loadtxt(os.path.join(output_dir, 'tb_data', 'rtl_cosim_results.log')) + assert np.allclose(bridge_result, cosim_result, rtol=0.0, atol=1e-4) + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('batch_size', [10]) +@pytest.mark.parametrize('axi_mode', ['axi_stream', 'axi_master']) +def test_csim_simulation(test_case_id, simple_unet, tmp_path, io_type, strategy, granularity, batch_size, axi_mode): + model = simple_unet + X_input = np.random.rand(batch_size, 4, 4, 1).astype(np.float32) + np.save(tmp_path / 'input.npy', X_input) + + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + config['Model']['Strategy'] = strategy + output_dir = str(test_root_path / test_case_id) + + vitis_unified_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode), + ) + vitis_unified_model.compile() + y_pred = vitis_unified_model.predict(X_input) + np.save(tmp_path / 'output.npy', y_pred) + + input_data_tb = str(tmp_path / 'input.npy') + output_data_tb = str(tmp_path / 'output.npy') + + vitis_unified_model_csim = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode, input_data_tb=input_data_tb, output_data_tb=output_data_tb), + ) + vitis_unified_model_csim.compile() + vitis_unified_model_csim.build(synth=True, csim=True, log_to_stdout=True) + + bridge_result = np.loadtxt(os.path.join(output_dir, 'tb_data', 'tb_output_predictions.dat')) + csim_result = np.loadtxt(os.path.join(output_dir, 'tb_data', 'csim_results.log')) + assert np.allclose(bridge_result, csim_result, rtol=0.0, atol=1e-4) + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('batch_size', [10]) +@pytest.mark.parametrize('axi_mode', ['axi_stream', 'axi_master']) +def test_fifo_depth(test_case_id, simple_unet, tmp_path, io_type, strategy, granularity, batch_size, axi_mode): + model = simple_unet + X_input = np.random.rand(batch_size, 4, 4, 1).astype(np.float32) + np.save(tmp_path / 'input.npy', X_input) + + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + config['Model']['Strategy'] = strategy + config['Flows'] = ['vitisunified:fifo_depth_optimization'] + output_dir = str(test_root_path / test_case_id) + + vitis_unified_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode), + ) + vitis_unified_model.compile() + y_pred = vitis_unified_model.predict(X_input) + np.save(tmp_path / 'output.npy', y_pred) + + input_data_tb = str(tmp_path / 'input.npy') + output_data_tb = str(tmp_path / 'output.npy') + + vitis_unified_model_fifo = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode, input_data_tb=input_data_tb, output_data_tb=output_data_tb), + ) + vitis_unified_model_fifo.compile() + + fifodepth_result_path = os.path.join(output_dir, 'fifo_depths.json') + assert os.path.exists(fifodepth_result_path) + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('batch_size', [10]) +@pytest.mark.parametrize('axi_mode', ['axi_stream', 'axi_master']) +# @pytest.mark.parametrize('board', ['zcu102', 'kv260']) +@pytest.mark.parametrize('board', ['kv260']) +def test_gen_unified(test_case_id, simple_unet, io_type, strategy, granularity, batch_size, axi_mode, board): + model = simple_unet + X_input = np.random.rand(batch_size, 4, 4, 1).astype(np.float32) + + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + config['Model']['Strategy'] = strategy + test_case_id = test_case_id + output_dir = str(test_root_path / test_case_id) + + vitis_unified_model = hls4ml.converters.convert_from_keras_model( + model, + hls_config=config, + output_dir=output_dir, + **_vitis_unified_convert_kwargs(io_type, axi_mode, board), + ) + vitis_unified_model.compile() + # predict and save for hardware comparison purpose + y_pred = vitis_unified_model.predict(X_input) + np.save(os.path.join(output_dir, 'x_input.npy'), X_input) + np.save(os.path.join(output_dir, 'y_pred_sw.npy'), y_pred) + vitis_unified_model.build(synth=True, bitfile=True, log_to_stdout=True) + + export_dir = os.path.join(output_dir, 'export') + driver_file = 'axi_stream_driver.py' if axi_mode == 'axi_stream' else 'axi_master_driver.py' + expected_files = {driver_file, 'system.bit', 'system.hwh'} + exported_files = set(os.listdir(export_dir)) + assert expected_files.issubset(exported_files), f'Missing files in export: {expected_files - exported_files}' + final_reports_dir = os.path.join(output_dir, 'final_reports') + assert os.path.isdir(final_reports_dir), f'final_reports directory does not exist: {final_reports_dir}' + rpt_files = [f for f in os.listdir(final_reports_dir) if f.endswith('.rpt')] + assert len(rpt_files) > 0, f'No .rpt files found in final_reports directory: {final_reports_dir}' + + +# test_gen_unified('axi_stream_debug_4', simple_unet(), 'io_stream', 'latency', 'name', 10, 'axi_stream', 'kv260')