From 392226044a6f2e93dc253b252a3611cba5e695f4 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 12 Jul 2025 09:12:54 +0200 Subject: [PATCH 01/70] add vitisUnified backend and its writer --- .gitignore | 3 + hls4ml/backends/__init__.py | 4 + hls4ml/backends/vitis_unified/__init__.py | 0 .../vitis_unified/supported_boards.json | 14 + .../vitis_unified/vitis_unified_backend.py | 227 ++++ .../vitis_unified/vitis_unified_config.py | 176 +++ hls4ml/writer/__init__.py | 2 + hls4ml/writer/vitis_unified_writer.py | 1027 +++++++++++++++++ 8 files changed, 1453 insertions(+) create mode 100644 hls4ml/backends/vitis_unified/__init__.py create mode 100644 hls4ml/backends/vitis_unified/supported_boards.json create mode 100644 hls4ml/backends/vitis_unified/vitis_unified_backend.py create mode 100644 hls4ml/backends/vitis_unified/vitis_unified_config.py create mode 100644 hls4ml/writer/vitis_unified_writer.py diff --git a/.gitignore b/.gitignore index 22c8ff685b..1f93c68d5d 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ docs/autodoc/* hls4mlprj_* *~ *.ipynb_checkpoints/ + +.idea/* +myTest/* \ No newline at end of file diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 4a48f072cd..08fca7fb39 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -11,9 +11,13 @@ from hls4ml.backends.vitis.vitis_backend import VitisBackend # isort: skip +from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend +from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig + 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/__init__.py b/hls4ml/backends/vitis_unified/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/backends/vitis_unified/supported_boards.json b/hls4ml/backends/vitis_unified/supported_boards.json new file mode 100644 index 0000000000..4a54ea2924 --- /dev/null +++ b/hls4ml/backends/vitis_unified/supported_boards.json @@ -0,0 +1,14 @@ +{ + "pynq-z2": { + "part": "xc7z020clg400-1", + "tcl_scripts": {"axi_lite": "axi_lite_design.tcl", "axi_stream": "axi_stream_design.tcl"}, + "python_drivers": {"axi_stream": "axi_stream_driver.py"}, + "c_drivers": {} + }, + "zcu102": { + "part": "xczu9eg-ffvb1156-2-e", + "tcl_scripts": { "axi_stream": "axi_stream_design.tcl"}, + "python_drivers": {"axi_stream": "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..b55d873e29 --- /dev/null +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -0,0 +1,227 @@ +import os +import sys +import subprocess + + +from hls4ml.backends import VitisBackend, VivadoBackend +from hls4ml.model.flow import register_flow +from hls4ml.report import parse_vivado_report + + +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=True, + synth=True, + cosim=False, + validation=False, + export=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 vitis > /dev/null') + if found != 0: + raise Exception('Vitis installation not found. Make sure "vitis" is on PATH.') + + # build_command = ( + # 'vitis -f build_prj.tcl "reset={reset} csim={csim} synth={synth} cosim={cosim} ' + # 'validation={validation} export={export} vsynth={vsynth} fifo_opt={fifo_opt}"' + # ).format( + # reset=reset, + # csim=csim, + # synth=synth, + # cosim=cosim, + # validation=validation, + # export=export, + # vsynth=vsynth, + # fifo_opt=fifo_opt, + # ) + + output_dir = model.config.get_output_dir() + ##### build working directory + if not os.path.exists(os.path.join(output_dir,"unifiedPrj")): + os.makedirs(os.path.join(output_dir, "unifiedPrj")) + + + ##### build command + build_command = ( + "v++ -c --mode hls --config {configPath} --work_dir unifiedPrj" + ).format(configPath=(os.path.join(output_dir, "hls_config.cfg"))) + + stdout_log = os.path.join(output_dir, 'build_stdout.log') + stderr_log = os.path.join(output_dir, 'build_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') + + ##### util template (used in csim/cosim/package) + util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" + + + ##### package command + + package_command = util_command.format(op="package", configPath=os.path.join(output_dir, "hls_config.cfg")) + pk_out_log_path = os.path.join(output_dir, 'package_out.log') + pk_err_log_path = os.path.join(output_dir, 'package_err.log') + pk_out_target = None if log_to_stdout else open(pk_out_log_path, 'w') + pk_err_target = None if log_to_stdout else open(pk_err_log_path, 'w') + + ##### co-sim command + + cosim_command = util_command.format(op="cosim", configPath=os.path.join(output_dir, "hls_config_cosim.cfg")) + #cosim_command += ' --flag "RTL_SIM"' + cos_out_log_path = os.path.join(output_dir, 'cosim_out.log') + cos_err_log_path = os.path.join(output_dir, 'cosim_err.log') + cos_out_target = None if log_to_stdout or (not cosim) else open(cos_out_log_path, 'w') + cos_err_target = None if log_to_stdout or (not cosim) else open(cos_err_log_path, 'w') + + ##### c-sim command + + csim_command = util_command.format(op="csim", configPath=os.path.join(output_dir, "hls_config_csim.cfg")) + # cosim_command += ' --flag "RTL_SIM"' + cs_out_log_path = os.path.join(output_dir, 'csim_out.log') + cs_err_log_path = os.path.join(output_dir, 'csim_err.log') + cs_out_target = None if log_to_stdout or (not csim) else open(cs_out_log_path, 'w') + cs_err_target = None if log_to_stdout or (not csim) else open(cs_err_log_path, 'w') + + try: + if synth: + print("---------------------------------------------------") + print("----------- start build command ---------------") + print("---------------------------------------------------") + ##### run build project + process = subprocess.Popen( + build_command, shell=True, cwd=output_dir, 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()}. See logs for details.') + ##### run package project + print("---------------------------------------------------") + print("----------- start package command ---------------") + print("---------------------------------------------------") + + packageProcess = subprocess.Popen( + package_command, shell=True, cwd=output_dir, stdout=pk_out_target, stderr=pk_err_target, text=True + ) + packageProcess.communicate() + if packageProcess.returncode != 0: + raise Exception(f'Package failed for {model.config.get_project_name()}. See logs for details.') + + if cosim: + print("---------------------------------------------------") + print("----------- start cosim command ---------------") + print("---------------------------------------------------") + cosimProcess = subprocess.Popen( + cosim_command, shell=True, cwd=output_dir, stdout=cos_out_target, stderr=cos_err_target, text=True + ) + cosimProcess.communicate() + if cosimProcess.returncode != 0: + raise Exception(f'Cosim failed for {model.config.get_project_name()}. See logs for details.') + + if csim: + print("---------------------------------------------------") + print("----------- start csim command ---------------") + print("---------------------------------------------------") + csimProcess = subprocess.Popen( + csim_command, shell=True, cwd=output_dir, stdout=cs_out_target, stderr=cs_err_target, text=True + ) + csimProcess.communicate() + if csimProcess.returncode != 0: + raise Exception(f'Csim failed for {model.config.get_project_name()}. See logs for details.') + + + + + finally: + if not log_to_stdout: + if synth: + stdout_target.close() + stderr_target.close() + pk_out_target.close() + pk_err_target.close() + + if cosim: + cos_out_target.close() + cos_err_target.close() + + if csim: + cs_out_target.close() + cs_err_target.close() + + # now make a bitfile + if bitfile: + curr_dir = os.getcwd() + os.chdir(model.config.get_output_dir()) + try: + os.system('vivado -mode batch -source design.tcl') # check if this is accepted as a command + except Exception: + print("Something went wrong, check the Vivado logs") + os.chdir(curr_dir) + + return parse_vivado_report(model.config.get_output_dir()) + + def create_initial_config( + self, + board='pynq-z2', + part=None, + clock_period=5, + clock_uncertainty='12.5%', + io_type='io_parallel', + interface='axi_stream', + driver='python', + input_type='float', + output_type='float', + input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream + output_interim_type='io_stream' + ): + board = board if board is not None else 'pynq-z2' + + if input_interim_type not in ['io_free_stream', 'io_stream']: + raise Exception(f'input_interim_type should be io_free_stream or io_stream, but got {input_interim_type}') + if output_interim_type not in ['io_free_stream', 'io_stream']: + raise Exception(f'output_interim_type should be io_free_stream or io_stream, but got {output_interim_type}') + + config = super().create_initial_config(part, clock_period, clock_uncertainty, io_type) + config['AcceleratorConfig'] = {} + config['AcceleratorConfig']['Board'] = board + config['AcceleratorConfig']['Interface'] = interface # axi_stream, axi_master, axi_lite + config['AcceleratorConfig']['Driver'] = driver + config['AcceleratorConfig']['Precision'] = {} + config['AcceleratorConfig']['Precision']['Input'] = {} + config['AcceleratorConfig']['Precision']['Output'] = {} + config['AcceleratorConfig']['Precision']['Input'] = input_type # float, double or ap_fixed + config['AcceleratorConfig']['Precision']['Output'] = output_type # float, double or ap_fixed + + config['MultiGraphConfig'] = {} + config['MultiGraphConfig']['IOInterimType'] = {} + config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type + config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type + + 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 + 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..f478b65209 --- /dev/null +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -0,0 +1,176 @@ +import json +import os + +import numpy as np + +from hls4ml.model.layers import FixedPrecisionType, IntegerPrecisionType + +class VitisUnifiedConfig: + def __init__(self, config, model_inputs, model_outputs): + self.config = config.config + self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') + self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) + self.freeInterimInput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Input") == "io_free_stream" + self.freeInterimOutput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Output") == "io_free_stream" + if self.board in self.supported_boards.keys(): + board_info = self.supported_boards[self.board] + self.part = board_info['part'] + else: + raise Exception('The board does not appear in supported_boards.json file') + + if self.config.get('Part') is not None: + if self.config.get('Part') != self.part: + print( + 'WARNING: You set a Part that does not correspond to the Board you specified. The correct ' + 'Part is now set.' + ) + self.config['Part'] = self.part + accel_config = self.config.get('AcceleratorConfig', None) + if accel_config is not None: + prec = accel_config.get('Precision') + if prec is None: + raise Exception('Precision must be provided in the AcceleratorConfig') + else: + if prec.get('Input') is None or prec.get('Output') is None: + raise Exception('Input and Output fields must be provided in the AcceleratorConfig->Precision') + else: + accel_config = { + 'Precision': {'Input': 'float', 'Output': 'float'}, + 'Driver': 'python', + 'Interface': 'axi_stream', + } + config.config['AcceleratorConfig'] = accel_config + + self.interface = self.config['AcceleratorConfig'].get('Interface', 'axi_stream') # axi_stream, axi_master, axi_lite + self.driver = self.config['AcceleratorConfig'].get('Driver', 'python') # python or c + self.input_type = self.config['AcceleratorConfig']['Precision'].get( + 'Input', 'float' + ) # float, double or ap_fixed + self.output_type = self.config['AcceleratorConfig']['Precision'].get( + 'Output', 'float' + ) # float, double or ap_fixed + self.platform = self.config['AcceleratorConfig'].get( + 'Platform', 'xilinx_u250_xdma_201830_2' + ) # Get platform folder name + + assert ( + len(model_inputs) >= 1 + ), "Only models with at least one input tensor are currently supported by VitisAcceleratorIPFlowPartialBackend" + assert ( + len(model_outputs) >= 1 + ), "Only models with one output tensor are currently supported by VitisAcceleratorIPFlowPartialBackend" + self.inps = model_inputs.copy() + self.outs = model_outputs.copy() + inp_axi_t = self.input_type + out_axi_t = self.output_type + + if inp_axi_t not in ['float', 'double']: + self.input_type = self._next_factor8_type(config.backend.convert_precision_string(inp_axi_t)) + if out_axi_t not in ['float', 'double']: + self.output_type = self._next_factor8_type(config.backend.convert_precision_string(out_axi_t)) + + if self.input_type == 'float': + self.input_bitwidth = 32 + elif self.input_type == 'double': + self.input_bitwidth = 64 + else: + self.input_bitwidth = config.backend.convert_precision_string(inp_axi_t).width + + if out_axi_t == 'float': + self.output_bitwidth = 32 + elif out_axi_t == 'double': + self.output_bitwidth = 64 + else: + self.output_bitwidth = config.backend.convert_precision_string(out_axi_t).width + + def _next_factor8_type(self, p): + '''Return a new type with the width rounded to the next factor of 8 up to p's width + Args: + p : IntegerPrecisionType or FixedPrecisionType + Returns: + An IntegerPrecisionType or FixedPrecisionType with the width rounder up to the next factor of 8 + of p's width. Other parameters (fractional bits, extra modes) stay the same. + ''' + W = p.width + newW = int(np.ceil(W / 8) * 8) + if isinstance(p, FixedPrecisionType): + return FixedPrecisionType(newW, p.integer, p.signed, p.rounding_mode, p.saturation_mode, p.saturation_bits) + elif isinstance(p, IntegerPrecisionType): + return IntegerPrecisionType(newW, p.signed) + + def get_io_bitwidth(self): + return self.input_bitwidth, self.output_bitwidth + + def get_corrected_types(self): + return self.input_type, self.output_type, self.inps, self.outs + + def get_interface(self): + return self.interface + + def get_board_info(self, board=None): + if board is None: + board = self.board + if board in self.supported_boards.keys(): + return self.supported_boards[board] + else: + raise Exception('The board is still not supported') + + def get_part(self): + return self.part + + def get_driver(self): + return self.driver + + def get_board(self): + return self.board + + def get_platform(self): + return self.platform + + def get_clock_period(self): + return self.clock_period + + def get_driver_path(self): + if self.board.startswith('alveo'): + return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + self.driver + '_drivers/' + self.get_driver_file() + else: + return ( + '../templates/vitis_accelerator_ip_flow/' + + self.board + + '/' + + self.driver + + '_drivers/' + + self.get_driver_file() + ) + + def get_driver_file(self): + driver_ext = '.py' if self.driver == 'python' else '.h' + return self.interface + '_driver' + driver_ext + + def get_krnl_rtl_src_dir(self): + return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + '/krnl_rtl_src' + + def get_input_type(self): + return self.input_type + + def get_output_type(self): + return self.output_type + + def isFreeInterimInput(self): + return self.freeInterimInput + + def isFreeInterimOutput(self): + return self.freeInterimOutput + + def get_tcl_file_path(self): + board_info = self.get_board_info(self.board) + tcl_scripts = board_info.get('tcl_scripts', None) + if tcl_scripts is None: + raise Exception('No tcl scripts definition available for the board in supported_board.json') + tcl_script = tcl_scripts.get(self.interface, None) + if tcl_script is None: + raise Exception('No tcl script definition available for the desired interface in supported_board.json') + if self.board.startswith('alveo'): + return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + '/tcl_scripts/' + tcl_script + else: + return '../templates/vitis_accelerator_ip_flow/' + self.board + '/tcl_scripts/' + tcl_script \ No newline at end of file diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 8de19fe1d2..48897ce1a7 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -3,6 +3,7 @@ from hls4ml.writer.quartus_writer import QuartusWriter from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter from hls4ml.writer.vitis_writer import VitisWriter +from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter from hls4ml.writer.vivado_accelerator_writer import VivadoAcceleratorWriter from hls4ml.writer.vivado_writer import VivadoWriter from hls4ml.writer.writers import Writer, get_writer, register_writer # noqa: F401 @@ -10,6 +11,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..71c67ad9fa --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer.py @@ -0,0 +1,1027 @@ +import os +from pathlib import Path +import stat + +from shutil import copyfile + +from hls4ml.writer.vitis_writer import VitisWriter + +class VitisUnifiedWriter(VitisWriter): + + def __init__(self): + super().__init__() + self.vitis_unified_config = None + + ####################################################### + ## naming of variable function helper ################# + ####################################################### + + def getDmaTypeName(self): + return "dma_data_packet" + + def getWrapperPortName(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}" + + def getTopModelName(self, model): + return f"{model.config.get_project_name()}_axi" + ### it is renamed for stitch layer + def renameType(self, tensorVar, layerIdx:int, isInput: bool): + return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" + + def get_inputSizeArrName(self, model): + return "N_IN_" + model.config.get_project_name() + + def get_outputSizeArrName(self, model): + return "N_OUT_" + model.config.get_project_name() + + def get_axi_wrapper_type(self, tensorVar): + return f"{tensorVar.type.name}_packet" + + def get_axi_wrapper_dec(self, tensorVar): + return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" + + + ######################################################## + ## axi_wrapper.h & axi_wrapper.cpp function helper #### + ######################################################## + ##### variable + def getWrapperPortNameLocal(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_local" + + def getWrapperTmpName(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_tmp" + + def getWrapperIsLastCnt(self, idx): + return f"isLastCnt_{str(idx)}" + ##### io + def write_axi_wrapper_io(self, inps, outs): + inputList = [] + outputList = [] + for inp in inps: + streamType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else "dma_data_packet" + inputList.append(f'hls::stream<{streamType}>& {self.getWrapperPortName(inp, True)}') + for out in outs: + streamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else "dma_data_packet" + outputList.append(f'hls::stream<{streamType}> & {self.getWrapperPortName(out, False)}') + + if len(inputList) == 0 or len(outputList) == 0: + raise Exception("No input or output stream found") + newline = "/////// inputs\n" + ",\n ".join(inputList) + ",\n\n ///outputs\n " + ", ".join(outputList) + "\n" + return newline + ##### content in axi_wrapper.cpp + def write_axi_wrapper_interface(self, model, inps, outs): + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline = '' + indent = " " + for inp in inps: + portname = self.getWrapperPortName(inp, True) + newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' + for out in outs: + portname = self.getWrapperPortName(out, False) + newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' + if model.config.get_config_value("IOType") == 'io_stream': + newline += indent + '#pragma HLS INTERFACE ap_ctrl_none port=return\n' + newline += indent + '#pragma HLS DATAFLOW\n' + return newline + else: + raise Exception("vitis_unified supports only axi_stream @ interface retriever") + + def write_axi_local_vars(self, model, inps, outs): + + ####### build local stream variable + + newline = '///// wrinting local stream vars /////\n' + if self.vitis_unified_config.get_interface() == 'axi_stream': + indent = " " + ##### loop to build local stream to send data into the system + newline += '///////// build input vars ///////////\n' + for idx, inp in enumerate(inps): + newline += f" bool {self.getWrapperIsLastCnt(idx)} = false;\n" + portname = self.getWrapperPortNameLocal(inp, True) + newline += indent + f'hls::stream<{inp.type.name}> {portname}("{portname}");\n' + newline += '///////// build output vars ///////////\n' + for out in outs: + portname = self.getWrapperPortNameLocal(out, False) + newline += indent + f'hls::stream<{out.type.name}> {portname}("{portname}");\n' + + ####### set stream DEPTH + + newline += '///////// set the stream depth ///////////\n' + ##### loop to set depth + + for inpIdx, inp in enumerate(inps): + portname = self.getWrapperPortNameLocal(inp, True) + newline += indent + f'#pragma HLS STREAM variable={portname} depth={inps[inpIdx].pragma[1]}\n' + for outIdx, out in enumerate(outs): + portname = self.getWrapperPortNameLocal(out, False) + newline += indent + f'#pragma HLS STREAM variable={portname} depth={model.get_output_variables()[outIdx].pragma[1]}\n' + + else: + raise Exception("vitis_unified supports only axi_stream @ local vars") + + + return newline + + def write_axi_wrapper_each_enqueue(self, model, inps, idx): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'dma_data_packet {self.getWrapperTmpName(inps[idx], True)};\n' + newline += indent + f"{self.getWrapperTmpName(inps[idx], True)}.last = 0;\n" + ### newline += indent + f'{inps[idx].type.name}\n' + newline += indent + f'for(unsigned i = 0; i < {self.get_inputSizeArrName(model)}[' +str(idx) +']/' + inps[idx].type.name + '::size; ++i){\n' + newline += indent + indent + inps[idx].type.name + ' ctype;\n' + newline += indent + indent + 'for(unsigned j = 0; j < '+ inps[idx].type.name + '::size; ++j){\n' + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline += indent + indent + indent + self.getWrapperPortName(inps[idx], True) + f'.read({self.getWrapperTmpName(inps[idx], True)});\n' + newline += indent + indent + indent + "ctype[j] = " + self.getWrapperTmpName(inps[idx], True) + ".data;\n" + newline += indent + indent + indent + self.getWrapperIsLastCnt(idx) + " = " + self.getWrapperTmpName(inps[idx], True) + ".last;\n" + else: + raise Exception("vitis_unified supports only axi_stream @ each enqueue") + + newline += indent + indent + '}\n' + newline += indent + indent + self.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" + newline += indent + '}\n' + newline += indent + self.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" + + else: + raise Exception("vitis_unified supports only io_stream @ each enqueue") + + return newline + + def write_free_axi_wrapper_each_enqueue(self, model, inps, idx): + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'{self.get_axi_wrapper_type(inps[idx])} {self.getWrapperTmpName(inps[idx], True)};\n' + newline += indent + f"{self.getWrapperTmpName(inps[idx], True)}.last = 0;\n" + newline += indent + f'for(unsigned i = 0; i < {self.get_inputSizeArrName(model)}[' + str(idx) + ']/' + inps[ + idx].type.name + '::size; ++i){\n' + newline += indent + indent + inps[idx].type.name + ' ctype;\n' + newline += indent + indent + self.getWrapperPortName(inps[idx], True) + f'.read({self.getWrapperTmpName(inps[idx], True)});\n' + newline += indent + indent + "ctype = " + self.getWrapperTmpName(inps[idx], True) + ".data;\n" + newline += indent + indent + self.getWrapperIsLastCnt(idx) + " = " + self.getWrapperTmpName(inps[idx], True) + ".last;\n" + newline += indent + indent + self.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" + newline += indent + '}\n' + newline += indent + self.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" + else: + raise Exception("vitis_unified supports only io_stream @ each free axi enqueue") + + return newline + + def write_axi_wrapper_dequeue(self, model, inputs, outs, idx, out_axi_t): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'dma_data_packet {self.getWrapperTmpName(outs[idx], False)};\n' + newline += indent + f"{self.getWrapperTmpName(outs[idx], False)}.last = 0;\n" + ####### the tmp must copy from input to prevent dma get stuck + newline += indent + f'for(unsigned i = 0; i < {self.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' + newline += indent + indent + outs[idx].type.name + ' ctype = ' + self.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' + newline += indent + indent + 'for(unsigned j = 0; j < ' + outs[idx].type.name + '::size; ++j){\n' + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline += indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f'.data = ({out_axi_t}) (ctype[j]);\n' + poolLastCondition = " & ".join([self.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) + newline += indent + indent + indent + f"if({poolLastCondition}){{\n" + newline += indent + indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f".last = (((i+1)*(j+1))=={self.get_outputSizeArrName(model)}[{str(idx)}]);\n" + newline += indent + indent + indent + "}\n" + newline += indent + indent + indent + self.getWrapperPortName(outs[idx], False) + f'.write({self.getWrapperTmpName(outs[idx], False)});\n' + newline += indent + indent + "}\n" + newline += indent + "}\n" + newline += indent + self.getWrapperTmpName(outs[idx], False) + ".last = 0;\n" + else: + raise Exception("vitis_unified supports only axi_stream @ each dequeue") + else: + raise Exception("vitis_unified supports only io_stream @ each dequeue") + + return newline + + def write_free_axi_wrapper_dequeue(self, model, inputs, outs, idx, out_axi_t): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'{self.get_axi_wrapper_type(outs[idx])} {self.getWrapperTmpName(outs[idx], False)};\n' + newline += indent + f"{self.getWrapperTmpName(outs[idx], False)}.last = 0;\n" + ####### the tmp must copy from input to prevent dma get stuck + newline += indent + f'for(unsigned i = 0; i < {self.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' + newline += indent + indent + outs[idx].type.name + ' ctype = ' + self.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' + newline += indent + indent + self.getWrapperTmpName(outs[idx], False) + ".data = ctype;\n" + poolLastCondition = " & ".join([self.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) + newline += indent + indent + f"if({poolLastCondition}){{\n" + newline += indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f".last = ((i+1) == ({self.get_outputSizeArrName(model)}[{str(idx)}] / {outs[idx].type.name + '::size'} ));\n" + newline += indent + indent + "}\n" + newline += indent + indent + self.getWrapperPortName(outs[idx],False) + f'.write({self.getWrapperTmpName(outs[idx], False)});\n' + newline += indent + "}\n" + else: + raise Exception("vitis_unified supports only io_stream @ each dequeue") + + return newline + + def write_axi_wrapper_insert_call(self, model, inps, outs): + io_type = model.config.get_config_value("IOType") + indent = " " + newline = indent + f'{model.config.get_project_name()}' + "(" + inputList = [] + outputList = [] + for inp in inps: + inputList.append(self.getWrapperPortNameLocal(inp, True)) + for out in outs: + outputList.append(self.getWrapperPortNameLocal(out, False)) + newline += ", ".join(inputList) + ", " + ", ".join(outputList) + ");\n" + return newline + + ######################################################## + ##### main function #################################### + ######################################################## + + def write_axi_wrapper(self, model): + ''' + We we want to have multi io system + ''' + inp_axi_t, out_axi_t, inps, outs = self.vitis_unified_config.get_corrected_types() + indent = ' ' + + print("------------------------------- input write wrapper is -------------------------") + print([inp.name for inp in inps]) + print(model.inputs) + print("------------------------------- output write wrapper is -------------------------") + print([out.name for out in outs]) + print(model.outputs) + print("-----------------------------------------------------------------------------------") + + ###################### + # myproject_axi.h + ###################### + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi.h')) + fout = open(f'{model.config.get_output_dir()}/firmware/{model.config.get_project_name()}_axi.h', 'w') + + for line in f.readlines(): + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{model.config.get_project_name()}.h"\n' + newline += '#include "ap_axi_sdata.h"\n' + elif 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + elif '// hls-fpga-machine-learning insert definitions' in line: + + ##### make input + newline = '' + inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" + newline += f'constexpr unsigned {self.get_inputSizeArrName(model)} [{len(inps)}] = {inputSizeStr};\n' + + ##### make output + outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" + newline += f'constexpr unsigned {self.get_outputSizeArrName(model)} [{len(outs)}] = {outputSizeStr};\n' + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline += 'typedef hls::axis dma_data_packet;\n' + else: + newline += f'typedef {inp_axi_t} input_axi_t;\n' + newline += f'typedef {out_axi_t} output_axi_t;\n' + #### incase the io is interim input + if self.vitis_unified_config.isFreeInterimInput(): + for inp in inps: + newline += self.get_axi_wrapper_dec(inp) + "\n" + #### incase the io is interim output + if self.vitis_unified_config.isFreeInterimOutput(): + for out in outs: + newline += self.get_axi_wrapper_dec(out) + "\n" + elif '// hls-fpga-machine-learning insert multi-io' in line: + newline = '' + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline += self.write_axi_wrapper_io(inps, outs) + else: + raise Exception("vitis_unified supports only axi_stream") + + else: + newline = line + + #### TODO add stream + + fout.write(newline) + f.close() + fout.close() + + ###################### + # myproject_axi.cpp + ###################### + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi.cpp')) + fout = open(f'{model.config.get_output_dir()}/firmware/{model.config.get_project_name()}_axi.cpp', 'w') + + io_type = model.config.get_config_value("IOType") + + for line in f.readlines(): + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{model.config.get_project_name()}_axi.h"\n' + elif '// hls-fpga-machine-learning insert multiIo' in line: + newline = '' + if self.vitis_unified_config.get_interface() == 'axi_stream': + newline += self.write_axi_wrapper_io(inps, outs) + else: + raise Exception("vitis_unified supports only axi_stream") + elif '// hls-fpga-machine-learning insert interface' in line: + newline = self.write_axi_wrapper_interface(model, inps, outs) + elif '// hls-fpga-machine-learning insert local vars' in line: + newline = self.write_axi_local_vars(model, inps, outs) + elif '// hls-fpga-machine-learning insert enqueue' in line: + newline = '' + if self.vitis_unified_config.isFreeInterimInput(): + for idx, inp in enumerate(inps): + newline += self.write_free_axi_wrapper_each_enqueue(model, inps, idx) + '\n' + else: + for idx, inp in enumerate(inps): + newline += self.write_axi_wrapper_each_enqueue(model, inps, idx) + '\n' + elif '// hls-fpga-machine-learning insert call' in line: + newline = '////// call the main variable\n' + newline += self.write_axi_wrapper_insert_call(model, inps, outs) + elif '// hls-fpga-machine-learning insert dequeue' in line: + newline = '' + if self.vitis_unified_config.isFreeInterimOutput(): + for idx, out in enumerate(outs): + newline += self.write_free_axi_wrapper_dequeue(model, inps, outs, idx, out_axi_t) + else: + for idx, out in enumerate(outs): + newline += self.write_axi_wrapper_dequeue(model, inps, outs, idx, out_axi_t) + else: + newline = line + fout.write(newline) + f.close() + fout.close() + + ######################################################## + ## write test (for co simulation)/ and bridge file () script function helper ############### + ######################################################## + + def write_wrapper_test(self, model): + + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_test.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + + 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 partial backend\n") + + for line in f.readlines(): + indent = ' ' * (len(line) - len(line.lstrip(' '))) + + #Insert numbers + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + 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 + offset = 0 + for inputIdx, inp in enumerate(model_inputs): + streamPktType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else self.getDmaTypeName() + + newline += " hls::stream<{desType}> {inputPortName};\n".format( + desType = streamPktType, inputPortName = self.getWrapperPortName(inp, True) + ) + if self.vitis_unified_config.isFreeInterimInput(): + newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( + underlyType = inp.type.name, + wrapType=streamPktType, + offset=offset, + inputSize=str(inp.size()), + inputPortName=self.getWrapperPortName(inp, True) + ) + else: + newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( + destype = streamPktType, offset=offset, inputSize=str(inp.size()), + inputPortName=self.getWrapperPortName(inp, True) + ) + offset += inp.size() + for out in model_outputs: + streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() + newline += ' ' + f"hls::stream<{streamPktType}> {self.getWrapperPortName(out, False)};\n" + + elif '// hls-fpga-machine-learning insert top-level-function' in line: + newline = line + + input_vars = ','.join([self.getWrapperPortName(inp, True) for inp in model_inputs]) + output_vars = ','.join([self.getWrapperPortName(out, False) for out in model_outputs]) + bram_vars = ','.join([b.name for b in model_brams]) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) + + top_level = indent + f'{self.getTopModelName(model)}({all_vars});\n' + + newline += top_level + elif '// hls-fpga-machine-learning insert predictions' in line: + newline = line + for outIdx, out in enumerate(model_outputs): + #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + newline += indent + f'for(int i = 0; i < {self.get_outputSizeArrName(model)}[{outIdx}]; 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 tb-output' in line: + # newline = line + # tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + # if tb_stream != 'stdout': + # for outIdx, out in enumerate(model_outputs): + # # newline += indent + 'nnet::print_result<{}, {}>({}, fout);\n'.format( + # # out.type.name, out.size_cpp(), out.name + # # ) # TODO enable this + # newline += indent + 'nnet::print_result<{actualType}, {dmaType}, {arrName}[{arrSize}]>({portName}, fout);\n'.format( + # actualType = out.type.name, dmaType = self.getDmaTypeName(), arrName = self.get_outputSizeArrName(model),arrSize = str(outIdx), portName = self.getWrapperPortName(out, False) + # ) # TODO enable this + elif '// hls-fpga-machine-learning insert zero' in line: + newline = line + for inpIdx, inp in enumerate(model_inputs): + streamPktType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else self.getDmaTypeName() + fillZeroFunc = "fill_zero_toArr" if self.vitis_unified_config.isFreeInterimInput() else "fill_zero" + newline += " " + f"hls::stream<{streamPktType}> {self.getWrapperPortName(inp, True)};\n" + newline += " " + (f'nnet::{fillZeroFunc}<{inp.type.name}, {streamPktType},{self.get_inputSizeArrName(model)}[{str(inpIdx)}]>' + f'({self.getWrapperPortName(inp,True)});\n') + for out in model_outputs: + #newline += indent + out.definition_cpp() + ';\n' + streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() + newline += " " + f"hls::stream<{streamPktType}> {self.getWrapperPortName(out, False)};\n" + + elif ( + '// hls-fpga-machine-learning insert output' in line + or '// hls-fpga-machine-learning insert quantized' in line + or '// hls-fpga-machine-learning insert tb-output' in line + ): + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' + keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" + #keep_output = str(tb_stream != 'stdout').lower() # We keep output if we need to write it to file too. + if tb_stream != 'file': ### it mean cout + for outIdx, out in enumerate(model_outputs): + # newline += indent + 'nnet::print_result<{}, {}>({}, std::cout, {});\n'.format( + # out.type.name, out.size_cpp(), out.name, keep_output + # ) + streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() + + newline += (indent + 'nnet::print_result<{actualType}, {pktType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + .format( actualType = out.type.name, + pktType = streamPktType, + arrName = self.get_outputSizeArrName(model), + arrIdx = str(outIdx), + portName = self.getWrapperPortName(out, False), + des = dest, + keepOutput = keep_output)) + + 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) + f.close() + fout.close() + + + #################################################### + ### write myproject_bridge.cpp ##################### + #################################################### + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') + + 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 f.readlines(): + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + + elif 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) + + 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() + inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) + outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) + + newline = '' + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + '\n' + + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + newline = '' + for inpIdx, inp in enumerate(model_inputs): ## former is i + if self.vitis_unified_config.isFreeInterimInput(): + newline += indent + f"hls::stream<{inp.type.name}> {self.getWrapperPortName(inp, True)};\n" + newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + srcType =dtype, + underlying_data_T=inp.type.name, + data_T=self.get_axi_wrapper_type(inp), + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=self.getWrapperPortName(inp, True), + ) + else: + newline += indent + f"hls::stream {self.getWrapperPortName(inp, True)};\n" + newline += indent + f"nnet::convert_data<{dtype}, {dtype}, {self.get_inputSizeArrName(model)}[{str(inpIdx)}]>({inp.name}, {self.getWrapperPortName(inp, True)});\n" + # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( + # dtype, i.type.name, i.size_cpp(), i.name, i.name + # ) + newline += '\n' + + for out in model_outputs: + #newline += indent + '{var};\n'.format(var=o.definition_cpp(name_suffix='_ap')) + outStreamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() + newline += indent + f"hls::stream<{outStreamType}> {self.getWrapperPortName(out, False)};\n" + + newline += '\n' + + input_vars = ','.join([self.getWrapperPortName(inp, True)for inp in model_inputs]) + bram_vars = ','.join([b.name for b in model_brams]) + output_vars = ','.join([self.getWrapperPortName(out, False) for out in model_outputs]) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) + + top_level = indent + f'{self.getTopModelName(model)}({all_vars});\n' + newline += top_level + + newline += '\n' + + for outIdx, out in enumerate(model_outputs): + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # o.type.name, dtype, o.size_cpp(), o.name, o.name + # ) + if self.vitis_unified_config.isFreeInterimOutput(): + newline += indent + f"nnet::convert_data_pkt<{dtype}, {out.type.name}, {self.get_outputSizeArrName(model)}[{str(outIdx)}]>({self.getWrapperPortName(out, False)}, {out.name});\n" + else: + newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {self.get_axi_wrapper_type(out)},{self.get_outputSizeArrName(model)}[{str(outIdx)}]>" + f"({self.getWrapperPortName(out, False)}, {out.name});\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): + vars = layer.get_variables() + for var in vars: + 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) + + f.close() + fout.close() + + ######################################################## + ## write test script function helper ############### + ######################################################## + + + def write_board_script(self, model): + ''' + Write the tcl scripts and kernel sources to create a Vivado IPI project for the VitisAcceleratorIPFlow + ''' + ### I am not sure yet what it is + # filedir = os.path.dirname(os.path.abspath(__file__)) + # copyfile( + # os.path.join(filedir, self.vitis_accelerator_ip_flow_config.get_tcl_file_path()), + # f'{model.config.get_output_dir()}/design.tcl', + # ) + + ################### + # project.tcl + ################### + f = open(f'{model.config.get_output_dir()}/project.tcl', 'w') + f.write('variable project_name\n') + f.write(f'set project_name "{model.config.get_project_name()}"\n') + f.write('variable backend\n') + f.write('set backend "vitisacceleratoripflowpartial"\n') + f.write('variable part\n') + f.write("set part \"xc7z020clg400-1\"\n") + #f.write(f'set part "{self.vitis_accelerator_ip_flow_config.get_part()}"\n') + f.write('variable clock_period\n') + f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))) + f.write('variable clock_uncertainty\n') + f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '12.5%'))) + f.write('variable version\n') + f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0'))) + # if self.vitis_accelerator_ip_flow_config.get_interface() == 'axi_stream': + # in_bit, out_bit = self.vitis_accelerator_ip_flow_config.get_io_bitwidth() + # f.write(f'set bit_width_hls_output {in_bit}\n') + # f.write(f'set bit_width_hls_input {out_bit}\n') + f.close() + return + + def write_driver(self, model): + print("[partial reconfig] we are not supporting write_driver this yet") + + def modify_build_script(self, model): + ''' + Modify the build_prj.tcl and build_lib.sh scripts to add the extra wrapper files and set the top function + ''' + filedir = os.path.dirname(os.path.abspath(__file__)) + oldfile = f'{model.config.get_output_dir()}/build_prj.tcl' + newfile = f'{model.config.get_output_dir()}/build_prj_axi.tcl' + f = open(oldfile) + fout = open(newfile, 'w') + + for line in f.readlines(): + if 'set_top' in line: + newline = line[:-1] + '_axi\n' # remove the newline from the line end and append _axi for the new top + newline += f'add_files firmware/{model.config.get_project_name()}_axi.cpp -cflags "-std=c++0x"\n' + elif f'{model.config.get_project_name()}_cosim' in line: + newline = line.replace( + f'{model.config.get_project_name()}_cosim', + f'{model.config.get_project_name()}_axi_cosim', + ) + elif '${project_name}.tcl' in line: + newline = line.replace('${project_name}.tcl', '${project_name}_axi.tcl') + else: + newline = line + fout.write(newline) + + f.close() + fout.close() + os.rename(newfile, oldfile) + + ################### + # build_lib.sh + ################### + + f = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) + fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') + + for line in f.readlines(): + line = line.replace('myproject', model.config.get_project_name()) + line = line.replace('mystamp', model.config.get_config_value('Stamp')) + + fout.write(line) + f.close() + fout.close() + + def write_new_tar(self, model): + super().write_tar(model) + + def write_bridge_multigraph(self, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') + model_inputs = model.graphs[0].get_input_variables() + model_outputs = model.graphs[-1].get_output_variables() + model_brams = [var for var in model.graphs[0].get_weight_variables() if var.storage.lower() == 'bram'] + + indent = ' ' + + for line in f.readlines(): + newline = '' + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + elif 'firmware/myproject' in line: + for graph_idx, g in enumerate(model.graphs): + newline += '#undef DEFINES_H_\n' + if len(g.outputs) == 1: + newline += '#define result_t ' + 'result_graph' + str(graph_idx + 1) + '_t\n' + newline += line.replace('myproject', format(model.graphs[graph_idx].config.get_project_name())) + if len(g.outputs) == 1: + newline += ( + 'typedef result_graph' + str(graph_idx + 1) + '_t graph' + str(graph_idx + 1) + '_result_t;\n' + ) + newline += '#undef result_t\n\n' if graph_idx < len(model.graphs) - 1 else '\n' + newline += '\n' + elif 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) + + 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() + inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) + outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) + + newline = '' + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + '\n' + + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + newline = '' + for inp in model_inputs: + + if self.vitis_unified_config.isFreeInterimInput(): + newline += indent + f"hls::stream<{inp.type.name}> {self.getWrapperPortName(inp, True)};\n" + newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + srcType =dtype, + underlying_data_T=inp.type.name, + data_T=self.get_axi_wrapper_type(inp), + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=self.getWrapperPortName(inp, True), + ) + else: + newline += indent + f"hls::stream<{self.getDmaTypeName()}> " + self.getWrapperPortName(inp, True) + ";\n" + newline += indent + "nnet::convert_data<{dtype}, {dtype}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + dtype=dtype, + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=self.getWrapperPortName(inp, True), + ) + + # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( + # dtype, i.type.name, i.size_cpp(), i.name, i.name + #) + newline += '\n' + + + for idx, g in enumerate(model.graphs): + for out in g.get_output_variables(): + outStreamName = self.getWrapperPortName(out, False) + outStreamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() + newline += indent + f"hls::stream<{outStreamType}> {outStreamName}(\"{outStreamName}\");\n" + # definition = o.definition_cpp(name_suffix='_ap') + # if len(g.outputs) == 1: + # parts = definition.split(' ', 1) + # datatype = 'graph' + str(idx + 1) + '_result_t' + # if parts[0].startswith('hls::stream'): + # modified_definition = 'hls::stream<' + datatype + '> ' + parts[1] + # else: + # modified_definition = datatype + ' ' + parts[1] + # newline += indent + f"{modified_definition};\n" + # else: + # newline += indent + f"{definition};\n" + + newline += '\n' + + top_level = '' + myOutputNextInput = [] + #output_vars = '' + for idx, g in enumerate(model.graphs): + # if idx == 0: + # input_vars = ','.join([i.name + '_ap' for i in g.get_input_variables()]) + # else: + # input_vars = output_vars + # bram_vars = ','.join( + # [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] + # ) + # output_vars = ','.join([o.name + '_ap' for o in g.get_output_variables()]) + # # Concatenate the input, output, and bram variables. Filter out empty/null values + if idx == 0: + input_vars = [self.getWrapperPortName(inp, True) for inp in g.get_input_variables()] + else: + input_vars = myOutputNextInput.copy() + + output_vars = [self.getWrapperPortName(out, False) for out in g.get_output_variables()] + myOutputNextInput = output_vars.copy() + bram_vars = [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] + allArgs = input_vars + output_vars + bram_vars + all_vars = ', '.join(allArgs) + top_level += indent + f"{g.config.get_project_name()}_axi({all_vars});\n" + newline += top_level + + newline += '\n' + + for outIdx, o in enumerate(model_outputs): + # if len(model.graphs[-1].outputs) == 1: + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # datatype, dtype, o.size_cpp(), o.name, o.name + # ) + # else: + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # o.type.name, dtype, o.size_cpp(), o.name, o.name + # ) + if self.vitis_unified_config.isFreeInterimOutput(): + newline += indent + (f"nnet::convert_data_pkt<{dtype}, {o.type.name}, " + f"{self.get_outputSizeArrName(model)}[{str(outIdx)}]>" + f"({self.getWrapperPortName(o, False)}, {o.name});\n") + else: + newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {str(o.size())}>" + f"({self.getWrapperPortName(o, False)}, {o.name});\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): + vars = layer.get_variables() + for var in vars: + 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' + + elif '// hls-fpga-machine-learning insert tb_input_writer' in line: + funcs = [ + ("float", "dump_tb_inputs_float"), + ("double", "dump_tb_inputs_double"), + ] + newline = "" + for dtype, funcname in funcs: + newline += f'void {funcname}(\n' + newline += ' const char* output_path' + for inp in model_inputs: + newline += f',\n {dtype} {inp.name}[{inp.size_cpp()}]' + newline += '\n) {\n\n' + + for inp in model_inputs: + decl = inp.definition_cpp(name_suffix='_ap').strip() + ap = inp.name + "_ap" + if decl.startswith("hls::stream"): + newline += f' {decl};\n' + else: + newline += f' {inp.type.name} {ap}[{inp.size_cpp()}];\n' + newline += ( + f' nnet::convert_data<{dtype}, {inp.type.name}, {inp.size_cpp()}>' f'({inp.name}, {ap});\n' + ) + newline += "\n" + newline += f' std::ofstream fout(std::string(output_path) + "/{inp.name}_input_data.txt");\n' + + for inp in model_inputs: + decl = inp.definition_cpp(name_suffix='_ap').strip() + dims = inp.shape + + if decl.startswith("hls::stream"): + if len(dims) == 1: + N = dims[0] + newline += f' for(int i = 0; i < {N}; i++) {{\n' + newline += f' auto temp = {inp.name}_ap.read();\n' + newline += ( + f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[0].range();\n' + ) + newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' + newline += ' }\n' + else: + inputs_list = model.nn_config['inputs'] + fifo_depth = next((e['fifo_depth'] for e in inputs_list if e['name'] == inp.name), None) + batch_size = next((e['batch_size'] for e in inputs_list if e['name'] == inp.name), None) + newline += f' for(int r = 0; r < {fifo_depth}; r++) {{\n' + newline += f' auto temp = {inp.name}_ap.read();\n' + newline += f' for(int c = 0; c < {batch_size}; c++) {{\n' + newline += ( + f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[c].range();\n' + ) + newline += ( + f' fout << bits.to_uint()' f' << (c+1<{batch_size} ? \' \' : \'\\n\');\n' + ) + newline += ' }\n' + newline += ' }\n' + else: + ap = inp.name + "_ap" + N = inp.size_cpp() + newline += f' for(int i = 0; i < {N}; i++) {{\n' + newline += f' ap_uint<{inp.type.name}::width> bits = ' f'{ap}[i].range();\n' + newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' + newline += ' }\n' + newline += " fout.close();\n" + newline += "}\n" + else: + newline = line + fout.write(newline) + + f.close() + fout.close() + + def write_build_script(self, model): + filedir = Path(__file__).parent + ##### we require vitis unified not + super().write_build_script(model) + + + # build_prj.tcl (lagacy unused) + srcpath = (filedir / '../templates/vitis_unified/build_prj.tcl').resolve() + dstpath = f'{model.config.get_output_dir()}/build_prj.tcl' + copyfile(srcpath, dstpath) + + #### we build 3 config file for hls_config.cfg/hls_config_cosim.cfg/hls_config_csim.cfg + + for configType in ["hls_config.cfg","hls_config_cosim.cfg","hls_config_csim.cfg"]: + # hls_config.cfg + srcpath = (filedir / '../templates/vitis_unified/hls_config.cfg').resolve() + despath = f'{model.config.get_output_dir()}/{configType}' + df = open(despath, 'w') + with open(srcpath, 'r') as sf: + lines = sf.readlines() + for line in lines: + if "{PART}" in line: + line = line.replace("{PART}", self.vitis_unified_config.get_part()) + if "{CLK}" in line: + line = line.replace("{CLK}", model.config.get_config_value('ClockPeriod')) + if "{OUTDIR}" in line: + line = line.replace("{OUTDIR}", model.config.get_output_dir()) + if "{CLK_UC}" in line: + line = line.replace("{CLK_UC}", model.config.get_config_value('ClockUncertainty', '12.5%')) + if "{PRJ_NAME}" in line: + line = line.replace("{PRJ_NAME}", model.config.get_project_name()) + if "{TOP_NAME}" in line: + line = line.replace("{TOP_NAME}", model.config.get_project_name() + "_axi") + if ("-DRTL_SIM" in line) and (configType != "hls_config_cosim.cfg"): + line = "" + + df.write(line) + df.close() + + + ##### override stitch multigraph + def write_build_script_multigraph(self, model): + """Write the build script (build_lib.sh) for stitched multigraph project + Args: + model (MultiModelGraph): the hls4ml multigraph model. + """ + filedir = Path(__file__).parent + os.makedirs(model.config.get_output_dir(), exist_ok=True) + build_lib_src = (filedir / '../templates/vitis_unified/build_lib_multigraph.sh').resolve() + build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve() + graph_project_names = ' '.join(f"\"{g.config.get_output_dir().split('/')[-1]}\"" for g in model.graphs) + + with open(build_lib_src) as src, open(build_lib_dst, 'w') as dst: + for line in src.readlines(): + line = line.replace('myproject', model.config.config['OriginalProjectName']) + line = line.replace('myproject_stitched', model.config.config['ProjectName']) + line = line.replace('mystamp', model.config.config['Stamp']) + line = line.replace('mygraph_name_list', graph_project_names) + dst.write(line) + os.chmod(build_lib_dst, os.stat(build_lib_dst).st_mode | stat.S_IEXEC) + + + + def write_hls(self, model, is_multigraph=False): + + from hls4ml.backends import VitisUnifiedConfig + + self.vitis_unified_config = VitisUnifiedConfig( + model.config, model.get_input_variables(), model.get_output_variables() + ) + super().write_hls(model, is_multigraph=is_multigraph) + if not is_multigraph: + self.write_board_script(model) + self.write_driver(model) + self.write_wrapper_test(model) + self.write_axi_wrapper(model) + self.modify_build_script(model) + self.write_new_tar(model) + else: + self.write_bridge_multigraph(model) + #self.modify_write_build_script_multigraph(model) + + + From 6ac2b711857c3bab1a415accead3a0ae2c7bf5f9 Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 14 Aug 2025 17:37:17 +0200 Subject: [PATCH 02/70] add vitis unified template --- hls4ml/templates/vitis_unified/build_lib.sh | 30 ++ .../vitis_unified/build_lib_multigraph.sh | 69 +++++ hls4ml/templates/vitis_unified/build_prj.tcl | 256 ++++++++++++++++++ hls4ml/templates/vitis_unified/hls_config.cfg | 21 ++ .../templates/vitis_unified/myproject_axi.cpp | 18 ++ .../templates/vitis_unified/myproject_axi.h | 15 + .../vitis_unified/myproject_bridge.cpp | 71 +++++ .../vitis_unified/myproject_test.cpp | 96 +++++++ 8 files changed, 576 insertions(+) create mode 100644 hls4ml/templates/vitis_unified/build_lib.sh create mode 100644 hls4ml/templates/vitis_unified/build_lib_multigraph.sh create mode 100644 hls4ml/templates/vitis_unified/build_prj.tcl create mode 100644 hls4ml/templates/vitis_unified/hls_config.cfg create mode 100644 hls4ml/templates/vitis_unified/myproject_axi.cpp create mode 100644 hls4ml/templates/vitis_unified/myproject_axi.h create mode 100644 hls4ml/templates/vitis_unified/myproject_bridge.cpp create mode 100644 hls4ml/templates/vitis_unified/myproject_test.cpp diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh new file mode 100644 index 0000000000..74f026f543 --- /dev/null +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -0,0 +1,30 @@ +#!/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=myproject +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/${PROJECT}_axi.cpp -o ${PROJECT}_axi.o +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_axi.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/build_prj.tcl b/hls4ml/templates/vitis_unified/build_prj.tcl new file mode 100644 index 0000000000..89906bd4a6 --- /dev/null +++ b/hls4ml/templates/vitis_unified/build_prj.tcl @@ -0,0 +1,256 @@ +################# +# HLS4ML +################# +array set opt { + reset 0 + csim 1 + synth 1 + cosim 1 + validation 1 + export 0 + vsynth 0 + fifo_opt 0 +} + +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +proc remove_recursive_log_wave {} { + set tcldir [file dirname [info script]] + source [file join $tcldir project.tcl] + + set filename ${project_name}_prj/solution1/sim/verilog/${project_name}_axi.tcl + set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}] + set temp $filename.new.$timestamp + # set backup $filename.bak.$timestamp + + set in [open $filename r] + set out [open $temp w] + + # line-by-line, read the original file + while {[gets $in line] != -1} { + if {[string equal "$line" "log_wave -r /"]} { + set line { } + } + puts $out $line + } + + close $in + close $out + + # move the new data to the proper filename + file delete -force $filename + file rename -force $temp $filename +} + +proc add_vcd_instructions_tcl {} { + set tcldir [file dirname [info script]] + source [file join $tcldir project.tcl] + + set filename ${project_name}_prj/solution1/sim/verilog/${project_name}_axi.tcl + set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}] + set temp $filename.new.$timestamp + # set backup $filename.bak.$timestamp + + set in [open $filename r] + set out [open $temp w] + + # line-by-line, read the original file + while {[gets $in line] != -1} { + if {[string equal "$line" "log_wave -r /"]} { + set line {source "../../../../project.tcl" + if {[string equal "$backend" "vivadoaccelerator"]} { + current_scope [get_scopes -regex "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi/${project_name}_U0.*"] + set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}] + append scopes { } + current_scope "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi" + append scopes [get_scopes -regexp {(in_local_V_data.*_0_.*)}] + append scopes { } + append scopes [get_scopes -regexp {(out_local_V_data.*_0_.*)}] + } else { + current_scope [get_scopes -regex "/apatb_${project_name}_top/AESL_inst_${project_name}"] + set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}] + } + open_vcd fifo_opt.vcd + foreach scope $scopes { + current_scope $scope + if {[catch [get_objects usedw]] == 0} { + puts "$scope skipped" + continue + } + set usedw [get_objects usedw] + set depth [get_objects DEPTH] + add_wave $usedw + log_vcd $usedw + log_wave $usedw + add_wave $depth + log_vcd $depth + log_wave $depth + } + } + } + + if {[string equal "$line" "quit"]} { + set line {flush_vcd + close_vcd + quit + } + } + # then write the transformed line + puts $out $line + } + + close $in + close $out + + # move the new data to the proper filename + file delete -force $filename + file rename -force $temp $filename +} + +foreach arg $::argv { + foreach o [lsort [array names opt]] { + regexp "$o=+(\\w+)" $arg unused opt($o) + } +} + +proc report_time { op_name time_start time_end } { + set time_taken [expr $time_end - $time_start] + set time_s [expr ($time_taken / 1000) % 60] + set time_m [expr ($time_taken / (1000*60)) % 60] + set time_h [expr ($time_taken / (1000*60*60)) % 24] + puts "***** ${op_name} COMPLETED IN ${time_h}h${time_m}m${time_s}s *****" +} + +# Compare file content: 1 = same, 0 = different +proc compare_files {file_1 file_2} { + # Check if files exist, error otherwise + if {! ([file exists $file_1] && [file exists $file_2])} { + return 0 + } + # Files with different sizes are obviously different + if {[file size $file_1] != [file size $file_2]} { + return 0 + } + + # String compare the content of the files + set fh_1 [open $file_1 r] + set fh_2 [open $file_2 r] + set equal [string equal [read $fh_1] [read $fh_2]] + close $fh_1 + close $fh_2 + return $equal +} + +file mkdir tb_data +set CSIM_RESULTS "./tb_data/csim_results.log" +set RTL_COSIM_RESULTS "./tb_data/rtl_cosim_results.log" + +if {$opt(reset)} { + open_project -reset ${project_name}_prj +} else { + open_project ${project_name}_prj +} +set_top ${project_name}_axi +add_files firmware/${project_name}_axi.cpp -cflags "-std=c++0x" +add_files firmware/${project_name}.cpp -cflags "-std=c++0x" +add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x" + +add_files -tb firmware/weights +add_files -tb tb_data +if {$opt(reset)} { + open_solution -reset "solution1" +} else { + open_solution "solution1" +} +catch {config_array_partition -maximum_size $maximum_size} +config_compile -name_max_length 80 +set_part $part +config_schedule -enable_dsp_full_reg=false +create_clock -period $clock_period -name default +set_clock_uncertainty $clock_uncertainty default + + +if {$opt(csim)} { + puts "***** C SIMULATION *****" + set time_start [clock clicks -milliseconds] + csim_design + set time_end [clock clicks -milliseconds] + report_time "C SIMULATION" $time_start $time_end +} + +if {$opt(synth)} { + puts "***** C/RTL SYNTHESIS *****" + + set time_start [clock clicks -milliseconds] + csynth_design + set time_end [clock clicks -milliseconds] + report_time "C/RTL SYNTHESIS" $time_start $time_end +} + +if {$opt(cosim)} { + puts "***** C/RTL SIMULATION *****" + # TODO: This is a workaround (Xilinx defines __RTL_SIMULATION__ only for SystemC testbenches). + add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x -DRTL_SIM" + set time_start [clock clicks -milliseconds] + + cosim_design -trace_level all -setup + + if {$opt(fifo_opt)} { + puts "\[hls4ml\] - FIFO optimization started" + + if {[string equal "$backend" "vivado"] || [string equal $backend "vivadoaccelerator"]} { + add_vcd_instructions_tcl + } + } + + remove_recursive_log_wave + set old_pwd [pwd] + cd ${project_name}_prj/solution1/sim/verilog/ + source run_sim.tcl + cd $old_pwd + puts "THIS IS MY BACKEND : $backend" + set time_end [clock clicks -milliseconds] + puts "INFO:" + if {[string equal "$backend" "vivadoaccelerator"] || [string equal $backend "vitisacceleratoripflow"] || [string equal $backend "vitisacceleratoripflowpartial"]} { + puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_axi_cosim.rpt r]] + } else { + puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_cosim.rpt r]] + } + report_time "C/RTL SIMULATION" $time_start $time_end +} + +if {$opt(validation)} { + puts "***** C/RTL VALIDATION *****" + if {[compare_files $CSIM_RESULTS $RTL_COSIM_RESULTS]} { + puts "INFO: Test PASSED" + } else { + puts "ERROR: Test failed" + puts "ERROR: - csim log: $CSIM_RESULTS" + puts "ERROR: - RTL-cosim log: $RTL_COSIM_RESULTS" + exit 1 + } +} + +if {$opt(export)} { + puts "***** EXPORT IP *****" + set time_start [clock clicks -milliseconds] + export_design -format ip_catalog -version $version + set time_end [clock clicks -milliseconds] + report_time "EXPORT IP" $time_start $time_end +} + +if {$opt(vsynth)} { + puts "***** VIVADO SYNTHESIS *****" + if {[file exist ${project_name}_prj/solution1/syn/verilog]} { + set time_start [clock clicks -milliseconds] + exec vivado -mode batch -source vivado_synth.tcl >@ stdout + set time_end [clock clicks -milliseconds] + report_time "VIVADO SYNTHESIS" $time_start $time_end + } else { + puts "ERROR: Cannot find generated Verilog files. Did you run C synthesis?" + exit 1 + } +} + +exit diff --git a/hls4ml/templates/vitis_unified/hls_config.cfg b/hls4ml/templates/vitis_unified/hls_config.cfg new file mode 100644 index 0000000000..14b164f3ed --- /dev/null +++ b/hls4ml/templates/vitis_unified/hls_config.cfg @@ -0,0 +1,21 @@ +part={PART} + +[hls] +clock={CLK} +clock_uncertainty={CLK_UC} +flow_target=vivado +syn.file={OUTDIR}/firmware/{PRJ_NAME}_axi.cpp +syn.file={OUTDIR}/firmware/{PRJ_NAME}.cpp +syn.file_cflags={OUTDIR}/firmware/{PRJ_NAME}_axi.cpp,-std=c++0x +syn.file_cflags={OUTDIR}/firmware/{PRJ_NAME}.cpp,-std=c++0x +syn.top={TOP_NAME} +tb.file={OUTDIR}/{PRJ_NAME}_test.cpp +tb.file={OUTDIR}/firmware/weights +tb.file={OUTDIR}/tb_data +tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-std=c++0x +tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-DRTL_SIM +package.ip.version=1.0.0 +package.output.format=ip_catalog +syn.compile.name_max_length=80 +syn.schedule.enable_dsp_full_reg=0 +package.output.syn=false \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_axi.cpp b/hls4ml/templates/vitis_unified/myproject_axi.cpp new file mode 100644 index 0000000000..35abb02e26 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi.cpp @@ -0,0 +1,18 @@ +// hls-fpga-machine-learning insert include + +void myproject_axi( + + // hls-fpga-machine-learning insert multiIo + +) { + + // hls-fpga-machine-learning insert interface + + // hls-fpga-machine-learning insert local vars + + // hls-fpga-machine-learning insert enqueue + + // hls-fpga-machine-learning insert call + + // hls-fpga-machine-learning insert dequeue +} diff --git a/hls4ml/templates/vitis_unified/myproject_axi.h b/hls4ml/templates/vitis_unified/myproject_axi.h new file mode 100644 index 0000000000..2ccc3b7d23 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_axi.h @@ -0,0 +1,15 @@ + +#ifndef MYPROJECT_AXI_H_ +#define MYPROJECT_AXI_H_ + +#include +// hls-fpga-machine-learning insert include + +// hls-fpga-machine-learning insert definitions + +void myproject_axi( + +// hls-fpga-machine-learning insert multi-io + +); +#endif \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_bridge.cpp b/hls4ml/templates/vitis_unified/myproject_bridge.cpp new file mode 100644 index 0000000000..20009e5b4f --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_bridge.cpp @@ -0,0 +1,71 @@ +#ifndef MYPROJECT_BRIDGE_H_ +#define MYPROJECT_BRIDGE_H_ + +#include "firmware/myproject_axi.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..689d4f055b --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_test.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firmware/myproject_axi.h" +#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; +} From cfc92d56af79bed53f9c93d5702c7f753d52a449 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 11:06:44 +0200 Subject: [PATCH 03/70] add dma wrapper access --- .../templates/vitis_unified/myproject_dm.cpp | 0 hls4ml/templates/vitis_unified/myproject_dm.h | 46 +++++++++++++++++++ hls4ml/writer/vitis_unified_writer.py | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 hls4ml/templates/vitis_unified/myproject_dm.cpp create mode 100644 hls4ml/templates/vitis_unified/myproject_dm.h diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h new file mode 100644 index 0000000000..be77c990c9 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -0,0 +1,46 @@ +#include +#include +#include +#include "ap_axi_sdata.h" +#include "MY_PROJECT_AXI.h" + +#define DMX_BUF_IN_SZ VAL +#define DMX_BUF_OUT_SZ VAL + + +static void load_input(float* in, hls::stream& inStream, int size) { +mem_rd: + for (int i = 0; i < size; i++) { +#pragma HLS PIPELINE II=1 + inStream.data << in[i]; + inStream.last = (i == (size-1)); + } +} + +static void store_result(float* out, hls::stream& out_stream, int size) { +mem_wr: + for (int i = 0; i < size; i++) { +#pragma HLS PIPELINE II=1 + out[i] = out_stream.read().data; + } +} + + +void MY_PROJECT(float* in, float* out, int inSize, int outSize){ + +#pragma HLS INTERFACE m_axi port = in bundle = gmem0 +#pragma HLS INTERFACE m_axi port = out bundle = gmem1 + +static hls::stream in_stream("in_stream") +static hls::stream out_stream("out_stream") + +#pragma HLS STREAM variable=in_stream depth=DMX_BUF_IN_SZ +#pragma HLS STREAM variable=out_stream depth=DMX_BUF_OUT_SZ + +#pragma HLS dataflow + + load_input(in, in_stream, inSize); + MY_PROJECT_CON(in_stream, out_stream); + store_result(out, out_stream, outSize); + +} \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer.py b/hls4ml/writer/vitis_unified_writer.py index 71c67ad9fa..bd77d913e4 100644 --- a/hls4ml/writer/vitis_unified_writer.py +++ b/hls4ml/writer/vitis_unified_writer.py @@ -1011,7 +1011,7 @@ def write_hls(self, model, is_multigraph=False): self.vitis_unified_config = VitisUnifiedConfig( model.config, model.get_input_variables(), model.get_output_variables() ) - super().write_hls(model, is_multigraph=is_multigraph) + super().write_hls(model) if not is_multigraph: self.write_board_script(model) self.write_driver(model) From f570c3f1e542e0bea7a76e2ef708e55d35fe8617 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 16:46:38 +0200 Subject: [PATCH 04/70] extract writer class + add gmem wrapper --- environment.yml | 22 + .../vitis_unified/vitis_unified_config.py | 8 +- hls4ml/converters/__init__.py | 2 + .../templates/vitis_unified/myproject_dm.cpp | 46 + hls4ml/templates/vitis_unified/myproject_dm.h | 46 - hls4ml/writer/vitis_unified_writer.py | 1027 ----------------- .../writer/vitis_unified_writer/__init__.py | 33 + .../writer/vitis_unified_writer/build_gen.py | 87 ++ hls4ml/writer/vitis_unified_writer/meta.py | 7 + .../writer/vitis_unified_writer/meta_gen.py | 70 ++ hls4ml/writer/vitis_unified_writer/mm_gen.py | 45 + .../writer/vitis_unified_writer/stream_gen.py | 316 +++++ .../vitis_unified_writer/test_bridge_gen.py | 232 ++++ .../vitis_unified_writer/test_cosim_gen.py | 252 ++++ 14 files changed, 1119 insertions(+), 1074 deletions(-) create mode 100644 environment.yml delete mode 100644 hls4ml/templates/vitis_unified/myproject_dm.h delete mode 100644 hls4ml/writer/vitis_unified_writer.py create mode 100644 hls4ml/writer/vitis_unified_writer/__init__.py create mode 100644 hls4ml/writer/vitis_unified_writer/build_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/meta.py create mode 100644 hls4ml/writer/vitis_unified_writer/meta_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/mm_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/stream_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/test_bridge_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/test_cosim_gen.py diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000000..040c3cb5a7 --- /dev/null +++ b/environment.yml @@ -0,0 +1,22 @@ +name: hls4ml-tutorial-dev +channels: + - conda-forge +dependencies: + - python=3.10.16 + - notebook<7 + - jupyter_contrib_nbextensions + - jupyterhub + - jupyter-book + - jsonschema-with-format-nongpl + - pydot==1.4.2 + - graphviz==7.1.0 + - scikit-learn==1.2.2 + - tensorflow==2.14.0 + - tensorflow-datasets==4.8.3 + - webcolors + - widgetsnbextension==3.6.0 + - pip==23.0.1 + - pip: + - pysr==0.16.3 + - xgboost==1.7.5 + - zstd diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index f478b65209..fa123a2f8e 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -173,4 +173,10 @@ def get_tcl_file_path(self): if self.board.startswith('alveo'): return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + '/tcl_scripts/' + tcl_script else: - return '../templates/vitis_accelerator_ip_flow/' + self.board + '/tcl_scripts/' + tcl_script \ No newline at end of file + return '../templates/vitis_accelerator_ip_flow/' + self.board + '/tcl_scripts/' + tcl_script + + def get_gmem_in_bufferSz(self): + return 12 ###### todo it must get in the config + + def get_gmem_out_bufferSz(self): + return 12 ###### todo it must get in the config \ No newline at end of file diff --git a/hls4ml/converters/__init__.py b/hls4ml/converters/__init__.py index 89f4fc04b9..9a80ef7b47 100644 --- a/hls4ml/converters/__init__.py +++ b/hls4ml/converters/__init__.py @@ -167,6 +167,8 @@ def convert_from_keras_model( hls_config=None, **kwargs, ): + + print("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd") """Convert Keras model to hls4ml model based on the provided configuration. Args: diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index e69de29bb2..9d872ee623 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include "ap_axi_sdata.h" +#include "MY_PROJECT_AXI_INC.h" + +#define DMX_BUF_IN_SZ VAL +#define DMX_BUF_OUT_SZ VAL + + +static void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int size) { +mem_rd: + for (int i = 0; i < size; i++) { +#pragma HLS PIPELINE II=1 + inStream.data << in[i]; + inStream.last = (i == (size-1)); + } +} + +static void store_result(float* out, hls::stream& out_stream, int size) { +mem_wr: + for (int i = 0; i < size; i++) { +#pragma HLS PIPELINE II=1 + out[i] = out_stream.read().data; + } +} + + +void MY_PROJECT_TOP_FUNC(ATOMIC_TYPE* in, ATOMIC_TYPE* out, int inSize, int outSize){ + +#pragma HLS INTERFACE m_axi port = in bundle = gmem0 +#pragma HLS INTERFACE m_axi port = out bundle = gmem1 + +static hls::stream in_stream("in_stream") +static hls::stream out_stream("out_stream") + +#pragma HLS STREAM variable=in_stream depth=DMX_BUF_IN_SZ +#pragma HLS STREAM variable=out_stream depth=DMX_BUF_OUT_SZ + +#pragma HLS dataflow + + load_input(in, in_stream, inSize); + MY_PROJECT_CON(in_stream, out_stream); + store_result(out, out_stream, outSize); + +} \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h deleted file mode 100644 index be77c990c9..0000000000 --- a/hls4ml/templates/vitis_unified/myproject_dm.h +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include "ap_axi_sdata.h" -#include "MY_PROJECT_AXI.h" - -#define DMX_BUF_IN_SZ VAL -#define DMX_BUF_OUT_SZ VAL - - -static void load_input(float* in, hls::stream& inStream, int size) { -mem_rd: - for (int i = 0; i < size; i++) { -#pragma HLS PIPELINE II=1 - inStream.data << in[i]; - inStream.last = (i == (size-1)); - } -} - -static void store_result(float* out, hls::stream& out_stream, int size) { -mem_wr: - for (int i = 0; i < size; i++) { -#pragma HLS PIPELINE II=1 - out[i] = out_stream.read().data; - } -} - - -void MY_PROJECT(float* in, float* out, int inSize, int outSize){ - -#pragma HLS INTERFACE m_axi port = in bundle = gmem0 -#pragma HLS INTERFACE m_axi port = out bundle = gmem1 - -static hls::stream in_stream("in_stream") -static hls::stream out_stream("out_stream") - -#pragma HLS STREAM variable=in_stream depth=DMX_BUF_IN_SZ -#pragma HLS STREAM variable=out_stream depth=DMX_BUF_OUT_SZ - -#pragma HLS dataflow - - load_input(in, in_stream, inSize); - MY_PROJECT_CON(in_stream, out_stream); - store_result(out, out_stream, outSize); - -} \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer.py b/hls4ml/writer/vitis_unified_writer.py deleted file mode 100644 index bd77d913e4..0000000000 --- a/hls4ml/writer/vitis_unified_writer.py +++ /dev/null @@ -1,1027 +0,0 @@ -import os -from pathlib import Path -import stat - -from shutil import copyfile - -from hls4ml.writer.vitis_writer import VitisWriter - -class VitisUnifiedWriter(VitisWriter): - - def __init__(self): - super().__init__() - self.vitis_unified_config = None - - ####################################################### - ## naming of variable function helper ################# - ####################################################### - - def getDmaTypeName(self): - return "dma_data_packet" - - def getWrapperPortName(self, tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}" - - def getTopModelName(self, model): - return f"{model.config.get_project_name()}_axi" - ### it is renamed for stitch layer - def renameType(self, tensorVar, layerIdx:int, isInput: bool): - return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" - - def get_inputSizeArrName(self, model): - return "N_IN_" + model.config.get_project_name() - - def get_outputSizeArrName(self, model): - return "N_OUT_" + model.config.get_project_name() - - def get_axi_wrapper_type(self, tensorVar): - return f"{tensorVar.type.name}_packet" - - def get_axi_wrapper_dec(self, tensorVar): - return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" - - - ######################################################## - ## axi_wrapper.h & axi_wrapper.cpp function helper #### - ######################################################## - ##### variable - def getWrapperPortNameLocal(self, tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_local" - - def getWrapperTmpName(self, tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_tmp" - - def getWrapperIsLastCnt(self, idx): - return f"isLastCnt_{str(idx)}" - ##### io - def write_axi_wrapper_io(self, inps, outs): - inputList = [] - outputList = [] - for inp in inps: - streamType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else "dma_data_packet" - inputList.append(f'hls::stream<{streamType}>& {self.getWrapperPortName(inp, True)}') - for out in outs: - streamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else "dma_data_packet" - outputList.append(f'hls::stream<{streamType}> & {self.getWrapperPortName(out, False)}') - - if len(inputList) == 0 or len(outputList) == 0: - raise Exception("No input or output stream found") - newline = "/////// inputs\n" + ",\n ".join(inputList) + ",\n\n ///outputs\n " + ", ".join(outputList) + "\n" - return newline - ##### content in axi_wrapper.cpp - def write_axi_wrapper_interface(self, model, inps, outs): - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline = '' - indent = " " - for inp in inps: - portname = self.getWrapperPortName(inp, True) - newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' - for out in outs: - portname = self.getWrapperPortName(out, False) - newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' - if model.config.get_config_value("IOType") == 'io_stream': - newline += indent + '#pragma HLS INTERFACE ap_ctrl_none port=return\n' - newline += indent + '#pragma HLS DATAFLOW\n' - return newline - else: - raise Exception("vitis_unified supports only axi_stream @ interface retriever") - - def write_axi_local_vars(self, model, inps, outs): - - ####### build local stream variable - - newline = '///// wrinting local stream vars /////\n' - if self.vitis_unified_config.get_interface() == 'axi_stream': - indent = " " - ##### loop to build local stream to send data into the system - newline += '///////// build input vars ///////////\n' - for idx, inp in enumerate(inps): - newline += f" bool {self.getWrapperIsLastCnt(idx)} = false;\n" - portname = self.getWrapperPortNameLocal(inp, True) - newline += indent + f'hls::stream<{inp.type.name}> {portname}("{portname}");\n' - newline += '///////// build output vars ///////////\n' - for out in outs: - portname = self.getWrapperPortNameLocal(out, False) - newline += indent + f'hls::stream<{out.type.name}> {portname}("{portname}");\n' - - ####### set stream DEPTH - - newline += '///////// set the stream depth ///////////\n' - ##### loop to set depth - - for inpIdx, inp in enumerate(inps): - portname = self.getWrapperPortNameLocal(inp, True) - newline += indent + f'#pragma HLS STREAM variable={portname} depth={inps[inpIdx].pragma[1]}\n' - for outIdx, out in enumerate(outs): - portname = self.getWrapperPortNameLocal(out, False) - newline += indent + f'#pragma HLS STREAM variable={portname} depth={model.get_output_variables()[outIdx].pragma[1]}\n' - - else: - raise Exception("vitis_unified supports only axi_stream @ local vars") - - - return newline - - def write_axi_wrapper_each_enqueue(self, model, inps, idx): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'dma_data_packet {self.getWrapperTmpName(inps[idx], True)};\n' - newline += indent + f"{self.getWrapperTmpName(inps[idx], True)}.last = 0;\n" - ### newline += indent + f'{inps[idx].type.name}\n' - newline += indent + f'for(unsigned i = 0; i < {self.get_inputSizeArrName(model)}[' +str(idx) +']/' + inps[idx].type.name + '::size; ++i){\n' - newline += indent + indent + inps[idx].type.name + ' ctype;\n' - newline += indent + indent + 'for(unsigned j = 0; j < '+ inps[idx].type.name + '::size; ++j){\n' - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline += indent + indent + indent + self.getWrapperPortName(inps[idx], True) + f'.read({self.getWrapperTmpName(inps[idx], True)});\n' - newline += indent + indent + indent + "ctype[j] = " + self.getWrapperTmpName(inps[idx], True) + ".data;\n" - newline += indent + indent + indent + self.getWrapperIsLastCnt(idx) + " = " + self.getWrapperTmpName(inps[idx], True) + ".last;\n" - else: - raise Exception("vitis_unified supports only axi_stream @ each enqueue") - - newline += indent + indent + '}\n' - newline += indent + indent + self.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" - newline += indent + '}\n' - newline += indent + self.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" - - else: - raise Exception("vitis_unified supports only io_stream @ each enqueue") - - return newline - - def write_free_axi_wrapper_each_enqueue(self, model, inps, idx): - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'{self.get_axi_wrapper_type(inps[idx])} {self.getWrapperTmpName(inps[idx], True)};\n' - newline += indent + f"{self.getWrapperTmpName(inps[idx], True)}.last = 0;\n" - newline += indent + f'for(unsigned i = 0; i < {self.get_inputSizeArrName(model)}[' + str(idx) + ']/' + inps[ - idx].type.name + '::size; ++i){\n' - newline += indent + indent + inps[idx].type.name + ' ctype;\n' - newline += indent + indent + self.getWrapperPortName(inps[idx], True) + f'.read({self.getWrapperTmpName(inps[idx], True)});\n' - newline += indent + indent + "ctype = " + self.getWrapperTmpName(inps[idx], True) + ".data;\n" - newline += indent + indent + self.getWrapperIsLastCnt(idx) + " = " + self.getWrapperTmpName(inps[idx], True) + ".last;\n" - newline += indent + indent + self.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" - newline += indent + '}\n' - newline += indent + self.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" - else: - raise Exception("vitis_unified supports only io_stream @ each free axi enqueue") - - return newline - - def write_axi_wrapper_dequeue(self, model, inputs, outs, idx, out_axi_t): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'dma_data_packet {self.getWrapperTmpName(outs[idx], False)};\n' - newline += indent + f"{self.getWrapperTmpName(outs[idx], False)}.last = 0;\n" - ####### the tmp must copy from input to prevent dma get stuck - newline += indent + f'for(unsigned i = 0; i < {self.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' - newline += indent + indent + outs[idx].type.name + ' ctype = ' + self.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' - newline += indent + indent + 'for(unsigned j = 0; j < ' + outs[idx].type.name + '::size; ++j){\n' - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline += indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f'.data = ({out_axi_t}) (ctype[j]);\n' - poolLastCondition = " & ".join([self.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) - newline += indent + indent + indent + f"if({poolLastCondition}){{\n" - newline += indent + indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f".last = (((i+1)*(j+1))=={self.get_outputSizeArrName(model)}[{str(idx)}]);\n" - newline += indent + indent + indent + "}\n" - newline += indent + indent + indent + self.getWrapperPortName(outs[idx], False) + f'.write({self.getWrapperTmpName(outs[idx], False)});\n' - newline += indent + indent + "}\n" - newline += indent + "}\n" - newline += indent + self.getWrapperTmpName(outs[idx], False) + ".last = 0;\n" - else: - raise Exception("vitis_unified supports only axi_stream @ each dequeue") - else: - raise Exception("vitis_unified supports only io_stream @ each dequeue") - - return newline - - def write_free_axi_wrapper_dequeue(self, model, inputs, outs, idx, out_axi_t): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'{self.get_axi_wrapper_type(outs[idx])} {self.getWrapperTmpName(outs[idx], False)};\n' - newline += indent + f"{self.getWrapperTmpName(outs[idx], False)}.last = 0;\n" - ####### the tmp must copy from input to prevent dma get stuck - newline += indent + f'for(unsigned i = 0; i < {self.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' - newline += indent + indent + outs[idx].type.name + ' ctype = ' + self.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' - newline += indent + indent + self.getWrapperTmpName(outs[idx], False) + ".data = ctype;\n" - poolLastCondition = " & ".join([self.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) - newline += indent + indent + f"if({poolLastCondition}){{\n" - newline += indent + indent + indent + self.getWrapperTmpName(outs[idx], False) + f".last = ((i+1) == ({self.get_outputSizeArrName(model)}[{str(idx)}] / {outs[idx].type.name + '::size'} ));\n" - newline += indent + indent + "}\n" - newline += indent + indent + self.getWrapperPortName(outs[idx],False) + f'.write({self.getWrapperTmpName(outs[idx], False)});\n' - newline += indent + "}\n" - else: - raise Exception("vitis_unified supports only io_stream @ each dequeue") - - return newline - - def write_axi_wrapper_insert_call(self, model, inps, outs): - io_type = model.config.get_config_value("IOType") - indent = " " - newline = indent + f'{model.config.get_project_name()}' + "(" - inputList = [] - outputList = [] - for inp in inps: - inputList.append(self.getWrapperPortNameLocal(inp, True)) - for out in outs: - outputList.append(self.getWrapperPortNameLocal(out, False)) - newline += ", ".join(inputList) + ", " + ", ".join(outputList) + ");\n" - return newline - - ######################################################## - ##### main function #################################### - ######################################################## - - def write_axi_wrapper(self, model): - ''' - We we want to have multi io system - ''' - inp_axi_t, out_axi_t, inps, outs = self.vitis_unified_config.get_corrected_types() - indent = ' ' - - print("------------------------------- input write wrapper is -------------------------") - print([inp.name for inp in inps]) - print(model.inputs) - print("------------------------------- output write wrapper is -------------------------") - print([out.name for out in outs]) - print(model.outputs) - print("-----------------------------------------------------------------------------------") - - ###################### - # myproject_axi.h - ###################### - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi.h')) - fout = open(f'{model.config.get_output_dir()}/firmware/{model.config.get_project_name()}_axi.h', 'w') - - for line in f.readlines(): - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - elif '// hls-fpga-machine-learning insert include' in line: - newline = f'#include "{model.config.get_project_name()}.h"\n' - newline += '#include "ap_axi_sdata.h"\n' - elif 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - elif '// hls-fpga-machine-learning insert definitions' in line: - - ##### make input - newline = '' - inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" - newline += f'constexpr unsigned {self.get_inputSizeArrName(model)} [{len(inps)}] = {inputSizeStr};\n' - - ##### make output - outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" - newline += f'constexpr unsigned {self.get_outputSizeArrName(model)} [{len(outs)}] = {outputSizeStr};\n' - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline += 'typedef hls::axis dma_data_packet;\n' - else: - newline += f'typedef {inp_axi_t} input_axi_t;\n' - newline += f'typedef {out_axi_t} output_axi_t;\n' - #### incase the io is interim input - if self.vitis_unified_config.isFreeInterimInput(): - for inp in inps: - newline += self.get_axi_wrapper_dec(inp) + "\n" - #### incase the io is interim output - if self.vitis_unified_config.isFreeInterimOutput(): - for out in outs: - newline += self.get_axi_wrapper_dec(out) + "\n" - elif '// hls-fpga-machine-learning insert multi-io' in line: - newline = '' - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline += self.write_axi_wrapper_io(inps, outs) - else: - raise Exception("vitis_unified supports only axi_stream") - - else: - newline = line - - #### TODO add stream - - fout.write(newline) - f.close() - fout.close() - - ###################### - # myproject_axi.cpp - ###################### - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_axi.cpp')) - fout = open(f'{model.config.get_output_dir()}/firmware/{model.config.get_project_name()}_axi.cpp', 'w') - - io_type = model.config.get_config_value("IOType") - - for line in f.readlines(): - if 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - elif '// hls-fpga-machine-learning insert include' in line: - newline = f'#include "{model.config.get_project_name()}_axi.h"\n' - elif '// hls-fpga-machine-learning insert multiIo' in line: - newline = '' - if self.vitis_unified_config.get_interface() == 'axi_stream': - newline += self.write_axi_wrapper_io(inps, outs) - else: - raise Exception("vitis_unified supports only axi_stream") - elif '// hls-fpga-machine-learning insert interface' in line: - newline = self.write_axi_wrapper_interface(model, inps, outs) - elif '// hls-fpga-machine-learning insert local vars' in line: - newline = self.write_axi_local_vars(model, inps, outs) - elif '// hls-fpga-machine-learning insert enqueue' in line: - newline = '' - if self.vitis_unified_config.isFreeInterimInput(): - for idx, inp in enumerate(inps): - newline += self.write_free_axi_wrapper_each_enqueue(model, inps, idx) + '\n' - else: - for idx, inp in enumerate(inps): - newline += self.write_axi_wrapper_each_enqueue(model, inps, idx) + '\n' - elif '// hls-fpga-machine-learning insert call' in line: - newline = '////// call the main variable\n' - newline += self.write_axi_wrapper_insert_call(model, inps, outs) - elif '// hls-fpga-machine-learning insert dequeue' in line: - newline = '' - if self.vitis_unified_config.isFreeInterimOutput(): - for idx, out in enumerate(outs): - newline += self.write_free_axi_wrapper_dequeue(model, inps, outs, idx, out_axi_t) - else: - for idx, out in enumerate(outs): - newline += self.write_axi_wrapper_dequeue(model, inps, outs, idx, out_axi_t) - else: - newline = line - fout.write(newline) - f.close() - fout.close() - - ######################################################## - ## write test (for co simulation)/ and bridge file () script function helper ############### - ######################################################## - - def write_wrapper_test(self, model): - - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_test.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') - - 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 partial backend\n") - - for line in f.readlines(): - indent = ' ' * (len(line) - len(line.lstrip(' '))) - - #Insert numbers - if 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - 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 - offset = 0 - for inputIdx, inp in enumerate(model_inputs): - streamPktType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else self.getDmaTypeName() - - newline += " hls::stream<{desType}> {inputPortName};\n".format( - desType = streamPktType, inputPortName = self.getWrapperPortName(inp, True) - ) - if self.vitis_unified_config.isFreeInterimInput(): - newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( - underlyType = inp.type.name, - wrapType=streamPktType, - offset=offset, - inputSize=str(inp.size()), - inputPortName=self.getWrapperPortName(inp, True) - ) - else: - newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( - destype = streamPktType, offset=offset, inputSize=str(inp.size()), - inputPortName=self.getWrapperPortName(inp, True) - ) - offset += inp.size() - for out in model_outputs: - streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() - newline += ' ' + f"hls::stream<{streamPktType}> {self.getWrapperPortName(out, False)};\n" - - elif '// hls-fpga-machine-learning insert top-level-function' in line: - newline = line - - input_vars = ','.join([self.getWrapperPortName(inp, True) for inp in model_inputs]) - output_vars = ','.join([self.getWrapperPortName(out, False) for out in model_outputs]) - bram_vars = ','.join([b.name for b in model_brams]) - - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) - - top_level = indent + f'{self.getTopModelName(model)}({all_vars});\n' - - newline += top_level - elif '// hls-fpga-machine-learning insert predictions' in line: - newline = line - for outIdx, out in enumerate(model_outputs): - #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' - newline += indent + f'for(int i = 0; i < {self.get_outputSizeArrName(model)}[{outIdx}]; 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 tb-output' in line: - # newline = line - # tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - # if tb_stream != 'stdout': - # for outIdx, out in enumerate(model_outputs): - # # newline += indent + 'nnet::print_result<{}, {}>({}, fout);\n'.format( - # # out.type.name, out.size_cpp(), out.name - # # ) # TODO enable this - # newline += indent + 'nnet::print_result<{actualType}, {dmaType}, {arrName}[{arrSize}]>({portName}, fout);\n'.format( - # actualType = out.type.name, dmaType = self.getDmaTypeName(), arrName = self.get_outputSizeArrName(model),arrSize = str(outIdx), portName = self.getWrapperPortName(out, False) - # ) # TODO enable this - elif '// hls-fpga-machine-learning insert zero' in line: - newline = line - for inpIdx, inp in enumerate(model_inputs): - streamPktType = self.get_axi_wrapper_type(inp) if self.vitis_unified_config.isFreeInterimInput() else self.getDmaTypeName() - fillZeroFunc = "fill_zero_toArr" if self.vitis_unified_config.isFreeInterimInput() else "fill_zero" - newline += " " + f"hls::stream<{streamPktType}> {self.getWrapperPortName(inp, True)};\n" - newline += " " + (f'nnet::{fillZeroFunc}<{inp.type.name}, {streamPktType},{self.get_inputSizeArrName(model)}[{str(inpIdx)}]>' - f'({self.getWrapperPortName(inp,True)});\n') - for out in model_outputs: - #newline += indent + out.definition_cpp() + ';\n' - streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() - newline += " " + f"hls::stream<{streamPktType}> {self.getWrapperPortName(out, False)};\n" - - elif ( - '// hls-fpga-machine-learning insert output' in line - or '// hls-fpga-machine-learning insert quantized' in line - or '// hls-fpga-machine-learning insert tb-output' in line - ): - newline = line - tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' - keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - #keep_output = str(tb_stream != 'stdout').lower() # We keep output if we need to write it to file too. - if tb_stream != 'file': ### it mean cout - for outIdx, out in enumerate(model_outputs): - # newline += indent + 'nnet::print_result<{}, {}>({}, std::cout, {});\n'.format( - # out.type.name, out.size_cpp(), out.name, keep_output - # ) - streamPktType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() - - newline += (indent + 'nnet::print_result<{actualType}, {pktType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' - .format( actualType = out.type.name, - pktType = streamPktType, - arrName = self.get_outputSizeArrName(model), - arrIdx = str(outIdx), - portName = self.getWrapperPortName(out, False), - des = dest, - keepOutput = keep_output)) - - 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) - f.close() - fout.close() - - - #################################################### - ### write myproject_bridge.cpp ##################### - #################################################### - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') - - 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 f.readlines(): - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - - elif 'myproject' in line: - newline = line.replace('myproject', format(model.config.get_project_name())) - - 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() - inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) - outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) - - newline = '' - newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + '\n' - - elif '// hls-fpga-machine-learning insert wrapper' in line: - dtype = line.split('#', 1)[1].strip() - newline = '' - for inpIdx, inp in enumerate(model_inputs): ## former is i - if self.vitis_unified_config.isFreeInterimInput(): - newline += indent + f"hls::stream<{inp.type.name}> {self.getWrapperPortName(inp, True)};\n" - newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - srcType =dtype, - underlying_data_T=inp.type.name, - data_T=self.get_axi_wrapper_type(inp), - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=self.getWrapperPortName(inp, True), - ) - else: - newline += indent + f"hls::stream {self.getWrapperPortName(inp, True)};\n" - newline += indent + f"nnet::convert_data<{dtype}, {dtype}, {self.get_inputSizeArrName(model)}[{str(inpIdx)}]>({inp.name}, {self.getWrapperPortName(inp, True)});\n" - # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( - # dtype, i.type.name, i.size_cpp(), i.name, i.name - # ) - newline += '\n' - - for out in model_outputs: - #newline += indent + '{var};\n'.format(var=o.definition_cpp(name_suffix='_ap')) - outStreamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() - newline += indent + f"hls::stream<{outStreamType}> {self.getWrapperPortName(out, False)};\n" - - newline += '\n' - - input_vars = ','.join([self.getWrapperPortName(inp, True)for inp in model_inputs]) - bram_vars = ','.join([b.name for b in model_brams]) - output_vars = ','.join([self.getWrapperPortName(out, False) for out in model_outputs]) - - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) - - top_level = indent + f'{self.getTopModelName(model)}({all_vars});\n' - newline += top_level - - newline += '\n' - - for outIdx, out in enumerate(model_outputs): - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # o.type.name, dtype, o.size_cpp(), o.name, o.name - # ) - if self.vitis_unified_config.isFreeInterimOutput(): - newline += indent + f"nnet::convert_data_pkt<{dtype}, {out.type.name}, {self.get_outputSizeArrName(model)}[{str(outIdx)}]>({self.getWrapperPortName(out, False)}, {out.name});\n" - else: - newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {self.get_axi_wrapper_type(out)},{self.get_outputSizeArrName(model)}[{str(outIdx)}]>" - f"({self.getWrapperPortName(out, False)}, {out.name});\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): - vars = layer.get_variables() - for var in vars: - 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) - - f.close() - fout.close() - - ######################################################## - ## write test script function helper ############### - ######################################################## - - - def write_board_script(self, model): - ''' - Write the tcl scripts and kernel sources to create a Vivado IPI project for the VitisAcceleratorIPFlow - ''' - ### I am not sure yet what it is - # filedir = os.path.dirname(os.path.abspath(__file__)) - # copyfile( - # os.path.join(filedir, self.vitis_accelerator_ip_flow_config.get_tcl_file_path()), - # f'{model.config.get_output_dir()}/design.tcl', - # ) - - ################### - # project.tcl - ################### - f = open(f'{model.config.get_output_dir()}/project.tcl', 'w') - f.write('variable project_name\n') - f.write(f'set project_name "{model.config.get_project_name()}"\n') - f.write('variable backend\n') - f.write('set backend "vitisacceleratoripflowpartial"\n') - f.write('variable part\n') - f.write("set part \"xc7z020clg400-1\"\n") - #f.write(f'set part "{self.vitis_accelerator_ip_flow_config.get_part()}"\n') - f.write('variable clock_period\n') - f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))) - f.write('variable clock_uncertainty\n') - f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '12.5%'))) - f.write('variable version\n') - f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0'))) - # if self.vitis_accelerator_ip_flow_config.get_interface() == 'axi_stream': - # in_bit, out_bit = self.vitis_accelerator_ip_flow_config.get_io_bitwidth() - # f.write(f'set bit_width_hls_output {in_bit}\n') - # f.write(f'set bit_width_hls_input {out_bit}\n') - f.close() - return - - def write_driver(self, model): - print("[partial reconfig] we are not supporting write_driver this yet") - - def modify_build_script(self, model): - ''' - Modify the build_prj.tcl and build_lib.sh scripts to add the extra wrapper files and set the top function - ''' - filedir = os.path.dirname(os.path.abspath(__file__)) - oldfile = f'{model.config.get_output_dir()}/build_prj.tcl' - newfile = f'{model.config.get_output_dir()}/build_prj_axi.tcl' - f = open(oldfile) - fout = open(newfile, 'w') - - for line in f.readlines(): - if 'set_top' in line: - newline = line[:-1] + '_axi\n' # remove the newline from the line end and append _axi for the new top - newline += f'add_files firmware/{model.config.get_project_name()}_axi.cpp -cflags "-std=c++0x"\n' - elif f'{model.config.get_project_name()}_cosim' in line: - newline = line.replace( - f'{model.config.get_project_name()}_cosim', - f'{model.config.get_project_name()}_axi_cosim', - ) - elif '${project_name}.tcl' in line: - newline = line.replace('${project_name}.tcl', '${project_name}_axi.tcl') - else: - newline = line - fout.write(newline) - - f.close() - fout.close() - os.rename(newfile, oldfile) - - ################### - # build_lib.sh - ################### - - f = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) - fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') - - for line in f.readlines(): - line = line.replace('myproject', model.config.get_project_name()) - line = line.replace('mystamp', model.config.get_config_value('Stamp')) - - fout.write(line) - f.close() - fout.close() - - def write_new_tar(self, model): - super().write_tar(model) - - def write_bridge_multigraph(self, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) - fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') - model_inputs = model.graphs[0].get_input_variables() - model_outputs = model.graphs[-1].get_output_variables() - model_brams = [var for var in model.graphs[0].get_weight_variables() if var.storage.lower() == 'bram'] - - indent = ' ' - - for line in f.readlines(): - newline = '' - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - elif 'firmware/myproject' in line: - for graph_idx, g in enumerate(model.graphs): - newline += '#undef DEFINES_H_\n' - if len(g.outputs) == 1: - newline += '#define result_t ' + 'result_graph' + str(graph_idx + 1) + '_t\n' - newline += line.replace('myproject', format(model.graphs[graph_idx].config.get_project_name())) - if len(g.outputs) == 1: - newline += ( - 'typedef result_graph' + str(graph_idx + 1) + '_t graph' + str(graph_idx + 1) + '_result_t;\n' - ) - newline += '#undef result_t\n\n' if graph_idx < len(model.graphs) - 1 else '\n' - newline += '\n' - elif 'myproject' in line: - newline = line.replace('myproject', format(model.config.get_project_name())) - - 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() - inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) - outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) - - newline = '' - newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + '\n' - - elif '// hls-fpga-machine-learning insert wrapper' in line: - dtype = line.split('#', 1)[1].strip() - newline = '' - for inp in model_inputs: - - if self.vitis_unified_config.isFreeInterimInput(): - newline += indent + f"hls::stream<{inp.type.name}> {self.getWrapperPortName(inp, True)};\n" - newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - srcType =dtype, - underlying_data_T=inp.type.name, - data_T=self.get_axi_wrapper_type(inp), - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=self.getWrapperPortName(inp, True), - ) - else: - newline += indent + f"hls::stream<{self.getDmaTypeName()}> " + self.getWrapperPortName(inp, True) + ";\n" - newline += indent + "nnet::convert_data<{dtype}, {dtype}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - dtype=dtype, - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=self.getWrapperPortName(inp, True), - ) - - # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( - # dtype, i.type.name, i.size_cpp(), i.name, i.name - #) - newline += '\n' - - - for idx, g in enumerate(model.graphs): - for out in g.get_output_variables(): - outStreamName = self.getWrapperPortName(out, False) - outStreamType = self.get_axi_wrapper_type(out) if self.vitis_unified_config.isFreeInterimOutput() else self.getDmaTypeName() - newline += indent + f"hls::stream<{outStreamType}> {outStreamName}(\"{outStreamName}\");\n" - # definition = o.definition_cpp(name_suffix='_ap') - # if len(g.outputs) == 1: - # parts = definition.split(' ', 1) - # datatype = 'graph' + str(idx + 1) + '_result_t' - # if parts[0].startswith('hls::stream'): - # modified_definition = 'hls::stream<' + datatype + '> ' + parts[1] - # else: - # modified_definition = datatype + ' ' + parts[1] - # newline += indent + f"{modified_definition};\n" - # else: - # newline += indent + f"{definition};\n" - - newline += '\n' - - top_level = '' - myOutputNextInput = [] - #output_vars = '' - for idx, g in enumerate(model.graphs): - # if idx == 0: - # input_vars = ','.join([i.name + '_ap' for i in g.get_input_variables()]) - # else: - # input_vars = output_vars - # bram_vars = ','.join( - # [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] - # ) - # output_vars = ','.join([o.name + '_ap' for o in g.get_output_variables()]) - # # Concatenate the input, output, and bram variables. Filter out empty/null values - if idx == 0: - input_vars = [self.getWrapperPortName(inp, True) for inp in g.get_input_variables()] - else: - input_vars = myOutputNextInput.copy() - - output_vars = [self.getWrapperPortName(out, False) for out in g.get_output_variables()] - myOutputNextInput = output_vars.copy() - bram_vars = [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] - allArgs = input_vars + output_vars + bram_vars - all_vars = ', '.join(allArgs) - top_level += indent + f"{g.config.get_project_name()}_axi({all_vars});\n" - newline += top_level - - newline += '\n' - - for outIdx, o in enumerate(model_outputs): - # if len(model.graphs[-1].outputs) == 1: - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # datatype, dtype, o.size_cpp(), o.name, o.name - # ) - # else: - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # o.type.name, dtype, o.size_cpp(), o.name, o.name - # ) - if self.vitis_unified_config.isFreeInterimOutput(): - newline += indent + (f"nnet::convert_data_pkt<{dtype}, {o.type.name}, " - f"{self.get_outputSizeArrName(model)}[{str(outIdx)}]>" - f"({self.getWrapperPortName(o, False)}, {o.name});\n") - else: - newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {str(o.size())}>" - f"({self.getWrapperPortName(o, False)}, {o.name});\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): - vars = layer.get_variables() - for var in vars: - 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' - - elif '// hls-fpga-machine-learning insert tb_input_writer' in line: - funcs = [ - ("float", "dump_tb_inputs_float"), - ("double", "dump_tb_inputs_double"), - ] - newline = "" - for dtype, funcname in funcs: - newline += f'void {funcname}(\n' - newline += ' const char* output_path' - for inp in model_inputs: - newline += f',\n {dtype} {inp.name}[{inp.size_cpp()}]' - newline += '\n) {\n\n' - - for inp in model_inputs: - decl = inp.definition_cpp(name_suffix='_ap').strip() - ap = inp.name + "_ap" - if decl.startswith("hls::stream"): - newline += f' {decl};\n' - else: - newline += f' {inp.type.name} {ap}[{inp.size_cpp()}];\n' - newline += ( - f' nnet::convert_data<{dtype}, {inp.type.name}, {inp.size_cpp()}>' f'({inp.name}, {ap});\n' - ) - newline += "\n" - newline += f' std::ofstream fout(std::string(output_path) + "/{inp.name}_input_data.txt");\n' - - for inp in model_inputs: - decl = inp.definition_cpp(name_suffix='_ap').strip() - dims = inp.shape - - if decl.startswith("hls::stream"): - if len(dims) == 1: - N = dims[0] - newline += f' for(int i = 0; i < {N}; i++) {{\n' - newline += f' auto temp = {inp.name}_ap.read();\n' - newline += ( - f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[0].range();\n' - ) - newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' - newline += ' }\n' - else: - inputs_list = model.nn_config['inputs'] - fifo_depth = next((e['fifo_depth'] for e in inputs_list if e['name'] == inp.name), None) - batch_size = next((e['batch_size'] for e in inputs_list if e['name'] == inp.name), None) - newline += f' for(int r = 0; r < {fifo_depth}; r++) {{\n' - newline += f' auto temp = {inp.name}_ap.read();\n' - newline += f' for(int c = 0; c < {batch_size}; c++) {{\n' - newline += ( - f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[c].range();\n' - ) - newline += ( - f' fout << bits.to_uint()' f' << (c+1<{batch_size} ? \' \' : \'\\n\');\n' - ) - newline += ' }\n' - newline += ' }\n' - else: - ap = inp.name + "_ap" - N = inp.size_cpp() - newline += f' for(int i = 0; i < {N}; i++) {{\n' - newline += f' ap_uint<{inp.type.name}::width> bits = ' f'{ap}[i].range();\n' - newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' - newline += ' }\n' - newline += " fout.close();\n" - newline += "}\n" - else: - newline = line - fout.write(newline) - - f.close() - fout.close() - - def write_build_script(self, model): - filedir = Path(__file__).parent - ##### we require vitis unified not - super().write_build_script(model) - - - # build_prj.tcl (lagacy unused) - srcpath = (filedir / '../templates/vitis_unified/build_prj.tcl').resolve() - dstpath = f'{model.config.get_output_dir()}/build_prj.tcl' - copyfile(srcpath, dstpath) - - #### we build 3 config file for hls_config.cfg/hls_config_cosim.cfg/hls_config_csim.cfg - - for configType in ["hls_config.cfg","hls_config_cosim.cfg","hls_config_csim.cfg"]: - # hls_config.cfg - srcpath = (filedir / '../templates/vitis_unified/hls_config.cfg').resolve() - despath = f'{model.config.get_output_dir()}/{configType}' - df = open(despath, 'w') - with open(srcpath, 'r') as sf: - lines = sf.readlines() - for line in lines: - if "{PART}" in line: - line = line.replace("{PART}", self.vitis_unified_config.get_part()) - if "{CLK}" in line: - line = line.replace("{CLK}", model.config.get_config_value('ClockPeriod')) - if "{OUTDIR}" in line: - line = line.replace("{OUTDIR}", model.config.get_output_dir()) - if "{CLK_UC}" in line: - line = line.replace("{CLK_UC}", model.config.get_config_value('ClockUncertainty', '12.5%')) - if "{PRJ_NAME}" in line: - line = line.replace("{PRJ_NAME}", model.config.get_project_name()) - if "{TOP_NAME}" in line: - line = line.replace("{TOP_NAME}", model.config.get_project_name() + "_axi") - if ("-DRTL_SIM" in line) and (configType != "hls_config_cosim.cfg"): - line = "" - - df.write(line) - df.close() - - - ##### override stitch multigraph - def write_build_script_multigraph(self, model): - """Write the build script (build_lib.sh) for stitched multigraph project - Args: - model (MultiModelGraph): the hls4ml multigraph model. - """ - filedir = Path(__file__).parent - os.makedirs(model.config.get_output_dir(), exist_ok=True) - build_lib_src = (filedir / '../templates/vitis_unified/build_lib_multigraph.sh').resolve() - build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve() - graph_project_names = ' '.join(f"\"{g.config.get_output_dir().split('/')[-1]}\"" for g in model.graphs) - - with open(build_lib_src) as src, open(build_lib_dst, 'w') as dst: - for line in src.readlines(): - line = line.replace('myproject', model.config.config['OriginalProjectName']) - line = line.replace('myproject_stitched', model.config.config['ProjectName']) - line = line.replace('mystamp', model.config.config['Stamp']) - line = line.replace('mygraph_name_list', graph_project_names) - dst.write(line) - os.chmod(build_lib_dst, os.stat(build_lib_dst).st_mode | stat.S_IEXEC) - - - - def write_hls(self, model, is_multigraph=False): - - from hls4ml.backends import VitisUnifiedConfig - - self.vitis_unified_config = VitisUnifiedConfig( - model.config, model.get_input_variables(), model.get_output_variables() - ) - super().write_hls(model) - if not is_multigraph: - self.write_board_script(model) - self.write_driver(model) - self.write_wrapper_test(model) - self.write_axi_wrapper(model) - self.modify_build_script(model) - self.write_new_tar(model) - else: - self.write_bridge_multigraph(model) - #self.modify_write_build_script_multigraph(model) - - - diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py new file mode 100644 index 0000000000..42421c22dd --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -0,0 +1,33 @@ +import os +from pathlib import Path +import stat +from shutil import copyfile + +from hls4ml.writer.vitis_writer import VitisWriter + + + +class VitisUnifiedWriter(VitisWriter): + + def __init__(self): + super().__init__() + self.vitis_unified_config = None + + def write_hls(self, model, is_multigraph=False): + + from hls4ml.backends import VitisUnifiedConfig + + self.vitis_unified_config = VitisUnifiedConfig( + model.config, model.get_input_variables(), model.get_output_variables() + ) + super().write_hls(model) + if not is_multigraph: + self.write_board_script(model) + self.write_driver(model) + self.write_wrapper_test(model) + self.write_axi_wrapper(model) + self.modify_build_script(model) + self.write_new_tar(model) + else: + self.write_bridge_multigraph(model) + # self.modify_write_build_script_multigraph(model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py new file mode 100644 index 0000000000..b4e6079493 --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -0,0 +1,87 @@ +import os + + +def write_board_script(meta, model): + ''' + Write the tcl scripts and kernel sources to create a Vivado IPI project for the VitisAcceleratorIPFlow + ''' + ### I am not sure yet what it is + # filedir = os.path.dirname(os.path.abspath(__file__)) + # copyfile( + # os.path.join(filedir, self.vitis_accelerator_ip_flow_config.get_tcl_file_path()), + # f'{model.config.get_output_dir()}/design.tcl', + # ) + + ################### + # project.tcl + ################### + f = open(f'{model.config.get_output_dir()}/project.tcl', 'w') + f.write('variable project_name\n') + f.write(f'set project_name "{model.config.get_project_name()}"\n') + f.write('variable backend\n') + f.write('set backend "vitisacceleratoripflowpartial"\n') + f.write('variable part\n') + f.write("set part \"xc7z020clg400-1\"\n") + #f.write(f'set part "{self.vitis_accelerator_ip_flow_config.get_part()}"\n') + f.write('variable clock_period\n') + f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))) + f.write('variable clock_uncertainty\n') + f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '12.5%'))) + f.write('variable version\n') + f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0'))) + # if self.vitis_accelerator_ip_flow_config.get_interface() == 'axi_stream': + # in_bit, out_bit = self.vitis_accelerator_ip_flow_config.get_io_bitwidth() + # f.write(f'set bit_width_hls_output {in_bit}\n') + # f.write(f'set bit_width_hls_input {out_bit}\n') + f.close() + return + +def write_driver(meta, model): + print("[partial reconfig] we are not supporting write_driver this yet") + +def modify_build_script(meta, model): + ''' + Modify the build_prj.tcl and build_lib.sh scripts to add the extra wrapper files and set the top function + ''' + filedir = os.path.dirname(os.path.abspath(__file__)) + oldfile = f'{model.config.get_output_dir()}/build_prj.tcl' + newfile = f'{model.config.get_output_dir()}/build_prj_axi.tcl' + f = open(oldfile) + fout = open(newfile, 'w') + + for line in f.readlines(): + if 'set_top' in line: + newline = line[:-1] + '_axi\n' # remove the newline from the line end and append _axi for the new top + newline += f'add_files firmware/{model.config.get_project_name()}_axi.cpp -cflags "-std=c++0x"\n' + elif f'{model.config.get_project_name()}_cosim' in line: + newline = line.replace( + f'{model.config.get_project_name()}_cosim', + f'{model.config.get_project_name()}_axi_cosim', + ) + elif '${project_name}.tcl' in line: + newline = line.replace('${project_name}.tcl', '${project_name}_axi.tcl') + else: + newline = line + fout.write(newline) + + f.close() + fout.close() + os.rename(newfile, oldfile) + + ################### + # build_lib.sh + ################### + + f = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) + fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') + + for line in f.readlines(): + line = line.replace('myproject', model.config.get_project_name()) + line = line.replace('mystamp', model.config.get_config_value('Stamp')) + + fout.write(line) + f.close() + fout.close() + +def write_new_tar(meta, model): + super().write_tar(model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta.py b/hls4ml/writer/vitis_unified_writer/meta.py new file mode 100644 index 0000000000..180eb6e09a --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/meta.py @@ -0,0 +1,7 @@ + + +class VitisUnifiedWriterMeta: + + def __init__(self): + super().__init__() + self.vitis_unified_config = None \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py new file mode 100644 index 0000000000..ae29a865d6 --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -0,0 +1,70 @@ +import os +from pathlib import Path +import stat + + + +from shutil import copyfile + +def getGmemWrapperFileName(model): + return f"{model.config.get_project_name()}_dm" + +def getAxiWrapperFileName(model): + return f"{model.config.get_project_name()}_axi" + +####################################################### +## naming of variable function helper ################# +####################################################### + +def getGmemTypeName(atomicType: str): + if atomicType not in ["float", "double"]: + raise Exception(f"Unsupported atomic type {atomicType}") + return f"{atomicType}*" + +def getGmemPortName(isInput: bool): + return "in" if isInput else "out" + +def getDmaTypeName(): + return "dma_data_packet" + +def getWrapperPortName(tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}" + +def getTopModelName(model): + return f"{model.config.get_project_name()}_axi" + +def getAxisTopFuncName(model): + return f"{model.config.get_project_name()}_axi" + +### it is renamed for stitch layer +def renameType(tensorVar, layerIdx:int, isInput: bool): + return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" + +def get_inputSizeArrName(model): + return "N_IN_" + model.config.get_project_name() + +def get_outputSizeArrName(model): + return "N_OUT_" + model.config.get_project_name() + +def get_axi_wrapper_type(tensorVar): + return f"{tensorVar.type.name}_packet" + +def get_axi_wrapper_dec(tensorVar): + return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {get_axi_wrapper_type(tensorVar)};" + + +######################################################## +## axi_wrapper.h & axi_wrapper.cpp function helper #### +######################################################## +##### variable +def getWrapperPortNameLocal(tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_local" + +def getWrapperTmpName(tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_tmp" + +def getWrapperIsLastCnt(idx): + return f"isLastCnt_{str(idx)}" \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py new file mode 100644 index 0000000000..66c535736c --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -0,0 +1,45 @@ +import os +from pathlib import Path +import stat +from shutil import copyfile + +from meta import VitisUnifiedWriterMeta +import meta_gen as mg + +################################################################################ +###### main function ########################################################### +################################################################################ + + +def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): + + inp_axi_t, out_axi_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + indent = ' ' + + ###################################### + ###### start write myproject_dm.cpp ## + ###################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../templates/vitis/myproject_dm.cpp'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') + + for line in fin.readlines(): + + if "MY_PROJECT_AXI_INC" in line: + line = line.replace("MY_PROJECT_AXI_INC", mg.getAxiWrapperFileName(model)) + elif "DMX_BUF_IN_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_sz())) + elif "DMX_BUF_OUT_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_sz())) + elif "load_input" in line: + line = line.replace("ATOMIC_TYPE", inp_axi_t) + elif "load_output" in line: + line = line.replace("ATOMIC_TYPE", out_axi_t) + elif "MY_PROJECT_CON" in line: + line = line.replace("MY_PROJECT_CON", mg.getAxisTopFuncName(model)) + fout.write(line) + + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/stream_gen.py b/hls4ml/writer/vitis_unified_writer/stream_gen.py new file mode 100644 index 0000000000..ac27028a3a --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/stream_gen.py @@ -0,0 +1,316 @@ +import os +from meta import VitisUnifiedWriterMeta +import meta_gen as mg + + +def write_axi_wrapper_io(meta: VitisUnifiedWriterMeta, inps, outs): + inputList = [] + outputList = [] + for inp in inps: + streamType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else "dma_data_packet" + inputList.append(f'hls::stream<{streamType}>& {mg.getWrapperPortName(inp, True)}') + for out in outs: + streamType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else "dma_data_packet" + outputList.append(f'hls::stream<{streamType}> & {mg.getWrapperPortName(out, False)}') + + if len(inputList) == 0 or len(outputList) == 0: + raise Exception("No input or output stream found") + newline = "/////// inputs\n" + ",\n ".join(inputList) + ",\n\n ///outputs\n " + ", ".join(outputList) + "\n" + return newline +##### content in axi_wrapper.cpp +def write_axi_wrapper_interface(meta: VitisUnifiedWriterMeta, model, inps, outs): + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline = '' + indent = " " + for inp in inps: + portname = mg.getWrapperPortName(inp, True) + newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' + for out in outs: + portname = mg.getWrapperPortName(out, False) + newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' + if model.config.get_config_value("IOType") == 'io_stream': + newline += indent + '#pragma HLS INTERFACE ap_ctrl_none port=return\n' + newline += indent + '#pragma HLS DATAFLOW\n' + return newline + else: + raise Exception("vitis_unified supports only axi_stream @ interface retriever") + +def write_axi_local_vars(meta: VitisUnifiedWriterMeta, model, inps, outs): + + ####### build local stream variable + + newline = '///// wrinting local stream vars /////\n' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + indent = " " + ##### loop to build local stream to send data into the system + newline += '///////// build input vars ///////////\n' + for idx, inp in enumerate(inps): + newline += f" bool {mg.getWrapperIsLastCnt(idx)} = false;\n" + portname = mg.getWrapperPortNameLocal(inp, True) + newline += indent + f'hls::stream<{inp.type.name}> {portname}("{portname}");\n' + newline += '///////// build output vars ///////////\n' + for out in outs: + portname = mg.getWrapperPortNameLocal(out, False) + newline += indent + f'hls::stream<{out.type.name}> {portname}("{portname}");\n' + + ####### set stream DEPTH + + newline += '///////// set the stream depth ///////////\n' + ##### loop to set depth + + for inpIdx, inp in enumerate(inps): + portname = mg.getWrapperPortNameLocal(inp, True) + newline += indent + f'#pragma HLS STREAM variable={portname} depth={inps[inpIdx].pragma[1]}\n' + for outIdx, out in enumerate(outs): + portname = mg.getWrapperPortNameLocal(out, False) + newline += indent + f'#pragma HLS STREAM variable={portname} depth={model.get_output_variables()[outIdx].pragma[1]}\n' + + return newline + + else: + raise Exception("vitis_unified supports only axi_stream @ local vars") + + +def write_axi_wrapper_each_enqueue(meta: VitisUnifiedWriterMeta, model, inps, idx): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'dma_data_packet {mg.getWrapperTmpName(inps[idx], True)};\n' + newline += indent + f"{mg.getWrapperTmpName(inps[idx], True)}.last = 0;\n" + ### newline += indent + f'{inps[idx].type.name}\n' + newline += indent + f'for(unsigned i = 0; i < {mg.get_inputSizeArrName(model)}[' +str(idx) +']/' + inps[idx].type.name + '::size; ++i){\n' + newline += indent + indent + inps[idx].type.name + ' ctype;\n' + newline += indent + indent + 'for(unsigned j = 0; j < '+ inps[idx].type.name + '::size; ++j){\n' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline += indent + indent + indent + mg.getWrapperPortName(inps[idx], True) + f'.read({mg.getWrapperTmpName(inps[idx], True)});\n' + newline += indent + indent + indent + "ctype[j] = " + mg.getWrapperTmpName(inps[idx], True) + ".data;\n" + newline += indent + indent + indent + mg.getWrapperIsLastCnt(idx) + " = " + mg.getWrapperTmpName(inps[idx], True) + ".last;\n" + else: + raise Exception("vitis_unified supports only axi_stream @ each enqueue") + + newline += indent + indent + '}\n' + newline += indent + indent + mg.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" + newline += indent + '}\n' + newline += indent + mg.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" + + else: + raise Exception("vitis_unified supports only io_stream @ each enqueue") + + return newline + +def write_free_axi_wrapper_each_enqueue(meta: VitisUnifiedWriterMeta, model, inps, idx): + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'{mg.get_axi_wrapper_type(inps[idx])} {mg.getWrapperTmpName(inps[idx], True)};\n' + newline += indent + f"{mg.getWrapperTmpName(inps[idx], True)}.last = 0;\n" + newline += indent + f'for(unsigned i = 0; i < {mg.get_inputSizeArrName(model)}[' + str(idx) + ']/' + inps[ + idx].type.name + '::size; ++i){\n' + newline += indent + indent + inps[idx].type.name + ' ctype;\n' + newline += indent + indent + mg.getWrapperPortName(inps[idx], True) + f'.read({mg.getWrapperTmpName(inps[idx], True)});\n' + newline += indent + indent + "ctype = " + mg.getWrapperTmpName(inps[idx], True) + ".data;\n" + newline += indent + indent + mg.getWrapperIsLastCnt(idx) + " = " + mg.getWrapperTmpName(inps[idx], True) + ".last;\n" + newline += indent + indent + mg.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" + newline += indent + '}\n' + newline += indent + mg.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" + else: + raise Exception("vitis_unified supports only io_stream @ each free axi enqueue") + + return newline + +def write_axi_wrapper_dequeue(meta: VitisUnifiedWriterMeta, model, inputs, outs, idx, out_axi_t): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'dma_data_packet {mg.getWrapperTmpName(outs[idx], False)};\n' + newline += indent + f"{mg.getWrapperTmpName(outs[idx], False)}.last = 0;\n" + ####### the tmp must copy from input to prevent dma get stuck + newline += indent + f'for(unsigned i = 0; i < {mg.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' + newline += indent + indent + outs[idx].type.name + ' ctype = ' + mg.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' + newline += indent + indent + 'for(unsigned j = 0; j < ' + outs[idx].type.name + '::size; ++j){\n' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline += indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f'.data = ({out_axi_t}) (ctype[j]);\n' + poolLastCondition = " & ".join([mg.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) + newline += indent + indent + indent + f"if({poolLastCondition}){{\n" + newline += indent + indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f".last = (((i+1)*(j+1))=={mg.get_outputSizeArrName(model)}[{str(idx)}]);\n" + newline += indent + indent + indent + "}\n" + newline += indent + indent + indent + mg.getWrapperPortName(outs[idx], False) + f'.write({mg.getWrapperTmpName(outs[idx], False)});\n' + newline += indent + indent + "}\n" + newline += indent + "}\n" + newline += indent + mg.getWrapperTmpName(outs[idx], False) + ".last = 0;\n" + else: + raise Exception("vitis_unified supports only axi_stream @ each dequeue") + else: + raise Exception("vitis_unified supports only io_stream @ each dequeue") + + return newline + +def write_free_axi_wrapper_dequeue(meta: VitisUnifiedWriterMeta, model, inputs, outs, idx, out_axi_t): + + io_type = model.config.get_config_value("IOType") + indent = " " + newline = "\n\n\n" + if io_type == 'io_stream': + newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' + newline += indent + "///// temp var \n" + newline += indent + f'{mg.get_axi_wrapper_type(outs[idx])} {mg.getWrapperTmpName(outs[idx], False)};\n' + newline += indent + f"{mg.getWrapperTmpName(outs[idx], False)}.last = 0;\n" + ####### the tmp must copy from input to prevent dma get stuck + newline += indent + f'for(unsigned i = 0; i < {mg.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' + newline += indent + indent + outs[idx].type.name + ' ctype = ' + mg.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' + newline += indent + indent + mg.getWrapperTmpName(outs[idx], False) + ".data = ctype;\n" + poolLastCondition = " & ".join([mg.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) + newline += indent + indent + f"if({poolLastCondition}){{\n" + newline += indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f".last = ((i+1) == ({mg.get_outputSizeArrName(model)}[{str(idx)}] / {outs[idx].type.name + '::size'} ));\n" + newline += indent + indent + "}\n" + newline += indent + indent + mg.getWrapperPortName(outs[idx],False) + f'.write({mg.getWrapperTmpName(outs[idx], False)});\n' + newline += indent + "}\n" + else: + raise Exception("vitis_unified supports only io_stream @ each dequeue") + + return newline + +def write_axi_wrapper_insert_call(meta, model, inps, outs): + io_type = model.config.get_config_value("IOType") + indent = " " + newline = indent + f'{model.config.get_project_name()}' + "(" + inputList = [] + outputList = [] + for inp in inps: + inputList.append(mg.getWrapperPortNameLocal(inp, True)) + for out in outs: + outputList.append(mg.getWrapperPortNameLocal(out, False)) + newline += ", ".join(inputList) + ", " + ", ".join(outputList) + ");\n" + return newline + +######################################################## +##### main function #################################### +######################################################## + +def write_axi_wrapper(meta: VitisUnifiedWriterMeta, model): + ''' + We we want to have multi io system + ''' + inp_axi_t, out_axi_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + indent = ' ' + + print("------------------------------- input write wrapper is -------------------------") + print([inp.name for inp in inps]) + print(model.inputs) + print("------------------------------- output write wrapper is -------------------------") + print([out.name for out in outs]) + print(model.outputs) + print("-----------------------------------------------------------------------------------") + + ###################### + # myproject_axi.h + ###################### + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_axi.h')) + fout = open(f'{model.config.get_output_dir()}/firmware/{mg.getAxiWrapperFileName(model)}.h', 'w') + + for line in f.readlines(): + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{model.config.get_project_name()}.h"\n' + newline += '#include "ap_axi_sdata.h"\n' + elif 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + elif '// hls-fpga-machine-learning insert definitions' in line: + + ##### make input + newline = '' + inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" + newline += f'constexpr unsigned {mg.get_inputSizeArrName(model)} [{len(inps)}] = {inputSizeStr};\n' + + ##### make output + outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" + newline += f'constexpr unsigned {mg.get_outputSizeArrName(model)} [{len(outs)}] = {outputSizeStr};\n' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline += 'typedef hls::axis dma_data_packet;\n' + else: + newline += f'typedef {inp_axi_t} input_axi_t;\n' + newline += f'typedef {out_axi_t} output_axi_t;\n' + #### incase the io is interim input + if meta.vitis_unified_config.isFreeInterimInput(): + for inp in inps: + newline += mg.get_axi_wrapper_dec(inp) + "\n" + #### incase the io is interim output + if meta.vitis_unified_config.isFreeInterimOutput(): + for out in outs: + newline += mg.get_axi_wrapper_dec(out) + "\n" + elif '// hls-fpga-machine-learning insert multi-io' in line: + newline = '' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline += write_axi_wrapper_io(meta, inps, outs) + else: + raise Exception("vitis_unified supports only axi_stream") + + else: + newline = line + + #### TODO add stream + + fout.write(newline) + f.close() + fout.close() + + ###################### + # myproject_axi.cpp + ###################### + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_axi.cpp')) + fout = open(f'{model.config.get_output_dir()}/firmware/{mg.getAxiWrapperFileName(model)}.cpp', 'w') + + io_type = model.config.get_config_value("IOType") + + for line in f.readlines(): + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + elif '// hls-fpga-machine-learning insert include' in line: + newline = f'#include "{model.config.get_project_name()}_axi.h"\n' + elif '// hls-fpga-machine-learning insert multiIo' in line: + newline = '' + if meta.vitis_unified_config.get_interface() == 'axi_stream': + newline += write_axi_wrapper_io(meta, inps, outs) + else: + raise Exception("vitis_unified supports only axi_stream") + elif '// hls-fpga-machine-learning insert interface' in line: + newline = write_axi_wrapper_interface(meta, model, inps, outs) + elif '// hls-fpga-machine-learning insert local vars' in line: + newline = write_axi_local_vars(meta, model, inps, outs) + elif '// hls-fpga-machine-learning insert enqueue' in line: + newline = '' + if meta.vitis_unified_config.isFreeInterimInput(): + for idx, inp in enumerate(inps): + newline += write_free_axi_wrapper_each_enqueue(meta, model, inps, idx) + '\n' + else: + for idx, inp in enumerate(inps): + newline += write_axi_wrapper_each_enqueue(meta, model, inps, idx) + '\n' + elif '// hls-fpga-machine-learning insert call' in line: + newline = '////// call the main variable\n' + newline += write_axi_wrapper_insert_call(meta, model, inps, outs) + elif '// hls-fpga-machine-learning insert dequeue' in line: + newline = '' + if meta.vitis_unified_config.isFreeInterimOutput(): + for idx, out in enumerate(outs): + newline += write_free_axi_wrapper_dequeue(meta, model, inps, outs, idx, out_axi_t) + else: + for idx, out in enumerate(outs): + newline += write_axi_wrapper_dequeue(meta, model, inps, outs, idx, out_axi_t) + else: + newline = line + fout.write(newline) + f.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py new file mode 100644 index 0000000000..7706e4373e --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -0,0 +1,232 @@ +import os +from meta import VitisUnifiedWriterMeta +import meta_gen as mg + +def write_bridge_multigraph(meta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') + model_inputs = model.graphs[0].get_input_variables() + model_outputs = model.graphs[-1].get_output_variables() + model_brams = [var for var in model.graphs[0].get_weight_variables() if var.storage.lower() == 'bram'] + + indent = ' ' + + for line in f.readlines(): + newline = '' + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + elif 'firmware/myproject' in line: + for graph_idx, g in enumerate(model.graphs): + newline += '#undef DEFINES_H_\n' + if len(g.outputs) == 1: + newline += '#define result_t ' + 'result_graph' + str(graph_idx + 1) + '_t\n' + newline += line.replace('myproject', format(model.graphs[graph_idx].config.get_project_name())) + if len(g.outputs) == 1: + newline += ( + 'typedef result_graph' + str(graph_idx + 1) + '_t graph' + str(graph_idx + 1) + '_result_t;\n' + ) + newline += '#undef result_t\n\n' if graph_idx < len(model.graphs) - 1 else '\n' + newline += '\n' + elif 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) + + 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() + inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) + outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) + + newline = '' + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + '\n' + + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + newline = '' + for inp in model_inputs: + + if meta.vitis_unified_config.isFreeInterimInput(): + newline += indent + f"hls::stream<{inp.type.name}> {meta.getWrapperPortName(inp, True)};\n" + newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + srcType =dtype, + underlying_data_T=inp.type.name, + data_T=meta.get_axi_wrapper_type(inp), + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=meta.getWrapperPortName(inp, True), + ) + else: + newline += indent + f"hls::stream<{meta.getDmaTypeName()}> " + meta.getWrapperPortName(inp, True) + ";\n" + newline += indent + "nnet::convert_data<{dtype}, {dtype}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + dtype=dtype, + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=meta.getWrapperPortName(inp, True), + ) + + # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( + # dtype, i.type.name, i.size_cpp(), i.name, i.name + #) + newline += '\n' + + + for idx, g in enumerate(model.graphs): + for out in g.get_output_variables(): + outStreamName = meta.getWrapperPortName(out, False) + outStreamType = meta.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else meta.getDmaTypeName() + newline += indent + f"hls::stream<{outStreamType}> {outStreamName}(\"{outStreamName}\");\n" + # definition = o.definition_cpp(name_suffix='_ap') + # if len(g.outputs) == 1: + # parts = definition.split(' ', 1) + # datatype = 'graph' + str(idx + 1) + '_result_t' + # if parts[0].startswith('hls::stream'): + # modified_definition = 'hls::stream<' + datatype + '> ' + parts[1] + # else: + # modified_definition = datatype + ' ' + parts[1] + # newline += indent + f"{modified_definition};\n" + # else: + # newline += indent + f"{definition};\n" + + newline += '\n' + + top_level = '' + myOutputNextInput = [] + #output_vars = '' + for idx, g in enumerate(model.graphs): + # if idx == 0: + # input_vars = ','.join([i.name + '_ap' for i in g.get_input_variables()]) + # else: + # input_vars = output_vars + # bram_vars = ','.join( + # [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] + # ) + # output_vars = ','.join([o.name + '_ap' for o in g.get_output_variables()]) + # # Concatenate the input, output, and bram variables. Filter out empty/null values + if idx == 0: + input_vars = [meta.getWrapperPortName(inp, True) for inp in g.get_input_variables()] + else: + input_vars = myOutputNextInput.copy() + + output_vars = [meta.getWrapperPortName(out, False) for out in g.get_output_variables()] + myOutputNextInput = output_vars.copy() + bram_vars = [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] + allArgs = input_vars + output_vars + bram_vars + all_vars = ', '.join(allArgs) + top_level += indent + f"{g.config.get_project_name()}_axi({all_vars});\n" + newline += top_level + + newline += '\n' + + for outIdx, o in enumerate(model_outputs): + # if len(model.graphs[-1].outputs) == 1: + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # datatype, dtype, o.size_cpp(), o.name, o.name + # ) + # else: + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # o.type.name, dtype, o.size_cpp(), o.name, o.name + # ) + if meta.vitis_unified_config.isFreeInterimOutput(): + newline += indent + (f"nnet::convert_data_pkt<{dtype}, {o.type.name}, " + f"{meta.get_outputSizeArrName(model)}[{str(outIdx)}]>" + f"({meta.getWrapperPortName(o, False)}, {o.name});\n") + else: + newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {str(o.size())}>" + f"({meta.getWrapperPortName(o, False)}, {o.name});\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): + vars = layer.get_variables() + for var in vars: + 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' + + elif '// hls-fpga-machine-learning insert tb_input_writer' in line: + funcs = [ + ("float", "dump_tb_inputs_float"), + ("double", "dump_tb_inputs_double"), + ] + newline = "" + for dtype, funcname in funcs: + newline += f'void {funcname}(\n' + newline += ' const char* output_path' + for inp in model_inputs: + newline += f',\n {dtype} {inp.name}[{inp.size_cpp()}]' + newline += '\n) {\n\n' + + for inp in model_inputs: + decl = inp.definition_cpp(name_suffix='_ap').strip() + ap = inp.name + "_ap" + if decl.startswith("hls::stream"): + newline += f' {decl};\n' + else: + newline += f' {inp.type.name} {ap}[{inp.size_cpp()}];\n' + newline += ( + f' nnet::convert_data<{dtype}, {inp.type.name}, {inp.size_cpp()}>' f'({inp.name}, {ap});\n' + ) + newline += "\n" + newline += f' std::ofstream fout(std::string(output_path) + "/{inp.name}_input_data.txt");\n' + + for inp in model_inputs: + decl = inp.definition_cpp(name_suffix='_ap').strip() + dims = inp.shape + + if decl.startswith("hls::stream"): + if len(dims) == 1: + N = dims[0] + newline += f' for(int i = 0; i < {N}; i++) {{\n' + newline += f' auto temp = {inp.name}_ap.read();\n' + newline += ( + f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[0].range();\n' + ) + newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' + newline += ' }\n' + else: + inputs_list = model.nn_config['inputs'] + fifo_depth = next((e['fifo_depth'] for e in inputs_list if e['name'] == inp.name), None) + batch_size = next((e['batch_size'] for e in inputs_list if e['name'] == inp.name), None) + newline += f' for(int r = 0; r < {fifo_depth}; r++) {{\n' + newline += f' auto temp = {inp.name}_ap.read();\n' + newline += f' for(int c = 0; c < {batch_size}; c++) {{\n' + newline += ( + f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[c].range();\n' + ) + newline += ( + f' fout << bits.to_uint()' f' << (c+1<{batch_size} ? \' \' : \'\\n\');\n' + ) + newline += ' }\n' + newline += ' }\n' + else: + ap = inp.name + "_ap" + N = inp.size_cpp() + newline += f' for(int i = 0; i < {N}; i++) {{\n' + newline += f' ap_uint<{inp.type.name}::width> bits = ' f'{ap}[i].range();\n' + newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' + newline += ' }\n' + newline += " fout.close();\n" + newline += "}\n" + else: + newline = line + fout.write(newline) + + f.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py new file mode 100644 index 0000000000..1aa09797bb --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -0,0 +1,252 @@ +import os +from meta import VitisUnifiedWriterMeta +import meta_gen as mg + +def write_wrapper_test(meta, model): + + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_test.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + + 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 partial backend\n") + + for line in f.readlines(): + indent = ' ' * (len(line) - len(line.lstrip(' '))) + + #Insert numbers + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + 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 + offset = 0 + for inputIdx, inp in enumerate(model_inputs): + streamPktType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else mg.getDmaTypeName() + + newline += " hls::stream<{desType}> {inputPortName};\n".format( + desType = streamPktType, inputPortName = mg.getWrapperPortName(inp, True) + ) + if meta.vitis_unified_config.isFreeInterimInput(): + newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( + underlyType = inp.type.name, + wrapType=streamPktType, + offset=offset, + inputSize=str(inp.size()), + inputPortName=mg.getWrapperPortName(inp, True) + ) + else: + newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( + destype = streamPktType, offset=offset, inputSize=str(inp.size()), + inputPortName=mg.getWrapperPortName(inp, True) + ) + offset += inp.size() + for out in model_outputs: + streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() + newline += ' ' + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(out, False)};\n" + + elif '// hls-fpga-machine-learning insert top-level-function' in line: + newline = line + + input_vars = ','.join([mg.getWrapperPortName(inp, True) for inp in model_inputs]) + output_vars = ','.join([mg.getWrapperPortName(out, False) for out in model_outputs]) + bram_vars = ','.join([b.name for b in model_brams]) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) + + top_level = indent + f'{mg.getTopModelName(model)}({all_vars});\n' + + newline += top_level + elif '// hls-fpga-machine-learning insert predictions' in line: + newline = line + for outIdx, out in enumerate(model_outputs): + #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 tb-output' in line: + # newline = line + # tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + # if tb_stream != 'stdout': + # for outIdx, out in enumerate(model_outputs): + # # newline += indent + 'nnet::print_result<{}, {}>({}, fout);\n'.format( + # # out.type.name, out.size_cpp(), out.name + # # ) # TODO enable this + # newline += indent + 'nnet::print_result<{actualType}, {dmaType}, {arrName}[{arrSize}]>({portName}, fout);\n'.format( + # actualType = out.type.name, dmaType = mg.getDmaTypeName(), arrName = mg.get_outputSizeArrName(model),arrSize = str(outIdx), portName = mg.getWrapperPortName(out, False) + # ) # TODO enable this + elif '// hls-fpga-machine-learning insert zero' in line: + newline = line + for inpIdx, inp in enumerate(model_inputs): + streamPktType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else mg.getDmaTypeName() + fillZeroFunc = "fill_zero_toArr" if meta.vitis_unified_config.isFreeInterimInput() else "fill_zero" + newline += " " + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(inp, True)};\n" + newline += " " + (f'nnet::{fillZeroFunc}<{inp.type.name}, {streamPktType},{mg.get_inputSizeArrName(model)}[{str(inpIdx)}]>' + f'({mg.getWrapperPortName(inp,True)});\n') + for out in model_outputs: + #newline += indent + out.definition_cpp() + ';\n' + streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() + newline += " " + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(out, False)};\n" + + elif ( + '// hls-fpga-machine-learning insert output' in line + or '// hls-fpga-machine-learning insert quantized' in line + or '// hls-fpga-machine-learning insert tb-output' in line + ): + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' + keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" + #keep_output = str(tb_stream != 'stdout').lower() # We keep output if we need to write it to file too. + if tb_stream != 'file': ### it mean cout + for outIdx, out in enumerate(model_outputs): + # newline += indent + 'nnet::print_result<{}, {}>({}, std::cout, {});\n'.format( + # out.type.name, out.size_cpp(), out.name, keep_output + # ) + streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() + + newline += (indent + 'nnet::print_result<{actualType}, {pktType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + .format( actualType = out.type.name, + pktType = streamPktType, + arrName = mg.get_outputSizeArrName(model), + arrIdx = str(outIdx), + portName = mg.getWrapperPortName(out, False), + des = dest, + keepOutput = keep_output)) + + 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) + f.close() + fout.close() + + + #################################################### + ### write myproject_bridge.cpp ##################### + #################################################### + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') + + 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 f.readlines(): + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + + elif 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) + + 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() + inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) + outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) + + newline = '' + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + '\n' + + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + newline = '' + for inpIdx, inp in enumerate(model_inputs): ## former is i + if meta.vitis_unified_config.isFreeInterimInput(): + newline += indent + f"hls::stream<{inp.type.name}> {mg.getWrapperPortName(inp, True)};\n" + newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( + srcType =dtype, + underlying_data_T=inp.type.name, + data_T=mg.get_axi_wrapper_type(inp), + sz=str(inp.size()), + inpRaw=inp.name, + inp_wrapper=mg.getWrapperPortName(inp, True), + ) + else: + newline += indent + f"hls::stream {mg.getWrapperPortName(inp, True)};\n" + newline += indent + f"nnet::convert_data<{dtype}, {dtype}, {mg.get_inputSizeArrName(model)}[{str(inpIdx)}]>({inp.name}, {mg.getWrapperPortName(inp, True)});\n" + # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( + # dtype, i.type.name, i.size_cpp(), i.name, i.name + # ) + newline += '\n' + + for out in model_outputs: + #newline += indent + '{var};\n'.format(var=o.definition_cpp(name_suffix='_ap')) + outStreamType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() + newline += indent + f"hls::stream<{outStreamType}> {mg.getWrapperPortName(out, False)};\n" + + newline += '\n' + + input_vars = ','.join([mg.getWrapperPortName(inp, True)for inp in model_inputs]) + bram_vars = ','.join([b.name for b in model_brams]) + output_vars = ','.join([mg.getWrapperPortName(out, False) for out in model_outputs]) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) + + top_level = indent + f'{mg.getTopModelName(model)}({all_vars});\n' + newline += top_level + + newline += '\n' + + for outIdx, out in enumerate(model_outputs): + # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( + # o.type.name, dtype, o.size_cpp(), o.name, o.name + # ) + if meta.vitis_unified_config.isFreeInterimOutput(): + newline += indent + f"nnet::convert_data_pkt<{dtype}, {out.type.name}, {mg.get_outputSizeArrName(model)}[{str(outIdx)}]>({mg.getWrapperPortName(out, False)}, {out.name});\n" + else: + newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {mg.get_axi_wrapper_type(out)},{mg.get_outputSizeArrName(model)}[{str(outIdx)}]>" + f"({mg.getWrapperPortName(out, False)}, {out.name});\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): + vars = layer.get_variables() + for var in vars: + 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) + + f.close() + fout.close() \ No newline at end of file From 1169bf4908cb3d9d311b60662a7a74666f37c918 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 16:53:02 +0200 Subject: [PATCH 05/70] extract writer class + add gmem wrapper --- hls4ml/templates/vitis_unified/myproject_dm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 9d872ee623..b6abcb4591 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -17,7 +17,7 @@ static void load_input(ATOMIC_TYPE* in, hls::stream& inStream, } } -static void store_result(float* out, hls::stream& out_stream, int size) { +static void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int size) { mem_wr: for (int i = 0; i < size; i++) { #pragma HLS PIPELINE II=1 From a772aeb98dc063dd52eb84d0659db963e0de2b79 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 16:53:50 +0200 Subject: [PATCH 06/70] fix store value override --- hls4ml/writer/vitis_unified_writer/mm_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index 66c535736c..f250800773 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -34,7 +34,7 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_sz())) elif "load_input" in line: line = line.replace("ATOMIC_TYPE", inp_axi_t) - elif "load_output" in line: + elif "store_output" in line: line = line.replace("ATOMIC_TYPE", out_axi_t) elif "MY_PROJECT_CON" in line: line = line.replace("MY_PROJECT_CON", mg.getAxisTopFuncName(model)) From 235bc2dfd407876acc8663afe1d942dd81405b60 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 17:32:02 +0200 Subject: [PATCH 07/70] draft write_hls initialization --- .../writer/vitis_unified_writer/__init__.py | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 42421c22dd..a33a085600 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -5,13 +5,22 @@ from hls4ml.writer.vitis_writer import VitisWriter +import build_gen as bg +import meta_gen as mtg +import mm_gen as mmg +import stream_gen as sg +import test_bridge_gen as tbg +import test_cosim_gen as tcg + +from meta import VitisUnifiedWriterMeta + class VitisUnifiedWriter(VitisWriter): def __init__(self): super().__init__() - self.vitis_unified_config = None + self.writer_meta = VitisUnifiedWriterMeta() def write_hls(self, model, is_multigraph=False): @@ -21,13 +30,16 @@ def write_hls(self, model, is_multigraph=False): model.config, model.get_input_variables(), model.get_output_variables() ) super().write_hls(model) - if not is_multigraph: - self.write_board_script(model) - self.write_driver(model) - self.write_wrapper_test(model) - self.write_axi_wrapper(model) - self.modify_build_script(model) - self.write_new_tar(model) - else: - self.write_bridge_multigraph(model) + sg.write_axi_wrapper (self.writer_meta, model) + bg .write_board_script(self.writer_meta, model) + bg .write_driver (self.writer_meta, model) + bg.modify_build_script(self.writer_meta, model) + tcg.write_wrapper_test(self.writer_meta, model) + + + #self.write_new_tar(model) + #if not is_multigraph: + + #else: + # self.write_bridge_multigraph(model) # self.modify_write_build_script_multigraph(model) \ No newline at end of file From 2c5a6e800470ed08f3eac47b18921e242e7bf220 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 18:29:24 +0200 Subject: [PATCH 08/70] fix import bug at VitisUnifiedwriter --- hls4ml/writer/vitis_unified_writer/__init__.py | 16 ++++++++-------- hls4ml/writer/vitis_unified_writer/build_gen.py | 2 +- hls4ml/writer/vitis_unified_writer/mm_gen.py | 4 ++-- hls4ml/writer/vitis_unified_writer/stream_gen.py | 4 ++-- .../vitis_unified_writer/test_bridge_gen.py | 4 ++-- .../vitis_unified_writer/test_cosim_gen.py | 8 ++++---- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index a33a085600..b908672251 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -5,14 +5,14 @@ from hls4ml.writer.vitis_writer import VitisWriter -import build_gen as bg -import meta_gen as mtg -import mm_gen as mmg -import stream_gen as sg -import test_bridge_gen as tbg -import test_cosim_gen as tcg +from . import build_gen as bg +from . import meta_gen as mtg +from . import mm_gen as mmg +from . import stream_gen as sg +from . import test_bridge_gen as tbg +from . import test_cosim_gen as tcg -from meta import VitisUnifiedWriterMeta +from .meta import VitisUnifiedWriterMeta @@ -26,7 +26,7 @@ def write_hls(self, model, is_multigraph=False): from hls4ml.backends import VitisUnifiedConfig - self.vitis_unified_config = VitisUnifiedConfig( + self.writer_meta.vitis_unified_config = VitisUnifiedConfig( model.config, model.get_input_variables(), model.get_output_variables() ) super().write_hls(model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index b4e6079493..f597b4938a 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -72,7 +72,7 @@ def modify_build_script(meta, model): # build_lib.sh ################### - f = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) + f = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') for line in f.readlines(): diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index f250800773..d1441f854d 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -3,8 +3,8 @@ import stat from shutil import copyfile -from meta import VitisUnifiedWriterMeta -import meta_gen as mg +from .meta import VitisUnifiedWriterMeta +from . import meta_gen as mg ################################################################################ ###### main function ########################################################### diff --git a/hls4ml/writer/vitis_unified_writer/stream_gen.py b/hls4ml/writer/vitis_unified_writer/stream_gen.py index ac27028a3a..a6d136a260 100644 --- a/hls4ml/writer/vitis_unified_writer/stream_gen.py +++ b/hls4ml/writer/vitis_unified_writer/stream_gen.py @@ -1,6 +1,6 @@ import os -from meta import VitisUnifiedWriterMeta -import meta_gen as mg +from .meta import VitisUnifiedWriterMeta +from . import meta_gen as mg def write_axi_wrapper_io(meta: VitisUnifiedWriterMeta, inps, outs): diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 7706e4373e..e9a3ad210c 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -1,6 +1,6 @@ import os -from meta import VitisUnifiedWriterMeta -import meta_gen as mg +from .meta import VitisUnifiedWriterMeta +from . import meta_gen as mg def write_bridge_multigraph(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 1aa09797bb..1d17dfb282 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -1,11 +1,11 @@ import os -from meta import VitisUnifiedWriterMeta -import meta_gen as mg +from .meta import VitisUnifiedWriterMeta +from . import meta_gen as mg def write_wrapper_test(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_test.cpp')) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') model_inputs = model.get_input_variables() @@ -142,7 +142,7 @@ def write_wrapper_test(meta, model): ### write myproject_bridge.cpp ##################### #################################################### filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') model_inputs = model.get_input_variables() From fd4f3d6f8441e0974537b3755944445f2e76237f Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 15 Aug 2025 22:45:05 +0200 Subject: [PATCH 09/70] add project generation and .h file generation --- hls4ml/templates/vitis_unified/hls_config.cfg | 6 +- hls4ml/templates/vitis_unified/myproject_dm.h | 9 ++ .../vitis_unified/workspace/vitis-comp.json | 9 ++ .../writer/vitis_unified_writer/__init__.py | 10 +- .../writer/vitis_unified_writer/build_gen.py | 116 +++++++----------- .../writer/vitis_unified_writer/meta_gen.py | 6 + hls4ml/writer/vitis_unified_writer/mm_gen.py | 29 ++++- 7 files changed, 108 insertions(+), 77 deletions(-) create mode 100644 hls4ml/templates/vitis_unified/myproject_dm.h create mode 100644 hls4ml/templates/vitis_unified/workspace/vitis-comp.json diff --git a/hls4ml/templates/vitis_unified/hls_config.cfg b/hls4ml/templates/vitis_unified/hls_config.cfg index 14b164f3ed..6afab50ffe 100644 --- a/hls4ml/templates/vitis_unified/hls_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_config.cfg @@ -4,10 +4,12 @@ part={PART} clock={CLK} clock_uncertainty={CLK_UC} flow_target=vivado +syn.file={OUTDIR}/firmware/{PRJ_NAME}_dm.cpp syn.file={OUTDIR}/firmware/{PRJ_NAME}_axi.cpp syn.file={OUTDIR}/firmware/{PRJ_NAME}.cpp -syn.file_cflags={OUTDIR}/firmware/{PRJ_NAME}_axi.cpp,-std=c++0x -syn.file_cflags={OUTDIR}/firmware/{PRJ_NAME}.cpp,-std=c++0x +syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_DM}.cpp,-std=c++0x +syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_AXIS}.cpp,-std=c++0x +syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp,-std=c++0x syn.top={TOP_NAME} tb.file={OUTDIR}/{PRJ_NAME}_test.cpp tb.file={OUTDIR}/firmware/weights diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h new file mode 100644 index 0000000000..a603eff996 --- /dev/null +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -0,0 +1,9 @@ +#ifndef FILENAME_H +#define FILENAME_H + +#include + + +void MY_PROJECT_TOP_FUNC(ATOMIC_TYPE* in, ATOMIC_TYPE* out, int inSize, int outSize); + +#endif \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/workspace/vitis-comp.json b/hls4ml/templates/vitis_unified/workspace/vitis-comp.json new file mode 100644 index 0000000000..c047eba31c --- /dev/null +++ b/hls4ml/templates/vitis_unified/workspace/vitis-comp.json @@ -0,0 +1,9 @@ +{ + "name": "{HLS_NAME}", + "type": "HLS", + "configuration": { + "componentType": "HLS", + "configFiles": ["{CONFIG_FILE}"], + "work_dir": "unifiedPrj" + } +} \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index b908672251..6c6ae79821 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -30,11 +30,11 @@ def write_hls(self, model, is_multigraph=False): model.config, model.get_input_variables(), model.get_output_variables() ) super().write_hls(model) - sg.write_axi_wrapper (self.writer_meta, model) - bg .write_board_script(self.writer_meta, model) - bg .write_driver (self.writer_meta, model) - bg.modify_build_script(self.writer_meta, model) - tcg.write_wrapper_test(self.writer_meta, model) + mmg.write_gmem_wrapper(self.writer_meta, model) + sg.write_axi_wrapper (self.writer_meta, model) + bg.write_hls_kernel_cfg(self.writer_meta, model) + bg .write_driver (self.writer_meta, model) + tcg.write_wrapper_test (self.writer_meta, model) #self.write_new_tar(model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index f597b4938a..d1a257c60d 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -1,87 +1,65 @@ import os - -def write_board_script(meta, model): - ''' - Write the tcl scripts and kernel sources to create a Vivado IPI project for the VitisAcceleratorIPFlow - ''' - ### I am not sure yet what it is - # filedir = os.path.dirname(os.path.abspath(__file__)) - # copyfile( - # os.path.join(filedir, self.vitis_accelerator_ip_flow_config.get_tcl_file_path()), - # f'{model.config.get_output_dir()}/design.tcl', - # ) - - ################### - # project.tcl - ################### - f = open(f'{model.config.get_output_dir()}/project.tcl', 'w') - f.write('variable project_name\n') - f.write(f'set project_name "{model.config.get_project_name()}"\n') - f.write('variable backend\n') - f.write('set backend "vitisacceleratoripflowpartial"\n') - f.write('variable part\n') - f.write("set part \"xc7z020clg400-1\"\n") - #f.write(f'set part "{self.vitis_accelerator_ip_flow_config.get_part()}"\n') - f.write('variable clock_period\n') - f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))) - f.write('variable clock_uncertainty\n') - f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '12.5%'))) - f.write('variable version\n') - f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0'))) - # if self.vitis_accelerator_ip_flow_config.get_interface() == 'axi_stream': - # in_bit, out_bit = self.vitis_accelerator_ip_flow_config.get_io_bitwidth() - # f.write(f'set bit_width_hls_output {in_bit}\n') - # f.write(f'set bit_width_hls_input {out_bit}\n') - f.close() - return +from . import meta_gen as mg def write_driver(meta, model): print("[partial reconfig] we are not supporting write_driver this yet") -def modify_build_script(meta, model): - ''' - Modify the build_prj.tcl and build_lib.sh scripts to add the extra wrapper files and set the top function - ''' +def write_hls_kernel_cfg(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - oldfile = f'{model.config.get_output_dir()}/build_prj.tcl' - newfile = f'{model.config.get_output_dir()}/build_prj_axi.tcl' - f = open(oldfile) - fout = open(newfile, 'w') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_config.h'), 'r') + fout = open(f"{model.config.get_output_dir()}/firmware/hls_kernel_config.h", 'w') - for line in f.readlines(): - if 'set_top' in line: - newline = line[:-1] + '_axi\n' # remove the newline from the line end and append _axi for the new top - newline += f'add_files firmware/{model.config.get_project_name()}_axi.cpp -cflags "-std=c++0x"\n' - elif f'{model.config.get_project_name()}_cosim' in line: - newline = line.replace( - f'{model.config.get_project_name()}_cosim', - f'{model.config.get_project_name()}_axi_cosim', - ) - elif '${project_name}.tcl' in line: - newline = line.replace('${project_name}.tcl', '${project_name}_axi.tcl') - else: - newline = line - fout.write(newline) + 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("{UNCERT}", 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", mg.getGemTopFuncName(model)) + if "{FILE_NAME_DM}" in line: + line = line.replace("FILE_NAME_DM", mg.getGmemWrapperFileName(model)) + if "{FILE_NAME_AXIS}" in line: + line = line.replace("FILE_NAME_AXIS", mg.getAxiWrapperFileName(model)) + if "{FILE_NAME_BASE}" in line: + line = line.replace("FILE_NAME_BASE", mg.getMainFileName(model)) - f.close() - fout.close() - os.rename(newfile, oldfile) + fout.write(line) - ################### - # build_lib.sh - ################### + fin.close() + fout.close() - f = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) - fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w') +def build_unified_project_ske(meta, model, workspaceDir = None): + if workspaceDir is None: + workspaceDir = os.path.join(model.config.get_output_dir(), "unifiedWorkspace") + hlsDir = os.path.join(workspaceDir, model.config.get_project_name()) + execDir = os.path.join(str(hlsDir), "unifiedPrj") + vitisComp = os.path.join(str(hlsDir), "vitis-comp.json") - for line in f.readlines(): - line = line.replace('myproject', model.config.get_project_name()) - line = line.replace('mystamp', model.config.get_config_value('Stamp')) + ###### create my own project for this graph + os.makedirs(workspaceDir, exist_ok=True) + os.makedirs(hlsDir , exist_ok=True) + os.makedirs(execDir , exist_ok=True) + ###### create project vitis-comp.json to + fin = open("../../templates/vitis_unified/vitis-comp.json", 'r') + fout = open(vitisComp, 'w') + for line in fin.readlines(): + if "{HLS_NAME}" in line: + line = line.replace("{HLS_NAME}", model.config.get_project_name()) + if "{CONFIG_FILE}" in line: + line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_config.h") fout.write(line) - f.close() + + fin.close() fout.close() + + + def write_new_tar(meta, model): super().write_tar(model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index ae29a865d6..08591433d0 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -12,6 +12,9 @@ def getGmemWrapperFileName(model): def getAxiWrapperFileName(model): return f"{model.config.get_project_name()}_axi" +def getMainFileName(model): + return f"{model.config.get_project_name()}" + ####################################################### ## naming of variable function helper ################# ####################################################### @@ -34,6 +37,9 @@ def getWrapperPortName(tensorVar, isInput: bool): def getTopModelName(model): return f"{model.config.get_project_name()}_axi" +def getGemTopFuncName(model): + return f"{model.config.get_project_name()}_gem" + def getAxisTopFuncName(model): return f"{model.config.get_project_name()}_axi" diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index d1441f854d..30899c5ba5 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -21,7 +21,7 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): ###################################### filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../templates/vitis/myproject_dm.cpp'), 'r') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp'), 'r') fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') for line in fin.readlines(): @@ -38,8 +38,35 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): line = line.replace("ATOMIC_TYPE", out_axi_t) elif "MY_PROJECT_CON" in line: line = line.replace("MY_PROJECT_CON", mg.getAxisTopFuncName(model)) + elif "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("ATOMIC_TYPE* in", f"{inp_axi_t}* in") + line = line.replace("ATOMIC_TYPE* out", f"{out_axi_t}* out") + line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) fout.write(line) + fin.close() + fout.close() + + ###################################### + ###### start write myproject_dm.h ## + ###################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.h'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.h', 'w') + + for line in fin.readlines(): + + if "FILENAME" in line: + line = line.replace("FILENAME", mg.getGmemWrapperFileName(model).upper()) + elif "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("ATOMIC_TYPE* in", f"{inp_axi_t}* in") + line = line.replace("ATOMIC_TYPE* out", f"{out_axi_t}* out") + line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) + + + fout.write(line) + fin.close() fout.close() \ No newline at end of file From 5913c9cfef60aa2d17586a692f33b9fef2716cb0 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 16 Aug 2025 10:44:40 +0200 Subject: [PATCH 10/70] fix generation bug in unified workspace --- .../{hls_config.cfg => hls_kernel_config.cfg} | 6 +-- .../{ => projectName}/vitis-comp.json | 0 .../writer/vitis_unified_writer/__init__.py | 11 +++--- .../writer/vitis_unified_writer/build_gen.py | 38 +++++++++---------- .../writer/vitis_unified_writer/meta_gen.py | 15 ++++++++ hls4ml/writer/vitis_unified_writer/mm_gen.py | 4 +- 6 files changed, 44 insertions(+), 30 deletions(-) rename hls4ml/templates/vitis_unified/{hls_config.cfg => hls_kernel_config.cfg} (81%) rename hls4ml/templates/vitis_unified/workspace/{ => projectName}/vitis-comp.json (100%) diff --git a/hls4ml/templates/vitis_unified/hls_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg similarity index 81% rename from hls4ml/templates/vitis_unified/hls_config.cfg rename to hls4ml/templates/vitis_unified/hls_kernel_config.cfg index 6afab50ffe..8dc3b93b99 100644 --- a/hls4ml/templates/vitis_unified/hls_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -4,9 +4,9 @@ part={PART} clock={CLK} clock_uncertainty={CLK_UC} flow_target=vivado -syn.file={OUTDIR}/firmware/{PRJ_NAME}_dm.cpp -syn.file={OUTDIR}/firmware/{PRJ_NAME}_axi.cpp -syn.file={OUTDIR}/firmware/{PRJ_NAME}.cpp +syn.file={OUTDIR}/firmware/{FILE_NAME_DM}.cpp +syn.file={OUTDIR}/firmware/{FILE_NAME_AXIS}.cpp +syn.file={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_DM}.cpp,-std=c++0x syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_AXIS}.cpp,-std=c++0x syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp,-std=c++0x diff --git a/hls4ml/templates/vitis_unified/workspace/vitis-comp.json b/hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json similarity index 100% rename from hls4ml/templates/vitis_unified/workspace/vitis-comp.json rename to hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 6c6ae79821..6b57a09269 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -30,11 +30,12 @@ def write_hls(self, model, is_multigraph=False): model.config, model.get_input_variables(), model.get_output_variables() ) super().write_hls(model) - mmg.write_gmem_wrapper(self.writer_meta, model) - sg.write_axi_wrapper (self.writer_meta, model) - bg.write_hls_kernel_cfg(self.writer_meta, model) - bg .write_driver (self.writer_meta, model) - tcg.write_wrapper_test (self.writer_meta, model) + mmg.write_gmem_wrapper (self.writer_meta, model) + sg.write_axi_wrapper (self.writer_meta, model) + bg.build_unified_project_ske(self.writer_meta, model) + bg.write_hls_kernel_cfg (self.writer_meta, model) + bg .write_driver (self.writer_meta, model) + tcg.write_wrapper_test (self.writer_meta, model) #self.write_new_tar(model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index d1a257c60d..904ebf6e3a 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -1,4 +1,6 @@ import os +from pathlib import Path + from . import meta_gen as mg @@ -7,8 +9,8 @@ def write_driver(meta, model): def write_hls_kernel_cfg(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_config.h'), 'r') - fout = open(f"{model.config.get_output_dir()}/firmware/hls_kernel_config.h", 'w') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') + fout = open(f"{model.config.get_output_dir()}/hls_kernel_config.cfg", 'w') for line in fin.readlines(): if "{PART}" in line: @@ -16,17 +18,18 @@ def write_hls_kernel_cfg(meta, model): if "{CLK}" in line: line = line.replace("{CLK}", model.config.get_config_value('ClockPeriod')) if "{CLK_UC}" in line: - line = line.replace("{UNCERT}", model.config.get_config_value('ClockUncertainty')) + line = line.replace("{CLK_UC}", model.config.get_config_value('ClockUncertainty')) if "{OUTDIR}" in line: - line = line.replace("OUTDIR", model.config.get_output_dir()) + line = line.replace("{OUTDIR}", model.config.get_output_dir()) if "{TOP_NAME}" in line: - line = line.replace("TOP_NAME", mg.getGemTopFuncName(model)) + line = line.replace("{TOP_NAME}", mg.getGemTopFuncName(model)) if "{FILE_NAME_DM}" in line: - line = line.replace("FILE_NAME_DM", mg.getGmemWrapperFileName(model)) + line = line.replace("{FILE_NAME_DM}", mg.getGmemWrapperFileName(model)) if "{FILE_NAME_AXIS}" in line: - line = line.replace("FILE_NAME_AXIS", mg.getAxiWrapperFileName(model)) + line = line.replace("{FILE_NAME_AXIS}", mg.getAxiWrapperFileName(model)) if "{FILE_NAME_BASE}" in line: - line = line.replace("FILE_NAME_BASE", mg.getMainFileName(model)) + line = line.replace("{FILE_NAME_BASE}", mg.getMainFileName(model)) + fout.write(line) @@ -35,9 +38,9 @@ def write_hls_kernel_cfg(meta, model): def build_unified_project_ske(meta, model, workspaceDir = None): if workspaceDir is None: - workspaceDir = os.path.join(model.config.get_output_dir(), "unifiedWorkspace") - hlsDir = os.path.join(workspaceDir, model.config.get_project_name()) - execDir = os.path.join(str(hlsDir), "unifiedPrj") + workspaceDir = mg.getVitisUnifiedWorkingDirectoryDir(model) + hlsDir = mg.getVitisHlsDir(model) + execDir = mg.getVitisHlsExecDir(model) vitisComp = os.path.join(str(hlsDir), "vitis-comp.json") ###### create my own project for this graph @@ -45,21 +48,16 @@ def build_unified_project_ske(meta, model, workspaceDir = None): os.makedirs(hlsDir , exist_ok=True) os.makedirs(execDir , exist_ok=True) ###### create project vitis-comp.json to - fin = open("../../templates/vitis_unified/vitis-comp.json", 'r') + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, "../../templates/vitis_unified/workspace/projectName/vitis-comp.json"), 'r') fout = open(vitisComp, 'w') for line in fin.readlines(): if "{HLS_NAME}" in line: line = line.replace("{HLS_NAME}", model.config.get_project_name()) if "{CONFIG_FILE}" in line: - line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_config.h") + line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_kernel_config.cfg") fout.write(line) fin.close() - fout.close() - - - - -def write_new_tar(meta, model): - super().write_tar(model) \ No newline at end of file + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index 08591433d0..2990755cae 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -6,6 +6,10 @@ from shutil import copyfile +####################################################### +## file and directory ################################# +####################################################### + def getGmemWrapperFileName(model): return f"{model.config.get_project_name()}_dm" @@ -15,6 +19,17 @@ def getAxiWrapperFileName(model): def getMainFileName(model): return f"{model.config.get_project_name()}" +def getVitisUnifiedWorkingDirectoryDir(model): + return os.path.join(model.config.get_output_dir(), "unifiedWorkspace") + +def getVitisHlsDir(model): + vitisWorkingDir = getVitisUnifiedWorkingDirectoryDir(model) + return os.path.join(vitisWorkingDir, model.config.get_project_name()) + +def getVitisHlsExecDir(model): + hlsDir = getVitisHlsDir(model) + return os.path.join(hlsDir, "unifiedPrj") + ####################################################### ## naming of variable function helper ################# ####################################################### diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index 30899c5ba5..19b0ccb2d7 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -29,9 +29,9 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): if "MY_PROJECT_AXI_INC" in line: line = line.replace("MY_PROJECT_AXI_INC", mg.getAxiWrapperFileName(model)) elif "DMX_BUF_IN_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_sz())) + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) elif "DMX_BUF_OUT_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_sz())) + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) elif "load_input" in line: line = line.replace("ATOMIC_TYPE", inp_axi_t) elif "store_output" in line: From 8304a20a94a10d621dd0eb480fcf925922f9be6b Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 16 Aug 2025 16:25:34 +0200 Subject: [PATCH 11/70] fix new gmem wrapper to get data and send data at wrong index --- .../templates/vitis_unified/myproject_dm.cpp | 51 +++++++++----- .../workspace/sysProj/vitis-sys.json | 0 .../writer/vitis_unified_writer/meta_gen.py | 21 ++++-- hls4ml/writer/vitis_unified_writer/mm_gen.py | 67 ++++++++++++++++--- 4 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index b6abcb4591..74024d891e 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -8,39 +8,56 @@ #define DMX_BUF_OUT_SZ VAL -static void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int size) { +template +void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int size) { mem_rd: - for (int i = 0; i < size; i++) { + + for (int i = 0; i < size; i = i + INPUT_LAYER_ARR::size) { #pragma HLS PIPELINE II=1 - inStream.data << in[i]; - inStream.last = (i == (size-1)); + INPUT_LAYER_ARR tmp; + for (int j = 0; j < INPUT_LAYER_ARR::size; j++){ + tmp[j] = in[i+j]; + } + inStream.write(tmp); } } -static void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int size) { +template +void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int size) { mem_wr: - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i = i + OUT_LAYER_ARR::size){ #pragma HLS PIPELINE II=1 - out[i] = out_stream.read().data; + OUT_LAYER_ARR tmp = out_stream.read(); + for (int j = 0; j < OUT_LAYER_ARR::size; j++){ + out[i+j] = tmp[j]; + } } } -void MY_PROJECT_TOP_FUNC(ATOMIC_TYPE* in, ATOMIC_TYPE* out, int inSize, int outSize){ +void MY_PROJECT_TOP_FUNC( +// vitis-unified-wrapper-input + +// vitis-unified-wrapper-output + +){ + +// vitis-unified-wrapper-interface + -#pragma HLS INTERFACE m_axi port = in bundle = gmem0 -#pragma HLS INTERFACE m_axi port = out bundle = gmem1 +// vitis-unified-wrapper-stream-dec -static hls::stream in_stream("in_stream") -static hls::stream out_stream("out_stream") -#pragma HLS STREAM variable=in_stream depth=DMX_BUF_IN_SZ -#pragma HLS STREAM variable=out_stream depth=DMX_BUF_OUT_SZ +// vitis-unified-wrapper-stream-config + #pragma HLS dataflow - load_input(in, in_stream, inSize); - MY_PROJECT_CON(in_stream, out_stream); - store_result(out, out_stream, outSize); +// vitis-unified-wrapper-load + +// vitis-unified-wrapper-compute + +// // vitis-unified-wrapper-store + } \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json b/hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index 2990755cae..c2dfa7dc3e 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -16,6 +16,9 @@ def getGmemWrapperFileName(model): def getAxiWrapperFileName(model): return f"{model.config.get_project_name()}_axi" +def getMainWrapperFileName(model): + return model.config.get_project_name() + def getMainFileName(model): return f"{model.config.get_project_name()}" @@ -34,13 +37,17 @@ def getVitisHlsExecDir(model): ## naming of variable function helper ################# ####################################################### -def getGmemTypeName(atomicType: str): - if atomicType not in ["float", "double"]: - raise Exception(f"Unsupported atomic type {atomicType}") - return f"{atomicType}*" +####### FOR GMEM WRAPPER -def getGmemPortName(isInput: bool): - return "in" if isInput else "out" +def getGmemIOPortName(tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"gmem_{ioDirect}{str(idx)}_ptr_{tensorVar.name}" +def getGmemIOPortSizeName(tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"gmem_{ioDirect}{str(idx)}_size_{tensorVar.name}" +def getGmemLocalStreamName(tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" def getDmaTypeName(): return "dma_data_packet" @@ -50,7 +57,7 @@ def getWrapperPortName(tensorVar, isInput: bool): return f"par_{ioStr}_{tensorVar.name}" def getTopModelName(model): - return f"{model.config.get_project_name()}_axi" + return f"{model.config.get_project_name()}" def getGemTopFuncName(model): return f"{model.config.get_project_name()}_gem" diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index 19b0ccb2d7..7381d0c072 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -27,21 +27,66 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): for line in fin.readlines(): if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.getAxiWrapperFileName(model)) + line = line.replace("MY_PROJECT_AXI_INC", mg.getMainWrapperFileName(model)) + if "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) elif "DMX_BUF_IN_SZ" in line: line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) elif "DMX_BUF_OUT_SZ" in line: line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) - elif "load_input" in line: - line = line.replace("ATOMIC_TYPE", inp_axi_t) - elif "store_output" in line: - line = line.replace("ATOMIC_TYPE", out_axi_t) - elif "MY_PROJECT_CON" in line: - line = line.replace("MY_PROJECT_CON", mg.getAxisTopFuncName(model)) - elif "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("ATOMIC_TYPE* in", f"{inp_axi_t}* in") - line = line.replace("ATOMIC_TYPE* out", f"{out_axi_t}* out") - line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) + elif "// vitis-unified-wrapper-input" in line: + inputList = [] + for inp_idx, inp in enumerate(inps): + inputList.append(f"{indent} {inp_axi_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") + inputList.append(f"{indent} int {mg.getGmemIOPortSizeName(inp, True, inp_idx)}") + line += ",\n".join(inputList) + line += ",\n" #### we assume that there is at least one output + elif "// vitis-unified-wrapper-output" in line: + outputList = [] + for out_idx, out in enumerate(outs): + outputList.append(f"{indent} {inp_axi_t}* {mg.getGmemIOPortName(out, False, out_idx)}") + outputList.append(f"{indent} int {mg.getGmemIOPortSizeName(out, False, out_idx)}") + line += ",\n".join(outputList) + line += "\n" + + elif "// vitis-unified-wrapper-interface" in line: + for inp_idx, inp in enumerate(inps): + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" + line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.getGmemIOPortSizeName(inp, True, inp_idx)} bundle = control\n" + for out_idx, out in enumerate(outs): + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(out, False, out_idx)} bundle = gmem_out{out_idx}\n" + line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.getGmemIOPortSizeName(out, False, out_idx)} bundle = control\n" + + + elif "// vitis-unified-wrapper-stream-dec" in line: + + for inp_idx, inp in enumerate(inps): + line += f"{indent} static hls::stream<{inp.type.name}> {mg.getGmemLocalStreamName(inp, True, inp_idx)};\n" + for out_idx, out in enumerate(outs): + line += f"{indent} static hls::stream<{out.type.name}> {mg.getGmemLocalStreamName(out, False, out_idx)};\n" + + elif "// vitis-unified-wrapper-stream-config" in line: + for inp_idx, inp in enumerate(inps): + line += f"#pragma HLS STREAM variable={mg.getGmemLocalStreamName(inp, True, inp_idx)} depth=DMX_BUF_IN_SZ\n" + for out_idx, out in enumerate(outs): + line += f"#pragma HLS STREAM variable={mg.getGmemLocalStreamName(out, False, out_idx)} depth=DMX_BUF_OUT_SZ\n" + + elif "// vitis-unified-wrapper-load" in line: + for inp_idx, inp in enumerate(inps): + line += f"load_input({mg.getGmemIOPortName(inp, True, inp_idx)}, {mg.getGmemLocalStreamName(inp, True, inp_idx)}, {mg.getGmemIOPortSizeName(inp, True, inp_idx)});\n" + elif "// vitis-unified-wrapper-compute" in line: + poolList = [] + for inp_idx, inp in enumerate(inps): + poolList.append(f"{mg.getGmemLocalStreamName(inp, True, inp_idx)}") + for out_idx, out in enumerate(outs): + poolList.append(f"{mg.getGmemLocalStreamName(out, False, out_idx)}") + joinedIo = ", \n".join(poolList) + line += f"{indent} {mg.getTopModelName(model)}({joinedIo});\n" + + elif "// vitis-unified-wrapper-store" in line: + for out_idx, out in enumerate(outs): + line += f"store_result({mg.getGmemIOPortName(out, False, out_idx)}, {mg.getGmemLocalStreamName(out, False, out_idx)}, {mg.getGmemIOPortSizeName(out, False, out_idx)});\n" + fout.write(line) From b979ec0ea62b5421d7af71e248976e7a44e19762 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 16 Aug 2025 17:55:53 +0200 Subject: [PATCH 12/70] add auto platform linker script --- .../vitis_unified/vitis_unified_config.py | 25 +- hls4ml/templates/vitis_unified/build_prj.tcl | 256 ------------------ .../vitis_unified/hls_kernel_config.cfg | 4 +- .../templates/vitis_unified/myproject_dm.cpp | 1 + .../workspace/sysProj/buildAcc.sh | 1 + .../workspace/sysProj/buildConfig.cfg | 2 + .../workspace/sysProj/vitis-sys.json | 0 .../writer/vitis_unified_writer/__init__.py | 8 + .../writer/vitis_unified_writer/build_gen.py | 39 +++ .../writer/vitis_unified_writer/meta_gen.py | 10 + 10 files changed, 79 insertions(+), 267 deletions(-) delete mode 100644 hls4ml/templates/vitis_unified/build_prj.tcl create mode 100644 hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh create mode 100644 hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg delete mode 100644 hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index fa123a2f8e..79054eed82 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -8,15 +8,19 @@ class VitisUnifiedConfig: def __init__(self, config, model_inputs, model_outputs): self.config = config.config - self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') - self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) + # self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') + # self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) self.freeInterimInput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Input") == "io_free_stream" self.freeInterimOutput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Output") == "io_free_stream" - if self.board in self.supported_boards.keys(): - board_info = self.supported_boards[self.board] - self.part = board_info['part'] - else: - raise Exception('The board does not appear in supported_boards.json file') + # if self.board in self.supported_boards.keys(): + # board_info = self.supported_boards[self.board] + # self.part = board_info['part'] + # else: + # raise Exception('The board does not appear in supported_boards.json file') + + self.gmem_in_bufferSz = self.config.get("UnifiedConfig", {}).get("bufInSize", 12) + self.gmem_out_bufferSz = self.config.get("UnifiedConfig", {}).get("bufOutSize", 12) + self.XPFMPath = self.config.get("UnifiedConfig", {}).get("XPFMPath", "") if self.config.get('Part') is not None: if self.config.get('Part') != self.part: @@ -176,7 +180,10 @@ def get_tcl_file_path(self): return '../templates/vitis_accelerator_ip_flow/' + self.board + '/tcl_scripts/' + tcl_script def get_gmem_in_bufferSz(self): - return 12 ###### todo it must get in the config + return self.gmem_in_bufferSz def get_gmem_out_bufferSz(self): - return 12 ###### todo it must get in the config \ No newline at end of file + return self.gmem_out_bufferSz + + def get_XPFMPath(self): + return self.XPFMPath \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/build_prj.tcl b/hls4ml/templates/vitis_unified/build_prj.tcl deleted file mode 100644 index 89906bd4a6..0000000000 --- a/hls4ml/templates/vitis_unified/build_prj.tcl +++ /dev/null @@ -1,256 +0,0 @@ -################# -# HLS4ML -################# -array set opt { - reset 0 - csim 1 - synth 1 - cosim 1 - validation 1 - export 0 - vsynth 0 - fifo_opt 0 -} - -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -proc remove_recursive_log_wave {} { - set tcldir [file dirname [info script]] - source [file join $tcldir project.tcl] - - set filename ${project_name}_prj/solution1/sim/verilog/${project_name}_axi.tcl - set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}] - set temp $filename.new.$timestamp - # set backup $filename.bak.$timestamp - - set in [open $filename r] - set out [open $temp w] - - # line-by-line, read the original file - while {[gets $in line] != -1} { - if {[string equal "$line" "log_wave -r /"]} { - set line { } - } - puts $out $line - } - - close $in - close $out - - # move the new data to the proper filename - file delete -force $filename - file rename -force $temp $filename -} - -proc add_vcd_instructions_tcl {} { - set tcldir [file dirname [info script]] - source [file join $tcldir project.tcl] - - set filename ${project_name}_prj/solution1/sim/verilog/${project_name}_axi.tcl - set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}] - set temp $filename.new.$timestamp - # set backup $filename.bak.$timestamp - - set in [open $filename r] - set out [open $temp w] - - # line-by-line, read the original file - while {[gets $in line] != -1} { - if {[string equal "$line" "log_wave -r /"]} { - set line {source "../../../../project.tcl" - if {[string equal "$backend" "vivadoaccelerator"]} { - current_scope [get_scopes -regex "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi/${project_name}_U0.*"] - set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}] - append scopes { } - current_scope "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi" - append scopes [get_scopes -regexp {(in_local_V_data.*_0_.*)}] - append scopes { } - append scopes [get_scopes -regexp {(out_local_V_data.*_0_.*)}] - } else { - current_scope [get_scopes -regex "/apatb_${project_name}_top/AESL_inst_${project_name}"] - set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}] - } - open_vcd fifo_opt.vcd - foreach scope $scopes { - current_scope $scope - if {[catch [get_objects usedw]] == 0} { - puts "$scope skipped" - continue - } - set usedw [get_objects usedw] - set depth [get_objects DEPTH] - add_wave $usedw - log_vcd $usedw - log_wave $usedw - add_wave $depth - log_vcd $depth - log_wave $depth - } - } - } - - if {[string equal "$line" "quit"]} { - set line {flush_vcd - close_vcd - quit - } - } - # then write the transformed line - puts $out $line - } - - close $in - close $out - - # move the new data to the proper filename - file delete -force $filename - file rename -force $temp $filename -} - -foreach arg $::argv { - foreach o [lsort [array names opt]] { - regexp "$o=+(\\w+)" $arg unused opt($o) - } -} - -proc report_time { op_name time_start time_end } { - set time_taken [expr $time_end - $time_start] - set time_s [expr ($time_taken / 1000) % 60] - set time_m [expr ($time_taken / (1000*60)) % 60] - set time_h [expr ($time_taken / (1000*60*60)) % 24] - puts "***** ${op_name} COMPLETED IN ${time_h}h${time_m}m${time_s}s *****" -} - -# Compare file content: 1 = same, 0 = different -proc compare_files {file_1 file_2} { - # Check if files exist, error otherwise - if {! ([file exists $file_1] && [file exists $file_2])} { - return 0 - } - # Files with different sizes are obviously different - if {[file size $file_1] != [file size $file_2]} { - return 0 - } - - # String compare the content of the files - set fh_1 [open $file_1 r] - set fh_2 [open $file_2 r] - set equal [string equal [read $fh_1] [read $fh_2]] - close $fh_1 - close $fh_2 - return $equal -} - -file mkdir tb_data -set CSIM_RESULTS "./tb_data/csim_results.log" -set RTL_COSIM_RESULTS "./tb_data/rtl_cosim_results.log" - -if {$opt(reset)} { - open_project -reset ${project_name}_prj -} else { - open_project ${project_name}_prj -} -set_top ${project_name}_axi -add_files firmware/${project_name}_axi.cpp -cflags "-std=c++0x" -add_files firmware/${project_name}.cpp -cflags "-std=c++0x" -add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x" - -add_files -tb firmware/weights -add_files -tb tb_data -if {$opt(reset)} { - open_solution -reset "solution1" -} else { - open_solution "solution1" -} -catch {config_array_partition -maximum_size $maximum_size} -config_compile -name_max_length 80 -set_part $part -config_schedule -enable_dsp_full_reg=false -create_clock -period $clock_period -name default -set_clock_uncertainty $clock_uncertainty default - - -if {$opt(csim)} { - puts "***** C SIMULATION *****" - set time_start [clock clicks -milliseconds] - csim_design - set time_end [clock clicks -milliseconds] - report_time "C SIMULATION" $time_start $time_end -} - -if {$opt(synth)} { - puts "***** C/RTL SYNTHESIS *****" - - set time_start [clock clicks -milliseconds] - csynth_design - set time_end [clock clicks -milliseconds] - report_time "C/RTL SYNTHESIS" $time_start $time_end -} - -if {$opt(cosim)} { - puts "***** C/RTL SIMULATION *****" - # TODO: This is a workaround (Xilinx defines __RTL_SIMULATION__ only for SystemC testbenches). - add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x -DRTL_SIM" - set time_start [clock clicks -milliseconds] - - cosim_design -trace_level all -setup - - if {$opt(fifo_opt)} { - puts "\[hls4ml\] - FIFO optimization started" - - if {[string equal "$backend" "vivado"] || [string equal $backend "vivadoaccelerator"]} { - add_vcd_instructions_tcl - } - } - - remove_recursive_log_wave - set old_pwd [pwd] - cd ${project_name}_prj/solution1/sim/verilog/ - source run_sim.tcl - cd $old_pwd - puts "THIS IS MY BACKEND : $backend" - set time_end [clock clicks -milliseconds] - puts "INFO:" - if {[string equal "$backend" "vivadoaccelerator"] || [string equal $backend "vitisacceleratoripflow"] || [string equal $backend "vitisacceleratoripflowpartial"]} { - puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_axi_cosim.rpt r]] - } else { - puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_cosim.rpt r]] - } - report_time "C/RTL SIMULATION" $time_start $time_end -} - -if {$opt(validation)} { - puts "***** C/RTL VALIDATION *****" - if {[compare_files $CSIM_RESULTS $RTL_COSIM_RESULTS]} { - puts "INFO: Test PASSED" - } else { - puts "ERROR: Test failed" - puts "ERROR: - csim log: $CSIM_RESULTS" - puts "ERROR: - RTL-cosim log: $RTL_COSIM_RESULTS" - exit 1 - } -} - -if {$opt(export)} { - puts "***** EXPORT IP *****" - set time_start [clock clicks -milliseconds] - export_design -format ip_catalog -version $version - set time_end [clock clicks -milliseconds] - report_time "EXPORT IP" $time_start $time_end -} - -if {$opt(vsynth)} { - puts "***** VIVADO SYNTHESIS *****" - if {[file exist ${project_name}_prj/solution1/syn/verilog]} { - set time_start [clock clicks -milliseconds] - exec vivado -mode batch -source vivado_synth.tcl >@ stdout - set time_end [clock clicks -milliseconds] - report_time "VIVADO SYNTHESIS" $time_start $time_end - } else { - puts "ERROR: Cannot find generated Verilog files. Did you run C synthesis?" - exit 1 - } -} - -exit diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg index 8dc3b93b99..5b44cca2d5 100644 --- a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -17,7 +17,7 @@ tb.file={OUTDIR}/tb_data tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-std=c++0x tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-DRTL_SIM package.ip.version=1.0.0 -package.output.format=ip_catalog +package.output.format=xo syn.compile.name_max_length=80 syn.schedule.enable_dsp_full_reg=0 -package.output.syn=false \ No newline at end of file +package.output.syn=1 \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 74024d891e..8763d2b196 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -43,6 +43,7 @@ void MY_PROJECT_TOP_FUNC( ){ // vitis-unified-wrapper-interface +#pragma HLS INTERFACE s_axilite port=return bundle=control // vitis-unified-wrapper-stream-dec diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh new file mode 100644 index 0000000000..f03ffd3607 --- /dev/null +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh @@ -0,0 +1 @@ +v++ -l -t hw --platform {PLATFORM_XPFM} {KERNEL_XO} --config buildConfig.cfg -o {PROJECT_NAME}.bin --save-temps \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg new file mode 100644 index 0000000000..de4c339543 --- /dev/null +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg @@ -0,0 +1,2 @@ +[clock] +freqHz={CLK}:{KERNEL_NAME} \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json b/hls4ml/templates/vitis_unified/workspace/sysProj/vitis-sys.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 6b57a09269..24e70420fb 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -32,8 +32,16 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model) mmg.write_gmem_wrapper (self.writer_meta, model) sg.write_axi_wrapper (self.writer_meta, model) + #### for hls kernel generation bg.build_unified_project_ske(self.writer_meta, model) bg.write_hls_kernel_cfg (self.writer_meta, model) + #### for v++ to link hls to the system + bg.write_launch_vitis_linker_dir(self.writer_meta, model) + bg.write_launch_vitis_linker_launcher(self.writer_meta, model) + bg.write_launch_vitis_linker_cfg(self.writer_meta, model) + + + ######### bg .write_driver (self.writer_meta, model) tcg.write_wrapper_test (self.writer_meta, model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 904ebf6e3a..02d69bef2d 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -59,5 +59,44 @@ def build_unified_project_ske(meta, model, workspaceDir = None): line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_kernel_config.cfg") fout.write(line) + fin.close() + fout.close() + +def write_launch_vitis_linker_dir(meta, model): + os.makedirs(mg.getVitisLinkerDir(model), exist_ok=True) + +def write_launch_vitis_linker_launcher(meta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh'), 'r') + fout = open(f"{mg.getVitisLinkerDir(model)}/buildAcc.sh", 'w') + + for line in fin.readlines(): + if "{PLATFORM_XPFM}" in line: + line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.getXPFMPath()) + if "{KERNEL_XO}" in line: + line.replace("{KERNEL_XO}", mg.getXOfilePath(model)) + if "{PROJECT_NAME}" in line: + line.replace("{PROJECT_NAME}", model.config.get_project_name()) + + fout.write(line) + + fin.close() + fout.close() + + + +def write_launch_vitis_linker_cfg(meta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg'), 'r') + fout = open(f"{mg.getVitisLinkerDir(model)}/buildConfig.cfg", 'w') + + for line in fin.readlines(): + if "{CLK}" in line: + line.replace("{CLK}", model.config.get_config_value('ClockPeriod')) + if "{KERNEL_NAME}" in line: + line.replace("{KERNEL_NAME}", mg.getGemTopFuncName(model)) + + fout.write(line) + fin.close() fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index c2dfa7dc3e..064043fb0d 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -33,6 +33,16 @@ def getVitisHlsExecDir(model): hlsDir = getVitisHlsDir(model) return os.path.join(hlsDir, "unifiedPrj") +def getVitisLinkerDir(model): + vitisWorkingDir = getVitisUnifiedWorkingDirectoryDir(model) + return os.path.join(vitisWorkingDir, "linker") + +def getXOfileName(model): + return f"{getGemTopFuncName(model)}.xo" + +def getXOfilePath(model): + return os.path.join(getVitisHlsExecDir(model), getXOfileName(model)) + ####################################################### ## naming of variable function helper ################# ####################################################### From 926f412930f073fe65750e6a0acb7a6e1d653e91 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 16 Aug 2025 18:14:54 +0200 Subject: [PATCH 13/70] add initiat config parameter for io buffer and platform path --- .../vitis_unified/vitis_unified_backend.py | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index b55d873e29..ed53c6fced 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -175,17 +175,21 @@ def build( def create_initial_config( self, - board='pynq-z2', - part=None, - clock_period=5, - clock_uncertainty='12.5%', - io_type='io_parallel', - interface='axi_stream', - driver='python', - input_type='float', - output_type='float', - input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream - output_interim_type='io_stream' + board ='pynq-z2', + part =None, + clock_period =5, + clock_uncertainty ='12.5%', + io_type ='io_parallel', + interface ='axi_stream', + driver ='python', + input_type ='float', + output_type ='float', + gmemBuf_in_size =12, + gmemBuf_out_size =12, + xpfmPath ='/tools/Xilinx/Vitis/2023.2/base_platforms/' + 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', + input_interim_type ='io_stream', #### it should be io_stream or io_free_stream/ io_stream + output_interim_type ='io_stream' ): board = board if board is not None else 'pynq-z2' @@ -205,6 +209,11 @@ def create_initial_config( config['AcceleratorConfig']['Precision']['Input'] = input_type # float, double or ap_fixed config['AcceleratorConfig']['Precision']['Output'] = output_type # float, double or ap_fixed + config['UnifiedConfig'] = {} + config['UnifiedConfig']['bufInSize'] = gmemBuf_in_size + config['UnifiedConfig']['bufOutSize'] = gmemBuf_out_size + config['UnifiedConfig']['XPFMPath'] = xpfmPath + config['MultiGraphConfig'] = {} config['MultiGraphConfig']['IOInterimType'] = {} config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type From b516a9612cca078089958b1fe2dfeb36f6640ccb Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 16 Aug 2025 20:27:19 +0200 Subject: [PATCH 14/70] modifying build function for vitis unified --- .../vitis_unified/vitis_unified_backend.py | 77 ++++++++++--------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index ed53c6fced..b4e697d5e1 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -7,6 +7,8 @@ from hls4ml.model.flow import register_flow from hls4ml.report import parse_vivado_report +from hls4ml.writer.vitis_unified_writer import meta_gen as mg + class VitisUnifiedBackend(VitisBackend): def __init__(self): @@ -15,11 +17,33 @@ def __init__(self): self._register_flows() + def run_term_command(self, model, taskName: str,command: str, logOutput: bool, cwd): + + + output_dir = model.config.get_output_dir() + + out_log_path = os.path.join(output_dir, f'{taskName}_out.log') + err_log_path = os.path.join(output_dir, f'{taskName}_err.log') + out_target = None if logOutput else open(out_log_path, 'w') + err_target = None if logOutput else open(err_log_path, 'w') + + runningProcess = subprocess.Popen( + command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True + ) + runningProcess.communicate() + if runningProcess.returncode != 0: + raise Exception(f'Package failed for {taskName} for project {model.config.get_project_name()}. See logs for details.') + + stdout, stderr = runningProcess.communicate() + return stdout, stderr + + + def build( self, model, reset=False, - csim=True, + csim=False, synth=True, cosim=False, validation=False, @@ -35,36 +59,23 @@ def build( if found != 0: raise Exception('Vitis installation not found. Make sure "vitis" is on PATH.') - # build_command = ( - # 'vitis -f build_prj.tcl "reset={reset} csim={csim} synth={synth} cosim={cosim} ' - # 'validation={validation} export={export} vsynth={vsynth} fifo_opt={fifo_opt}"' - # ).format( - # reset=reset, - # csim=csim, - # synth=synth, - # cosim=cosim, - # validation=validation, - # export=export, - # vsynth=vsynth, - # fifo_opt=fifo_opt, - # ) + ##### TODO support this system + if csim: + raise Exception("Current Vitis Unified not support csim. Please set csim=False to run Vitis Unified.") + if validation: + raise Exception("Current Vitis Unified not support validation. Please set validation=False to run Vitis Unified.") + if export: + raise Exception("Current Vitis Unified not support export. Please set export=False to run Vitis Unified.") + if fifo_opt: + raise Exception("Current Vitis Unified not support fifo_opt. Please set fifo_opt=False to run Vitis Unified.") output_dir = model.config.get_output_dir() - ##### build working directory - if not os.path.exists(os.path.join(output_dir,"unifiedPrj")): - os.makedirs(os.path.join(output_dir, "unifiedPrj")) - ##### build command - build_command = ( + csynth_cmd = ( "v++ -c --mode hls --config {configPath} --work_dir unifiedPrj" - ).format(configPath=(os.path.join(output_dir, "hls_config.cfg"))) - - stdout_log = os.path.join(output_dir, 'build_stdout.log') - stderr_log = os.path.join(output_dir, 'build_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') + ).format(configPath=(os.path.join(output_dir, "hls_kernel_config.cfg"))) + csynth_cwd = mg.getVitisHlsDir(model) ##### util template (used in csim/cosim/package) util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" @@ -73,23 +84,15 @@ def build( ##### package command package_command = util_command.format(op="package", configPath=os.path.join(output_dir, "hls_config.cfg")) - pk_out_log_path = os.path.join(output_dir, 'package_out.log') - pk_err_log_path = os.path.join(output_dir, 'package_err.log') - pk_out_target = None if log_to_stdout else open(pk_out_log_path, 'w') - pk_err_target = None if log_to_stdout else open(pk_err_log_path, 'w') + cosim_command = util_command.format(op="cosim", configPath=os.path.join(output_dir, "hls_config_cosim.cfg")) + csim_command = util_command.format(op="csim", configPath=os.path.join(output_dir, "hls_config_csim.cfg")) ##### co-sim command - cosim_command = util_command.format(op="cosim", configPath=os.path.join(output_dir, "hls_config_cosim.cfg")) - #cosim_command += ' --flag "RTL_SIM"' - cos_out_log_path = os.path.join(output_dir, 'cosim_out.log') - cos_err_log_path = os.path.join(output_dir, 'cosim_err.log') - cos_out_target = None if log_to_stdout or (not cosim) else open(cos_out_log_path, 'w') - cos_err_target = None if log_to_stdout or (not cosim) else open(cos_err_log_path, 'w') + ##### c-sim command - csim_command = util_command.format(op="csim", configPath=os.path.join(output_dir, "hls_config_csim.cfg")) # cosim_command += ' --flag "RTL_SIM"' cs_out_log_path = os.path.join(output_dir, 'csim_out.log') cs_err_log_path = os.path.join(output_dir, 'csim_err.log') From 3f6d22405aa18629869856c1de4e1f72c3cca4b2 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 10:20:45 +0200 Subject: [PATCH 15/70] update build function for vitis unified --- .../vitis_unified/vitis_unified_backend.py | 156 +++++++----------- 1 file changed, 61 insertions(+), 95 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index b4e697d5e1..70c9ace913 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -1,6 +1,7 @@ import os import sys import subprocess +from shutil import copy2 from hls4ml.backends import VitisBackend, VivadoBackend @@ -17,25 +18,39 @@ def __init__(self): self._register_flows() - def run_term_command(self, model, taskName: str,command: str, logOutput: bool, cwd): + def run_term_command(self, model, taskName: str,command: str, logStdOut: bool, cwd): + print("-------------------------------------------------------") + print(f"start running task : {taskName}") + print("-------------------------------------------------------") output_dir = model.config.get_output_dir() out_log_path = os.path.join(output_dir, f'{taskName}_out.log') err_log_path = os.path.join(output_dir, f'{taskName}_err.log') - out_target = None if logOutput else open(out_log_path, 'w') - err_target = None if logOutput else open(err_log_path, 'w') + out_target = None if logStdOut else open(out_log_path, 'w') + err_target = None if logStdOut else open(err_log_path, 'w') - runningProcess = subprocess.Popen( - command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True - ) - runningProcess.communicate() - if runningProcess.returncode != 0: - raise Exception(f'Package failed for {taskName} for project {model.config.get_project_name()}. See logs for details.') - stdout, stderr = runningProcess.communicate() - return stdout, stderr + try: + + runningProcess = subprocess.Popen( + command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True + ) + runningProcess.communicate() + if runningProcess.returncode != 0: + raise Exception(f'Package failed for {taskName} for project {model.config.get_project_name()}. See logs for details.') + + stdout, stderr = runningProcess.communicate() + print(f"stdout: {stdout}") + print(f"stderr: {stderr}") + + print(f"task {taskName} finished") + finally: + if out_target: + out_target.close() + if err_target: + err_target.close() @@ -71,110 +86,61 @@ def build( 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 unifiedPrj" - ).format(configPath=(os.path.join(output_dir, "hls_kernel_config.cfg"))) + ).format(configPath=hls_config_file) csynth_cwd = mg.getVitisHlsDir(model) ##### util template (used in csim/cosim/package) util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" + ##### package command + package_cmd = util_command.format(op="package", configPath=hls_config_file) + package_cwd = mg.getVitisHlsDir(model) + cosim_cmd = util_command.format(op="cosim" , configPath=hls_config_file) + cosim_cwd = mg.getVitisHlsDir(model) + csim_cmd = util_command.format(op="csim" , configPath=hls_config_file) + csim_cwd = mg.getVitisHlsDir(model) - ##### package command + kerlink_cmd = "./buildAcc.sh" + kerlink_cwd = mg.getVitisLinkerDir(model) - package_command = util_command.format(op="package", configPath=os.path.join(output_dir, "hls_config.cfg")) - cosim_command = util_command.format(op="cosim", configPath=os.path.join(output_dir, "hls_config_cosim.cfg")) - csim_command = util_command.format(op="csim", configPath=os.path.join(output_dir, "hls_config_csim.cfg")) + if csim or synth or cosim or bitfile : + self.run_term_command(model, "csynth", csynth_cmd, log_to_stdout, csynth_cwd) + self.run_term_command(model, "package", package_cmd, log_to_stdout, package_cwd) - ##### co-sim command + if csim: + self.run_term_command(model, "csim", csim_cmd, log_to_stdout, csim_cwd) + if cosim: + self.run_term_command(model, "cosim", cosim_cmd, log_to_stdout, cosim_cwd) + ##if bitfile + if bitfile: + self.run_term_command(model, "kerlink", kerlink_cmd, log_to_stdout, kerlink_cwd) + ### dump the output + exportPath = os.path.join(output_dir, "export") + os.makedirs(exportPath, exist_ok=True) + srcBitFile = os.path.join(mg.getVitisLinkerDir(model), + f"{model.config.get_project_name()}.bin") + #"_x/link/vivado/vpl/prj/prj.runs/impl_1/vitis_design_wrapper.bin") + srcHwhFile = os.path.join(mg.getVitisLinkerDir(model), + "_x/link/vivado/vpl/prj/prj.runs/impl_1/vitis_design_wrapper.hwh") + desBitFile = os.path.join(exportPath, "system.bin") + desHwhFile = os.path.join(exportPath, "system.hwh") + print("copy src bit file to des bit file: ", srcBitFile, " to ", desBitFile) + copy2(str(srcBitFile), desBitFile) + print("copy src hwh file to des hwh file: ", srcHwhFile, " to ", desHwhFile) + copy2(srcHwhFile, desHwhFile) - ##### c-sim command - # cosim_command += ' --flag "RTL_SIM"' - cs_out_log_path = os.path.join(output_dir, 'csim_out.log') - cs_err_log_path = os.path.join(output_dir, 'csim_err.log') - cs_out_target = None if log_to_stdout or (not csim) else open(cs_out_log_path, 'w') - cs_err_target = None if log_to_stdout or (not csim) else open(cs_err_log_path, 'w') - try: - if synth: - print("---------------------------------------------------") - print("----------- start build command ---------------") - print("---------------------------------------------------") - ##### run build project - process = subprocess.Popen( - build_command, shell=True, cwd=output_dir, 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()}. See logs for details.') - ##### run package project - print("---------------------------------------------------") - print("----------- start package command ---------------") - print("---------------------------------------------------") - - packageProcess = subprocess.Popen( - package_command, shell=True, cwd=output_dir, stdout=pk_out_target, stderr=pk_err_target, text=True - ) - packageProcess.communicate() - if packageProcess.returncode != 0: - raise Exception(f'Package failed for {model.config.get_project_name()}. See logs for details.') - - if cosim: - print("---------------------------------------------------") - print("----------- start cosim command ---------------") - print("---------------------------------------------------") - cosimProcess = subprocess.Popen( - cosim_command, shell=True, cwd=output_dir, stdout=cos_out_target, stderr=cos_err_target, text=True - ) - cosimProcess.communicate() - if cosimProcess.returncode != 0: - raise Exception(f'Cosim failed for {model.config.get_project_name()}. See logs for details.') - - if csim: - print("---------------------------------------------------") - print("----------- start csim command ---------------") - print("---------------------------------------------------") - csimProcess = subprocess.Popen( - csim_command, shell=True, cwd=output_dir, stdout=cs_out_target, stderr=cs_err_target, text=True - ) - csimProcess.communicate() - if csimProcess.returncode != 0: - raise Exception(f'Csim failed for {model.config.get_project_name()}. See logs for details.') - finally: - if not log_to_stdout: - if synth: - stdout_target.close() - stderr_target.close() - pk_out_target.close() - pk_err_target.close() - - if cosim: - cos_out_target.close() - cos_err_target.close() - - if csim: - cs_out_target.close() - cs_err_target.close() - - # now make a bitfile - if bitfile: - curr_dir = os.getcwd() - os.chdir(model.config.get_output_dir()) - try: - os.system('vivado -mode batch -source design.tcl') # check if this is accepted as a command - except Exception: - print("Something went wrong, check the Vivado logs") - os.chdir(curr_dir) - - return parse_vivado_report(model.config.get_output_dir()) def create_initial_config( self, From 19e0af91e55b8414e66cfe4fd25bbd275d68726f Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 11:28:20 +0200 Subject: [PATCH 16/70] add bridge simulation --- .../vitis_unified/myproject_bridge.cpp | 2 +- .../writer/vitis_unified_writer/__init__.py | 3 + .../vitis_unified_writer/test_bridge_gen.py | 226 ++++-------------- 3 files changed, 50 insertions(+), 181 deletions(-) diff --git a/hls4ml/templates/vitis_unified/myproject_bridge.cpp b/hls4ml/templates/vitis_unified/myproject_bridge.cpp index 20009e5b4f..9a56f10d99 100644 --- a/hls4ml/templates/vitis_unified/myproject_bridge.cpp +++ b/hls4ml/templates/vitis_unified/myproject_bridge.cpp @@ -1,7 +1,7 @@ #ifndef MYPROJECT_BRIDGE_H_ #define MYPROJECT_BRIDGE_H_ -#include "firmware/myproject_axi.h" +#include "firmware/PROJECT_FILE_NAME.h" #include "firmware/nnet_utils/nnet_helpers.h" #include #include diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 24e70420fb..1ce9084fee 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -22,6 +22,9 @@ def __init__(self): super().__init__() self.writer_meta = VitisUnifiedWriterMeta() + def write_bridge(self, model): + tbg.write_bridge(self.writer_meta, model) + def write_hls(self, model, is_multigraph=False): from hls4ml.backends import VitisUnifiedConfig diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index e9a3ad210c..e203378068 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -2,35 +2,28 @@ from .meta import VitisUnifiedWriterMeta from . import meta_gen as mg -def write_bridge_multigraph(meta, model): +def write_bridge(meta: VitisUnifiedWriterMeta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fin = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') - model_inputs = model.graphs[0].get_input_variables() - model_outputs = model.graphs[-1].get_output_variables() - model_brams = [var for var in model.graphs[0].get_weight_variables() if var.storage.lower() == 'bram'] + + 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 f.readlines(): - newline = '' + for line in fin.readlines(): if 'MYPROJECT' in line: newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - elif 'firmware/myproject' in line: - for graph_idx, g in enumerate(model.graphs): - newline += '#undef DEFINES_H_\n' - if len(g.outputs) == 1: - newline += '#define result_t ' + 'result_graph' + str(graph_idx + 1) + '_t\n' - newline += line.replace('myproject', format(model.graphs[graph_idx].config.get_project_name())) - if len(g.outputs) == 1: - newline += ( - 'typedef result_graph' + str(graph_idx + 1) + '_t graph' + str(graph_idx + 1) + '_result_t;\n' - ) - newline += '#undef result_t\n\n' if graph_idx < len(model.graphs) - 1 else '\n' - newline += '\n' + elif 'myproject' in line: newline = line.replace('myproject', format(model.config.get_project_name())) + elif 'PROJECT_FILE_NAME' in line: + newline = line.replace('PROJECT_FILE_NAME', format(mg.getGmemWrapperFileName(model))) + elif '// hls-fpga-machine-learning insert bram' in line: newline = line for bram in model_brams: @@ -38,8 +31,18 @@ def write_bridge_multigraph(meta, model): elif '// hls-fpga-machine-learning insert header' in line: dtype = line.split('#', 1)[1].strip() - inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) - outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) + input_ios = [] + output_ios = [] + + for idx, inp in enumerate(model_inputs): + input_ios.append(f"{dtype} {mg.getGmemIOPortName(inp, True, idx)}[{inp.size_cpp()}]") + input_ios.append(f"int {mg.getGmemIOPortSizeName(inp, True, idx)}") + for idx, out in enumerate(model_outputs): + output_ios.append(f"{mg.getGmemIOPortName(out, False, idx)}[{out.size_cpp()}]") + output_ios.append(f"int {mg.getGmemIOPortSizeName(out, False, idx)}") + + inputs_str = ', '.join(input_ios) + outputs_str = ', '.join(output_ios) newline = '' newline += indent + inputs_str + ',\n' @@ -48,97 +51,24 @@ def write_bridge_multigraph(meta, model): elif '// hls-fpga-machine-learning insert wrapper' in line: dtype = line.split('#', 1)[1].strip() newline = '' - for inp in model_inputs: - - if meta.vitis_unified_config.isFreeInterimInput(): - newline += indent + f"hls::stream<{inp.type.name}> {meta.getWrapperPortName(inp, True)};\n" - newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - srcType =dtype, - underlying_data_T=inp.type.name, - data_T=meta.get_axi_wrapper_type(inp), - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=meta.getWrapperPortName(inp, True), - ) - else: - newline += indent + f"hls::stream<{meta.getDmaTypeName()}> " + meta.getWrapperPortName(inp, True) + ";\n" - newline += indent + "nnet::convert_data<{dtype}, {dtype}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - dtype=dtype, - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=meta.getWrapperPortName(inp, True), - ) - - # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( - # dtype, i.type.name, i.size_cpp(), i.name, i.name - #) - newline += '\n' - - - for idx, g in enumerate(model.graphs): - for out in g.get_output_variables(): - outStreamName = meta.getWrapperPortName(out, False) - outStreamType = meta.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else meta.getDmaTypeName() - newline += indent + f"hls::stream<{outStreamType}> {outStreamName}(\"{outStreamName}\");\n" - # definition = o.definition_cpp(name_suffix='_ap') - # if len(g.outputs) == 1: - # parts = definition.split(' ', 1) - # datatype = 'graph' + str(idx + 1) + '_result_t' - # if parts[0].startswith('hls::stream'): - # modified_definition = 'hls::stream<' + datatype + '> ' + parts[1] - # else: - # modified_definition = datatype + ' ' + parts[1] - # newline += indent + f"{modified_definition};\n" - # else: - # newline += indent + f"{definition};\n" - - newline += '\n' - - top_level = '' - myOutputNextInput = [] - #output_vars = '' - for idx, g in enumerate(model.graphs): - # if idx == 0: - # input_vars = ','.join([i.name + '_ap' for i in g.get_input_variables()]) - # else: - # input_vars = output_vars - # bram_vars = ','.join( - # [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] - # ) - # output_vars = ','.join([o.name + '_ap' for o in g.get_output_variables()]) - # # Concatenate the input, output, and bram variables. Filter out empty/null values - if idx == 0: - input_vars = [meta.getWrapperPortName(inp, True) for inp in g.get_input_variables()] - else: - input_vars = myOutputNextInput.copy() - - output_vars = [meta.getWrapperPortName(out, False) for out in g.get_output_variables()] - myOutputNextInput = output_vars.copy() - bram_vars = [b.name for b in [var for var in g.get_weight_variables() if var.storage.lower() == 'bram']] - allArgs = input_vars + output_vars + bram_vars - all_vars = ', '.join(allArgs) - top_level += indent + f"{g.config.get_project_name()}_axi({all_vars});\n" - newline += top_level - - newline += '\n' - - for outIdx, o in enumerate(model_outputs): - # if len(model.graphs[-1].outputs) == 1: - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # datatype, dtype, o.size_cpp(), o.name, o.name - # ) - # else: - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # o.type.name, dtype, o.size_cpp(), o.name, o.name - # ) - if meta.vitis_unified_config.isFreeInterimOutput(): - newline += indent + (f"nnet::convert_data_pkt<{dtype}, {o.type.name}, " - f"{meta.get_outputSizeArrName(model)}[{str(outIdx)}]>" - f"({meta.getWrapperPortName(o, False)}, {o.name});\n") - else: - newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {str(o.size())}>" - f"({meta.getWrapperPortName(o, False)}, {o.name});\n") + + input_vars = [] + output_vars = [] + + for idx, inp in enumerate(model_inputs): + input_vars.append(mg.getGmemIOPortName(inp, True, idx)) + input_vars.append(mg.getGmemIOPortSizeName(inp, True, idx)) + for idx, out in enumerate(model_outputs): + output_vars.append(mg.getGmemIOPortName(out, False, idx)) + output_vars.append(mg.getGmemIOPortSizeName(out, False, idx)) + + inputs_str = ', '.join(input_vars) + outputs_str = ', '.join(output_vars) + + newline = '' + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + '\n' + elif '// hls-fpga-machine-learning insert trace_outputs' in line: newline = '' @@ -148,9 +78,9 @@ def write_bridge_multigraph(meta, model): vars = layer.get_variables() for var in vars: newline += ( - indent - + 'nnet::trace_outputs->insert(std::pair(' - + f'"{layer.name}", (void *) malloc({var.size_cpp()} * element_size)));\n' + 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: @@ -160,73 +90,9 @@ def write_bridge_multigraph(meta, model): if namespace is not None: newline += indent + f'using namespace {namespace};\n' - elif '// hls-fpga-machine-learning insert tb_input_writer' in line: - funcs = [ - ("float", "dump_tb_inputs_float"), - ("double", "dump_tb_inputs_double"), - ] - newline = "" - for dtype, funcname in funcs: - newline += f'void {funcname}(\n' - newline += ' const char* output_path' - for inp in model_inputs: - newline += f',\n {dtype} {inp.name}[{inp.size_cpp()}]' - newline += '\n) {\n\n' - - for inp in model_inputs: - decl = inp.definition_cpp(name_suffix='_ap').strip() - ap = inp.name + "_ap" - if decl.startswith("hls::stream"): - newline += f' {decl};\n' - else: - newline += f' {inp.type.name} {ap}[{inp.size_cpp()}];\n' - newline += ( - f' nnet::convert_data<{dtype}, {inp.type.name}, {inp.size_cpp()}>' f'({inp.name}, {ap});\n' - ) - newline += "\n" - newline += f' std::ofstream fout(std::string(output_path) + "/{inp.name}_input_data.txt");\n' - - for inp in model_inputs: - decl = inp.definition_cpp(name_suffix='_ap').strip() - dims = inp.shape - - if decl.startswith("hls::stream"): - if len(dims) == 1: - N = dims[0] - newline += f' for(int i = 0; i < {N}; i++) {{\n' - newline += f' auto temp = {inp.name}_ap.read();\n' - newline += ( - f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[0].range();\n' - ) - newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' - newline += ' }\n' - else: - inputs_list = model.nn_config['inputs'] - fifo_depth = next((e['fifo_depth'] for e in inputs_list if e['name'] == inp.name), None) - batch_size = next((e['batch_size'] for e in inputs_list if e['name'] == inp.name), None) - newline += f' for(int r = 0; r < {fifo_depth}; r++) {{\n' - newline += f' auto temp = {inp.name}_ap.read();\n' - newline += f' for(int c = 0; c < {batch_size}; c++) {{\n' - newline += ( - f' ap_uint<{inp.type.name}::value_type::width> bits = ' f'temp[c].range();\n' - ) - newline += ( - f' fout << bits.to_uint()' f' << (c+1<{batch_size} ? \' \' : \'\\n\');\n' - ) - newline += ' }\n' - newline += ' }\n' - else: - ap = inp.name + "_ap" - N = inp.size_cpp() - newline += f' for(int i = 0; i < {N}; i++) {{\n' - newline += f' ap_uint<{inp.type.name}::width> bits = ' f'{ap}[i].range();\n' - newline += f' fout << bits.to_uint()' f' << (i+1<{N} ? \' \' : \'\\n\');\n' - newline += ' }\n' - newline += " fout.close();\n" - newline += "}\n" else: newline = line fout.write(newline) - f.close() + fin.close() fout.close() \ No newline at end of file From 32d079b361f16c00df270f6bc6802f19627dbfa0 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 12:08:46 +0200 Subject: [PATCH 17/70] add bridge script and move a bit bridge generator --- hls4ml/templates/vitis_unified/build_lib.sh | 4 ++-- .../writer/vitis_unified_writer/__init__.py | 19 +++++++++++-------- .../writer/vitis_unified_writer/build_gen.py | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh index 74f026f543..ea0963f994 100644 --- a/hls4ml/templates/vitis_unified/build_lib.sh +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -24,7 +24,7 @@ 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/${PROJECT}_axi.cpp -o ${PROJECT}_axi.o +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c firmware/${PROJECT}_dm.cpp -o ${PROJECT}_dm.o ${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o ${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_axi.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so -rm -f *.o +rm -f *.o \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 1ce9084fee..12c43aa8c0 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -25,6 +25,17 @@ def __init__(self): def write_bridge(self, model): tbg.write_bridge(self.writer_meta, model) + def write_build_script(self, model): + #### for bridge simulation + bg.write_bridge_build_script(self.writer_meta, model) + #### for hls kernel generation + bg.build_unified_project_ske(self.writer_meta, model) + bg.write_hls_kernel_cfg(self.writer_meta, model) + #### for v++ to link hls to the system + bg.write_launch_vitis_linker_dir(self.writer_meta, model) + bg.write_launch_vitis_linker_launcher(self.writer_meta, model) + bg.write_launch_vitis_linker_cfg(self.writer_meta, model) + def write_hls(self, model, is_multigraph=False): from hls4ml.backends import VitisUnifiedConfig @@ -35,14 +46,6 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model) mmg.write_gmem_wrapper (self.writer_meta, model) sg.write_axi_wrapper (self.writer_meta, model) - #### for hls kernel generation - bg.build_unified_project_ske(self.writer_meta, model) - bg.write_hls_kernel_cfg (self.writer_meta, model) - #### for v++ to link hls to the system - bg.write_launch_vitis_linker_dir(self.writer_meta, model) - bg.write_launch_vitis_linker_launcher(self.writer_meta, model) - bg.write_launch_vitis_linker_cfg(self.writer_meta, model) - ######### bg .write_driver (self.writer_meta, model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 02d69bef2d..9b9befcf2f 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -2,11 +2,27 @@ from pathlib import Path +from .meta import VitisUnifiedWriterMeta from . import meta_gen as mg def write_driver(meta, model): print("[partial reconfig] we are not supporting write_driver this yet") + +def write_bridge_build_script(meta: VitisUnifiedWriterMeta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) + fout = open(f"{model.config.get_output_dir()}/build_lib.sh", 'w') + + for line in fin.readlines(): + if 'myproject' in line: + line = line.replace('myproject', format(model.config.get_project_name())) + + fout.write(line) + + fin.close() + fout.close() + def write_hls_kernel_cfg(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') From 9237af56f4a513efeae28eaa82c21c4936e97ec0 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 13:42:13 +0200 Subject: [PATCH 18/70] change build script permission and refactoring cosim writing --- .../writer/vitis_unified_writer/build_gen.py | 5 + .../vitis_unified_writer/test_cosim_gen.py | 114 ------------------ 2 files changed, 5 insertions(+), 114 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 9b9befcf2f..0f192b8413 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -1,4 +1,5 @@ import os +import stat from pathlib import Path @@ -23,6 +24,10 @@ def write_bridge_build_script(meta: VitisUnifiedWriterMeta, model): fin.close() fout.close() + #### change permission + 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_cfg(meta, model): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 1d17dfb282..6dfd5a0a02 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -136,117 +136,3 @@ def write_wrapper_test(meta, model): fout.write(newline) f.close() fout.close() - - - #################################################### - ### write myproject_bridge.cpp ##################### - #################################################### - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp', 'w') - - 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 f.readlines(): - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - - elif 'myproject' in line: - newline = line.replace('myproject', format(model.config.get_project_name())) - - 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() - inputs_str = ', '.join([f'{dtype} {i.name}[{i.size_cpp()}]' for i in model_inputs]) - outputs_str = ', '.join([f'{dtype} {o.name}[{o.size_cpp()}]' for o in model_outputs]) - - newline = '' - newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + '\n' - - elif '// hls-fpga-machine-learning insert wrapper' in line: - dtype = line.split('#', 1)[1].strip() - newline = '' - for inpIdx, inp in enumerate(model_inputs): ## former is i - if meta.vitis_unified_config.isFreeInterimInput(): - newline += indent + f"hls::stream<{inp.type.name}> {mg.getWrapperPortName(inp, True)};\n" - newline += indent + "nnet::convert_data_pkt<{srcType}, {underlying_data_T}, {data_T}, {sz}>({inpRaw}, {inp_wrapper});\n".format( - srcType =dtype, - underlying_data_T=inp.type.name, - data_T=mg.get_axi_wrapper_type(inp), - sz=str(inp.size()), - inpRaw=inp.name, - inp_wrapper=mg.getWrapperPortName(inp, True), - ) - else: - newline += indent + f"hls::stream {mg.getWrapperPortName(inp, True)};\n" - newline += indent + f"nnet::convert_data<{dtype}, {dtype}, {mg.get_inputSizeArrName(model)}[{str(inpIdx)}]>({inp.name}, {mg.getWrapperPortName(inp, True)});\n" - # newline += indent + '{var};\n'.format(var=i.definition_cpp(name_suffix='_ap')) - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}, {}_ap);\n'.format( - # dtype, i.type.name, i.size_cpp(), i.name, i.name - # ) - newline += '\n' - - for out in model_outputs: - #newline += indent + '{var};\n'.format(var=o.definition_cpp(name_suffix='_ap')) - outStreamType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() - newline += indent + f"hls::stream<{outStreamType}> {mg.getWrapperPortName(out, False)};\n" - - newline += '\n' - - input_vars = ','.join([mg.getWrapperPortName(inp, True)for inp in model_inputs]) - bram_vars = ','.join([b.name for b in model_brams]) - output_vars = ','.join([mg.getWrapperPortName(out, False) for out in model_outputs]) - - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) - - top_level = indent + f'{mg.getTopModelName(model)}({all_vars});\n' - newline += top_level - - newline += '\n' - - for outIdx, out in enumerate(model_outputs): - # newline += indent + 'nnet::convert_data<{}, {}, {}>({}_ap, {});\n'.format( - # o.type.name, dtype, o.size_cpp(), o.name, o.name - # ) - if meta.vitis_unified_config.isFreeInterimOutput(): - newline += indent + f"nnet::convert_data_pkt<{dtype}, {out.type.name}, {mg.get_outputSizeArrName(model)}[{str(outIdx)}]>({mg.getWrapperPortName(out, False)}, {out.name});\n" - else: - newline += indent + (f"nnet::convert_data<{dtype}, {dtype}, {mg.get_axi_wrapper_type(out)},{mg.get_outputSizeArrName(model)}[{str(outIdx)}]>" - f"({mg.getWrapperPortName(out, False)}, {out.name});\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): - vars = layer.get_variables() - for var in vars: - 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) - - f.close() - fout.close() \ No newline at end of file From bd6a384bb488d4eb066978a2a085a8e1ee1cbc2e Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 15:20:31 +0200 Subject: [PATCH 19/70] add cosim testbench + fix namming in gmem --- hls4ml/writer/vitis_unified_writer/mm_gen.py | 10 +- .../vitis_unified_writer/test_cosim_gen.py | 101 +++++++----------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index 7381d0c072..43e1732b6f 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -13,7 +13,7 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): - inp_axi_t, out_axi_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() indent = ' ' ###################################### @@ -37,14 +37,14 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): elif "// vitis-unified-wrapper-input" in line: inputList = [] for inp_idx, inp in enumerate(inps): - inputList.append(f"{indent} {inp_axi_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") + inputList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") inputList.append(f"{indent} int {mg.getGmemIOPortSizeName(inp, True, inp_idx)}") line += ",\n".join(inputList) line += ",\n" #### we assume that there is at least one output elif "// vitis-unified-wrapper-output" in line: outputList = [] for out_idx, out in enumerate(outs): - outputList.append(f"{indent} {inp_axi_t}* {mg.getGmemIOPortName(out, False, out_idx)}") + outputList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(out, False, out_idx)}") outputList.append(f"{indent} int {mg.getGmemIOPortSizeName(out, False, out_idx)}") line += ",\n".join(outputList) line += "\n" @@ -106,8 +106,8 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): if "FILENAME" in line: line = line.replace("FILENAME", mg.getGmemWrapperFileName(model).upper()) elif "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("ATOMIC_TYPE* in", f"{inp_axi_t}* in") - line = line.replace("ATOMIC_TYPE* out", f"{out_axi_t}* out") + line = line.replace("ATOMIC_TYPE* in", f"{inp_gmem_t}* in") + line = line.replace("ATOMIC_TYPE* out", f"{out_gmem_t}* out") line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 6dfd5a0a02..89ef867a6d 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -4,6 +4,10 @@ def write_wrapper_test(meta, model): + + #### warning we have to fix to float because the system locked by template + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + filedir = os.path.dirname(os.path.abspath(__file__)) f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') @@ -29,42 +33,36 @@ def write_wrapper_test(meta, model): newline = line offset = 0 for inputIdx, inp in enumerate(model_inputs): - streamPktType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else mg.getDmaTypeName() - - newline += " hls::stream<{desType}> {inputPortName};\n".format( - desType = streamPktType, inputPortName = mg.getWrapperPortName(inp, True) + ##### input should be float + newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + inputPortName=mg.getGmemIOPortName(inp, True, inputIdx), + startIdx=str(offset) ) - if meta.vitis_unified_config.isFreeInterimInput(): - newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( - underlyType = inp.type.name, - wrapType=streamPktType, - offset=offset, - inputSize=str(inp.size()), - inputPortName=mg.getWrapperPortName(inp, True) - ) - else: - newline += ' nnet::copy_data_axi_w_offset(in, {inputPortName});\n'.format( - destype = streamPktType, offset=offset, inputSize=str(inp.size()), - inputPortName=mg.getWrapperPortName(inp, True) - ) offset += inp.size() - for out in model_outputs: - streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() - newline += ' ' + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(out, False)};\n" + for outputIdx, out in enumerate(model_outputs): + newline += f" float {mg.getGmemIOPortName(out, False, outputIdx)}[{out.size()}];\n" + elif '// hls-fpga-machine-learning insert top-level-function' in line: newline = line - input_vars = ','.join([mg.getWrapperPortName(inp, True) for inp in model_inputs]) - output_vars = ','.join([mg.getWrapperPortName(out, False) for out in model_outputs]) - bram_vars = ','.join([b.name for b in model_brams]) + input_ios = [] + output_ios = [] + bram_ios = [b.name for b in model_brams] - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [input_vars, output_vars, bram_vars])) + for inpIdx, inp in enumerate(model_inputs): + input_ios.append(mg.getGmemIOPortName(inp, True, inpIdx)) + input_ios.append(str(inp.size())) - top_level = indent + f'{mg.getTopModelName(model)}({all_vars});\n' + for outIdx, out in enumerate(model_outputs): + output_ios.append(mg.getGmemIOPortName(out, False, outIdx)) + output_ios.append(str(out.size())) + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) + top_level = indent + f'{mg.getGemTopFuncName(model)}({all_vars});\n' newline += top_level + elif '// hls-fpga-machine-learning insert predictions' in line: newline = line for outIdx, out in enumerate(model_outputs): @@ -73,55 +71,34 @@ def write_wrapper_test(meta, model): newline += indent + ' std::cout << pr[i] << " ";\n' newline += indent + '}\n' newline += indent + 'std::cout << std::endl;\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': - # for outIdx, out in enumerate(model_outputs): - # # newline += indent + 'nnet::print_result<{}, {}>({}, fout);\n'.format( - # # out.type.name, out.size_cpp(), out.name - # # ) # TODO enable this - # newline += indent + 'nnet::print_result<{actualType}, {dmaType}, {arrName}[{arrSize}]>({portName}, fout);\n'.format( - # actualType = out.type.name, dmaType = mg.getDmaTypeName(), arrName = mg.get_outputSizeArrName(model),arrSize = str(outIdx), portName = mg.getWrapperPortName(out, False) - # ) # TODO enable this elif '// hls-fpga-machine-learning insert zero' in line: newline = line for inpIdx, inp in enumerate(model_inputs): - streamPktType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else mg.getDmaTypeName() - fillZeroFunc = "fill_zero_toArr" if meta.vitis_unified_config.isFreeInterimInput() else "fill_zero" - newline += " " + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(inp, True)};\n" - newline += " " + (f'nnet::{fillZeroFunc}<{inp.type.name}, {streamPktType},{mg.get_inputSizeArrName(model)}[{str(inpIdx)}]>' - f'({mg.getWrapperPortName(inp,True)});\n') - for out in model_outputs: - #newline += indent + out.definition_cpp() + ';\n' - streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() - newline += " " + f"hls::stream<{streamPktType}> {mg.getWrapperPortName(out, False)};\n" + newline += indent + f'float {mg.getGmemIOPortName(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' + + for outIdx, out in enumerate(model_outputs): + newline += indent + f"float {mg.getGmemIOPortName(out, False, outIdx)}[{str(out.size())}] = {{}};\n" elif ( '// hls-fpga-machine-learning insert output' in line or '// hls-fpga-machine-learning insert quantized' in line or '// hls-fpga-machine-learning insert tb-output' in line ): + newline = line tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - #keep_output = str(tb_stream != 'stdout').lower() # We keep output if we need to write it to file too. - if tb_stream != 'file': ### it mean cout - for outIdx, out in enumerate(model_outputs): - # newline += indent + 'nnet::print_result<{}, {}>({}, std::cout, {});\n'.format( - # out.type.name, out.size_cpp(), out.name, keep_output - # ) - streamPktType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else mg.getDmaTypeName() - - newline += (indent + 'nnet::print_result<{actualType}, {pktType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' - .format( actualType = out.type.name, - pktType = streamPktType, - arrName = mg.get_outputSizeArrName(model), - arrIdx = str(outIdx), - portName = mg.getWrapperPortName(out, False), - des = dest, - keepOutput = keep_output)) + newline += "/// warning keep is forced to be true\n" + + for outIdx, out in enumerate(model_outputs): + newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + .format( actualType = "float", + arrName = mg.get_outputSizeArrName(model), + arrIdx = str(outIdx), + portName = mg.getGmemIOPortName(out, False, outIdx), + des = dest, + keepOutput = keep_output)) elif '// hls-fpga-machine-learning insert namespace' in line: newline = '' From c1b95c9230badf659bdce0447f310d44ed016bee Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 17 Aug 2025 17:51:45 +0200 Subject: [PATCH 20/70] fix wrapper mismatch io bug and testing the bridge simulation --- .../vitis_unified/vitis_unified_config.py | 14 ++--- hls4ml/templates/vitis_unified/build_lib.sh | 2 +- .../templates/vitis_unified/myproject_dm.cpp | 6 +-- hls4ml/templates/vitis_unified/myproject_dm.h | 7 ++- .../vivado/nnet_utils/nnet_helpers.h | 1 + .../writer/vitis_unified_writer/__init__.py | 9 ++++ .../writer/vitis_unified_writer/build_gen.py | 6 ++- hls4ml/writer/vitis_unified_writer/mm_gen.py | 48 +++++++++-------- .../vitis_unified_writer/test_bridge_gen.py | 53 +++++++++++-------- 9 files changed, 88 insertions(+), 58 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index 79054eed82..e57a40cf1d 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -22,13 +22,13 @@ def __init__(self, config, model_inputs, model_outputs): self.gmem_out_bufferSz = self.config.get("UnifiedConfig", {}).get("bufOutSize", 12) self.XPFMPath = self.config.get("UnifiedConfig", {}).get("XPFMPath", "") - if self.config.get('Part') is not None: - if self.config.get('Part') != self.part: - print( - 'WARNING: You set a Part that does not correspond to the Board you specified. The correct ' - 'Part is now set.' - ) - self.config['Part'] = self.part + # if self.config.get('Part') is not None: + # if self.config.get('Part') != self.part: + # print( + # 'WARNING: You set a Part that does not correspond to the Board you specified. The correct ' + # 'Part is now set.' + # ) + # self.config['Part'] = self.part accel_config = self.config.get('AcceleratorConfig', None) if accel_config is not None: prec = accel_config.get('Precision') diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh index ea0963f994..fd7f3c2cdb 100644 --- a/hls4ml/templates/vitis_unified/build_lib.sh +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -26,5 +26,5 @@ 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/${PROJECT}_dm.cpp -o ${PROJECT}_dm.o ${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o -${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_axi.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_dm.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so rm -f *.o \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 8763d2b196..286b9ae9a0 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "ap_axi_sdata.h" +//#include "ap_axi_sdata.h" #include "MY_PROJECT_AXI_INC.h" #define DMX_BUF_IN_SZ VAL @@ -36,9 +36,7 @@ void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int void MY_PROJECT_TOP_FUNC( -// vitis-unified-wrapper-input - -// vitis-unified-wrapper-output +// vitis-unified-wrapper-io ){ diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h index a603eff996..63acb7ac57 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.h +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -4,6 +4,11 @@ #include -void MY_PROJECT_TOP_FUNC(ATOMIC_TYPE* in, ATOMIC_TYPE* out, int inSize, int outSize); +void MY_PROJECT_TOP_FUNC( + +// vitis-unified-wrapper-io + + +); #endif \ No newline at end of file diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h index 225bce181d..655102971d 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace nnet { diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 12c43aa8c0..f569e60cc3 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -22,6 +22,15 @@ def __init__(self): super().__init__() self.writer_meta = VitisUnifiedWriterMeta() + def write_board_script_override(self, model): + pass + def write_build_prj_override(self, model): + pass + def write_build_opts(self, model): + pass + def write_tar(self, model): + pass + def write_bridge(self, model): tbg.write_bridge(self.writer_meta, model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 0f192b8413..5580df9974 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -12,12 +12,14 @@ def write_driver(meta, model): def write_bridge_build_script(meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../templates/vitis_unified/build_lib.sh')) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) fout = open(f"{model.config.get_output_dir()}/build_lib.sh", 'w') for line in fin.readlines(): if 'myproject' in line: line = line.replace('myproject', format(model.config.get_project_name())) + if 'mystamp' in line: + line = line.replace('mystamp', model.config.get_config_value('Stamp')) fout.write(line) @@ -93,7 +95,7 @@ def write_launch_vitis_linker_launcher(meta, model): for line in fin.readlines(): if "{PLATFORM_XPFM}" in line: - line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.getXPFMPath()) + line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.get_XPFMPath()) if "{KERNEL_XO}" in line: line.replace("{KERNEL_XO}", mg.getXOfilePath(model)) if "{PROJECT_NAME}" in line: diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py index 43e1732b6f..09c20c4ac7 100644 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ b/hls4ml/writer/vitis_unified_writer/mm_gen.py @@ -10,6 +10,29 @@ ###### main function ########################################################### ################################################################################ +def genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs): + + inputPtrList = [] + outputPtrList = [] + inputSizeList = [] + outputSizeList = [] + + for inp_idx, inp in enumerate(inps): + inputPtrList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") + inputSizeList.append(f"{indent} int {mg.getGmemIOPortSizeName(inp, True, inp_idx)}") + + for out_idx, out in enumerate(outs): + outputPtrList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(out, False, out_idx)}") + outputSizeList.append(f"{indent} int {mg.getGmemIOPortSizeName(out, False, out_idx)}") + + + line = ", ".join(inputPtrList) + ",\n" + line += ", ".join(outputPtrList) + ",\n" + line += ", ".join(inputSizeList) + ",\n" + line += ", ".join(outputSizeList) + + return line + def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): @@ -34,21 +57,8 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) elif "DMX_BUF_OUT_SZ" in line: line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) - elif "// vitis-unified-wrapper-input" in line: - inputList = [] - for inp_idx, inp in enumerate(inps): - inputList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") - inputList.append(f"{indent} int {mg.getGmemIOPortSizeName(inp, True, inp_idx)}") - line += ",\n".join(inputList) - line += ",\n" #### we assume that there is at least one output - elif "// vitis-unified-wrapper-output" in line: - outputList = [] - for out_idx, out in enumerate(outs): - outputList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(out, False, out_idx)}") - outputList.append(f"{indent} int {mg.getGmemIOPortSizeName(out, False, out_idx)}") - line += ",\n".join(outputList) - line += "\n" - + elif "// vitis-unified-wrapper-io" in line: + line = genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: for inp_idx, inp in enumerate(inps): line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" @@ -56,8 +66,6 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): for out_idx, out in enumerate(outs): line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(out, False, out_idx)} bundle = gmem_out{out_idx}\n" line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.getGmemIOPortSizeName(out, False, out_idx)} bundle = control\n" - - elif "// vitis-unified-wrapper-stream-dec" in line: for inp_idx, inp in enumerate(inps): @@ -106,11 +114,9 @@ def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): if "FILENAME" in line: line = line.replace("FILENAME", mg.getGmemWrapperFileName(model).upper()) elif "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("ATOMIC_TYPE* in", f"{inp_gmem_t}* in") - line = line.replace("ATOMIC_TYPE* out", f"{out_gmem_t}* out") line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) - - + elif "// vitis-unified-wrapper-io" in line: + line += genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" fout.write(line) fin.close() diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index e203378068..8b46384d4c 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -5,7 +5,7 @@ def write_bridge(meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../templates/vitis_unified/myproject_bridge.cpp')) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') model_inputs = model.get_input_variables() @@ -30,16 +30,17 @@ def write_bridge(meta: VitisUnifiedWriterMeta, model): 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 = [] output_ios = [] + for idx, inp in enumerate(model_inputs): input_ios.append(f"{dtype} {mg.getGmemIOPortName(inp, True, idx)}[{inp.size_cpp()}]") - input_ios.append(f"int {mg.getGmemIOPortSizeName(inp, True, idx)}") for idx, out in enumerate(model_outputs): - output_ios.append(f"{mg.getGmemIOPortName(out, False, idx)}[{out.size_cpp()}]") - output_ios.append(f"int {mg.getGmemIOPortSizeName(out, False, idx)}") + output_ios.append(f"{dtype} {mg.getGmemIOPortName(out, False, idx)}[{out.size_cpp()}]") inputs_str = ', '.join(input_ios) outputs_str = ', '.join(output_ios) @@ -50,24 +51,32 @@ def write_bridge(meta: VitisUnifiedWriterMeta, model): elif '// hls-fpga-machine-learning insert wrapper' in line: dtype = line.split('#', 1)[1].strip() - newline = '' - - input_vars = [] - output_vars = [] - - for idx, inp in enumerate(model_inputs): - input_vars.append(mg.getGmemIOPortName(inp, True, idx)) - input_vars.append(mg.getGmemIOPortSizeName(inp, True, idx)) - for idx, out in enumerate(model_outputs): - output_vars.append(mg.getGmemIOPortName(out, False, idx)) - output_vars.append(mg.getGmemIOPortSizeName(out, False, idx)) - - inputs_str = ', '.join(input_vars) - outputs_str = ', '.join(output_vars) - - newline = '' - newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + '\n' + if dtype == 'float': + newline = '' + input_vars = [] + input_sizes = [] + output_vars = [] + otuput_sizes = [] + + for idx, inp in enumerate(model_inputs): + input_vars.append(mg.getGmemIOPortName(inp, True, idx)) + input_sizes.append(inp.size_cpp()) + for idx, out in enumerate(model_outputs): + output_vars.append(mg.getGmemIOPortName(out, False, idx)) + otuput_sizes.append(out.size_cpp()) + + inputs_str = ', '.join(input_vars) + input_size_str = ', '.join(input_sizes) + outputs_str = ', '.join(output_vars) + output_size_str = ', '.join(otuput_sizes) + + newline = '' + newline += indent + mg.getGemTopFuncName(model) + "(\n" + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + ',\n' + newline += indent + input_size_str + ',\n' + newline += indent + output_size_str + '\n' + newline += indent + ");\n" elif '// hls-fpga-machine-learning insert trace_outputs' in line: From 6e37f3c7ebc52bcf57987aea94ab7fa3282d6b6f Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 18 Aug 2025 11:43:51 +0200 Subject: [PATCH 21/70] add .bit file for full flow --- .../vitis_unified/vitis_unified_backend.py | 32 ++++++------------- .../workspace/sysProj/buildAcc.sh | 7 +++- .../workspace/sysProj/buildConfig.cfg | 4 +-- .../writer/vitis_unified_writer/build_gen.py | 17 ++++++---- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 70c9ace913..5ee6c70850 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -18,10 +18,11 @@ def __init__(self): self._register_flows() - def run_term_command(self, model, taskName: str,command: str, logStdOut: bool, cwd): + def run_term_command(self, model, taskName: str, command: str, logStdOut: bool, cwd): print("-------------------------------------------------------") print(f"start running task : {taskName}") + print(f" with command: {command}") print("-------------------------------------------------------") output_dir = model.config.get_output_dir() @@ -31,9 +32,7 @@ def run_term_command(self, model, taskName: str,command: str, logStdOut: bool, c out_target = None if logStdOut else open(out_log_path, 'w') err_target = None if logStdOut else open(err_log_path, 'w') - try: - runningProcess = subprocess.Popen( command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True ) @@ -46,6 +45,11 @@ def run_term_command(self, model, taskName: str,command: str, logStdOut: bool, c print(f"stderr: {stderr}") print(f"task {taskName} finished") + + except Exception as e: + print(f"task {taskName} failed") + print(e) + raise e finally: if out_target: out_target.close() @@ -59,7 +63,7 @@ def build( model, reset=False, csim=False, - synth=True, + synth=False, cosim=False, validation=False, export=False, @@ -107,7 +111,7 @@ def build( kerlink_cmd = "./buildAcc.sh" kerlink_cwd = mg.getVitisLinkerDir(model) - if csim or synth or cosim or bitfile : + if synth: self.run_term_command(model, "csynth", csynth_cmd, log_to_stdout, csynth_cwd) self.run_term_command(model, "package", package_cmd, log_to_stdout, package_cwd) @@ -120,24 +124,6 @@ def build( ##if bitfile if bitfile: self.run_term_command(model, "kerlink", kerlink_cmd, log_to_stdout, kerlink_cwd) - ### dump the output - exportPath = os.path.join(output_dir, "export") - os.makedirs(exportPath, exist_ok=True) - srcBitFile = os.path.join(mg.getVitisLinkerDir(model), - f"{model.config.get_project_name()}.bin") - #"_x/link/vivado/vpl/prj/prj.runs/impl_1/vitis_design_wrapper.bin") - srcHwhFile = os.path.join(mg.getVitisLinkerDir(model), - "_x/link/vivado/vpl/prj/prj.runs/impl_1/vitis_design_wrapper.hwh") - desBitFile = os.path.join(exportPath, "system.bin") - desHwhFile = os.path.join(exportPath, "system.hwh") - print("copy src bit file to des bit file: ", srcBitFile, " to ", desBitFile) - copy2(str(srcBitFile), desBitFile) - print("copy src hwh file to des hwh file: ", srcHwhFile, " to ", desHwhFile) - copy2(srcHwhFile, desHwhFile) - - - - diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh index f03ffd3607..8bed88a2fa 100644 --- a/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh @@ -1 +1,6 @@ -v++ -l -t hw --platform {PLATFORM_XPFM} {KERNEL_XO} --config buildConfig.cfg -o {PROJECT_NAME}.bin --save-temps \ No newline at end of file +v++ -l -t hw --platform {PLATFORM_XPFM} {KERNEL_XO} --config buildConfig.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 \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg index de4c339543..01218a1178 100644 --- a/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg @@ -1,2 +1,2 @@ -[clock] -freqHz={CLK}:{KERNEL_NAME} \ No newline at end of file +[vivado] +gui={GUI_STATUS} \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 5580df9974..7c5dcfb4b8 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -95,17 +95,20 @@ def write_launch_vitis_linker_launcher(meta, model): for line in fin.readlines(): if "{PLATFORM_XPFM}" in line: - line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.get_XPFMPath()) + line = line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.get_XPFMPath()) if "{KERNEL_XO}" in line: - line.replace("{KERNEL_XO}", mg.getXOfilePath(model)) + line = line.replace("{KERNEL_XO}", mg.getXOfilePath(model)) if "{PROJECT_NAME}" in line: - line.replace("{PROJECT_NAME}", model.config.get_project_name()) + line = line.replace("{PROJECT_NAME}", model.config.get_project_name()) fout.write(line) fin.close() fout.close() + link_lib_dst = Path(f"{mg.getVitisLinkerDir(model)}/buildAcc.sh").resolve() + link_lib_dst.chmod(link_lib_dst.stat().st_mode | stat.S_IEXEC) + def write_launch_vitis_linker_cfg(meta, model): @@ -115,10 +118,12 @@ def write_launch_vitis_linker_cfg(meta, model): for line in fin.readlines(): if "{CLK}" in line: - line.replace("{CLK}", model.config.get_config_value('ClockPeriod')) + line = line.replace("{CLK}", str(100_000_000))#model.config.get_config_value('ClockPeriod')) if "{KERNEL_NAME}" in line: - line.replace("{KERNEL_NAME}", mg.getGemTopFuncName(model)) - + line = line.replace("{KERNEL_NAME}", mg.getGemTopFuncName(model)) + if "{GUI_STATUS}" in line: + line = line.replace("{GUI_STATUS}", "true") + line="" fout.write(line) fin.close() From f64b50d99225a3ccf57dab5ec9dfb94f9e727bf0 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 18 Aug 2025 21:23:47 +0200 Subject: [PATCH 22/70] add python generator for the system --- .../vitis_unified/driver/pynq/pynq_driver.py | 69 +++++++++++++++++++ .../writer/vitis_unified_writer/__init__.py | 3 +- .../writer/vitis_unified_writer/build_gen.py | 4 +- .../writer/vitis_unified_writer/driver_gen.py | 55 +++++++++++++++ 4 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py create mode 100644 hls4ml/writer/vitis_unified_writer/driver_gen.py diff --git a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py new file mode 100644 index 0000000000..980883ab7b --- /dev/null +++ b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py @@ -0,0 +1,69 @@ +# 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 +import numpy as np +import os +import subprocess +import re +import time + + +class MyDfxCtrl(DefaultIP): + def __init__(self, description): + super().__init__(description=description) + + self.REG_ADDR_AP_CTRL = 0x00 + + self.INP_PORT_NAMEs = [ + #### hls-driver-input-dbg-name + ] + + self.REG_ADDR_INP_PTRs = [ + #### hls-driver-input-ptr + ] + self.REG_ADDR_INP_SZs = [ + #### hls-driver-input-size + ] + + self.OUT_PORT_NAMEs = [ + #### hls-driver-output-dbg-name + ] + + self.REG_ADDR_OUT_PTRs = [ + #### hls-driver-output-ptr + ] + + self.REG_ADDR_OUT_SZs = [ + #### hls-driver-output-size + ] + + bindto = ['xilinx.com:hls::1.0'] + + ######## TODO interrupt + + + def setSingleBit(self, addr, idx): + self.write(addr, 1 << idx) + + def ctrlStart(self): + self.write(0x00, 0x01) # ap_start = 1 + + def waitUntilDone(self): + while (self.read(0x00) & 0x2) == 0: # Wait for ap_done + time.sleep(0.001) + + def setInput(self, idx, buffer): + + print(f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {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) + self.write(self.REG_ADDR_INP_SZs[idx], buffer.size) + buffer.flush() + + def setOutput(self, idx, buffer): + + print(f"input {self.OUT_PORT_NAMEs[idx]} will be set to addr: {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) + self.write(self.REG_ADDR_OUT_SZs[idx], buffer.size) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index f569e60cc3..3516b7cee0 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -11,6 +11,7 @@ from . import stream_gen as sg from . import test_bridge_gen as tbg from . import test_cosim_gen as tcg +from . import driver_gen as dg from .meta import VitisUnifiedWriterMeta @@ -57,7 +58,7 @@ def write_hls(self, model, is_multigraph=False): sg.write_axi_wrapper (self.writer_meta, model) ######### - bg .write_driver (self.writer_meta, model) + dg .write_driver (self.writer_meta, model) tcg.write_wrapper_test (self.writer_meta, model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 7c5dcfb4b8..409fe31e8e 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -6,8 +6,8 @@ from .meta import VitisUnifiedWriterMeta from . import meta_gen as mg -def write_driver(meta, model): - print("[partial reconfig] we are not supporting write_driver this yet") +# def write_driver(meta, model): +# print("[partial reconfig] we are not supporting write_driver this yet") def write_bridge_build_script(meta: VitisUnifiedWriterMeta, model): diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py new file mode 100644 index 0000000000..ddd12c559c --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -0,0 +1,55 @@ +import os +import stat +from pathlib import Path + + +from .meta import VitisUnifiedWriterMeta +from . import meta_gen as mg + +def write_driver(meta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py'), 'r') + fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') + + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + + strideInPtrAddr = 4*3 + strideOutPtrAddr = 4*3 + strideInSizeAddr = 4*2 + strideOutSizeAddr = 4*2 + + startInPtrAddr = 0x10 + startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) + startInSizeAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) + startOutSizeAddr = startInSizeAddr + strideInSizeAddr * len(inps) + + def genHexAddrList(startAddr, stride, size, indent): + addrs = [f"{indent}{hex(startAddr + inp_idx * stride)}" for inp_idx in range(size)] + return addrs + + indentAmt = 3 + indentStr = indentAmt * " " if indentAmt > 0 else "" + + for line in fin.readlines(): + + if "#### hls-driver-input-dbg-name" in line: + input_names = [ f'{indentStr}"{mg.getGmemIOPortName(inp, True, idx)}"' for idx, inp in enumerate(inps) ] + line += ",\n".join(input_names) + "\n" + if "#### hls-driver-input-ptr" in line: + line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" + if "#### hls-driver-input-size" in line: + line += ",\n".join(genHexAddrList(startInSizeAddr, strideInSizeAddr, len(inps), indentStr)) + "\n" + if "#### hls-driver-output-dbg-name" in line: + output_names = [ f'{indentStr}"{mg.getGmemIOPortName(out, False, idx)}"' for idx, out in enumerate(outs) ] + line += ",\n".join(output_names) + "\n" + if "#### hls-driver-output-ptr" in line: + line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" + if "#### hls-driver-output-size" in line: + line += ",\n".join(genHexAddrList(startOutSizeAddr, strideOutSizeAddr, len(outs), indentStr)) + "\n" + if "" in line: + line = line.replace("", mg.getGemTopFuncName(model)) + + fout.write(line) + + fin.close() + fout.close() \ No newline at end of file From 3f465abfc4e6cfd64a5e1a109367c954eb19f763 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 19 Aug 2025 11:24:56 +0200 Subject: [PATCH 23/70] clean some code --- hls4ml/converters/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hls4ml/converters/__init__.py b/hls4ml/converters/__init__.py index 9a80ef7b47..eb6c587b31 100644 --- a/hls4ml/converters/__init__.py +++ b/hls4ml/converters/__init__.py @@ -168,7 +168,6 @@ def convert_from_keras_model( **kwargs, ): - print("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd") """Convert Keras model to hls4ml model based on the provided configuration. Args: From 86d64d568b41f3eea6046b5149584038c70db4f7 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 19 Aug 2025 15:18:13 +0200 Subject: [PATCH 24/70] add base ip for magic architecture and add axi warpper --- .../vitis_unified_partial/build_lib.sh | 30 + .../build_lib_multigraph.sh | 69 + .../ips/magic_dummy_master/component.xml | 331 ++++ .../src/dummyStreamMaster.v | 23 + .../xgui/DummyStreamMaster_v1_0.tcl | 39 + .../ips/magic_dummy_slave/component.xml | 344 ++++ .../magic_dummy_slave/src/dummyStreamSlave.v | 21 + .../xgui/DummyStreamSlave_v1_0.tcl | 54 + .../ips/magic_seq/component.xml | 1600 +++++++++++++++++ .../ips/magic_seq/src/m_axi_read.v | 48 + .../ips/magic_seq/src/m_axi_write.v | 205 +++ .../ips/magic_seq/src/magicSeq.v | 634 +++++++ .../ips/magic_seq/src/magicSeqCore.v | 644 +++++++ .../ips/magic_seq/src/s_axi_read.v | 162 ++ .../ips/magic_seq/src/s_axi_write.v | 240 +++ .../ips/magic_seq/src/slot.v | 89 + .../ips/magic_seq/src/slotTable.v | 150 ++ .../ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl | 310 ++++ .../ips/magic_seq/xgui/MagicSeq_v1_0.tcl | 309 ++++ .../ips/magic_steamer/component.xml | 559 ++++++ .../ips/magic_steamer/src/magicStreamer.v | 161 ++ .../xgui/MagicStreammerCore_v1_0.tcl | 54 + .../ips/magic_stream_grp_gen/streamGrp.v | 16 + .../vitis_unified_partial/myproject_axi.cpp | 83 + .../vitis_unified_partial/myproject_axi.h | 14 + .../myproject_bridge.cpp | 71 + .../vitis_unified_partial/myproject_test.cpp | 96 + .../workspace/projectName/vitis-comp.json | 9 + 28 files changed, 6365 insertions(+) create mode 100644 hls4ml/templates/vitis_unified_partial/build_lib.sh create mode 100644 hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeqCore.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/s_axi_read.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/s_axi_write.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/slot.v create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/slotTable.v create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeq_v1_0.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_steamer/component.xml create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v create mode 100644 hls4ml/templates/vitis_unified_partial/myproject_axi.cpp create mode 100644 hls4ml/templates/vitis_unified_partial/myproject_axi.h create mode 100644 hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp create mode 100644 hls4ml/templates/vitis_unified_partial/myproject_test.cpp create mode 100644 hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json diff --git a/hls4ml/templates/vitis_unified_partial/build_lib.sh b/hls4ml/templates/vitis_unified_partial/build_lib.sh new file mode 100644 index 0000000000..fd7f3c2cdb --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/build_lib.sh @@ -0,0 +1,30 @@ +#!/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=myproject +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/${PROJECT}_dm.cpp -o ${PROJECT}_dm.o +${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_dm.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so +rm -f *.o \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh b/hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh new file mode 100644 index 0000000000..9dcd85f7d1 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/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_partial/ips/magic_dummy_master/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml new file mode 100644 index 0000000000..b7d7fd4cdf --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml @@ -0,0 +1,331 @@ + + + user.org + user + DummyStreamMaster + 1.0 + + + M_AXI + + + + + + + TDATA + + + M_AXI_TDATA + + + + + TLAST + + + M_AXI_TLAST + + + + + TVALID + + + M_AXI_TVALID + + + + + TREADY + + + M_AXI_TREADY + + + + + + reset + + + + + + + RST + + + reset + + + + + + clk + + + + + + + CLK + + + clk + + + + + + ASSOCIATED_BUSIF + M_AXI + + + ASSOCIATED_RESET + reset + + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + DummyStreamMaster + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + 2ce15dc3 + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + DummyStreamMaster + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + 2ce15dc3 + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + 83c2f9ad + + + + + + + M_AXI_TDATA + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_TVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_TREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 1 + + + + + M_AXI_TLAST + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + clk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + reset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/dummyStreamMaster.v + verilogSource + CHECKSUM_2ce15dc3 + IMPORTED_FILE + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/dummyStreamMaster.v + verilogSource + IMPORTED_FILE + + + + xilinx_xpgui_view_fileset + + xgui/DummyStreamMaster_v1_0.tcl + tclSource + CHECKSUM_83c2f9ad + XGUI_VERSION_2 + + + + DummyStreamMaster + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + Component_Name + DummyStreamMaster_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + artixuplus + kintexu + + + /UserIP + + DummyStreamMaster + package_project + 3 + 2025-08-19T11:20:58Z + + + 2023.2 + + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v new file mode 100755 index 0000000000..5510e387a5 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v @@ -0,0 +1,23 @@ +module DummyStreamMaster # +( + parameter integer DATA_WIDTH = 32, + parameter integer STORAGE_IDX_WIDTH = 10 //// 4 Kb +) +( + // AXIS Master Interface load interface + output wire [DATA_WIDTH-1:0] M_AXI_TDATA, +// output wire [DATA_WIDTH/8-1:0] M_AXI_TKEEP, // <= tkeep added + output wire M_AXI_TVALID, + input wire M_AXI_TREADY, + output wire M_AXI_TLAST, + + input wire clk, + input wire reset +); + +assign M_AXI_TDATA = 0; // Dummy implementation, always output zero +//assign M_AXI_TKEEP = 0; // Dummy implementation, always output zero +assign M_AXI_TVALID = 1'b0; // Dummy implementation, always not valid +assign M_AXI_TLAST = 1'b0; // Dummy implementation, always not last + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl new file mode 100644 index 0000000000..b3c93b639b --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl @@ -0,0 +1,39 @@ +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + set Page_0 [ipgui::add_page $IPINST -name "Page 0"] + ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} + + +} + +proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to validate DATA_WIDTH + return true +} + +proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to validate STORAGE_IDX_WIDTH + return true +} + + +proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} +} + +proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} +} + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml new file mode 100644 index 0000000000..07e8fb3fd7 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml @@ -0,0 +1,344 @@ + + + hls4ml_par_gen + user + DummyStreamSlave + 1.0 + + + S_AXI + + + + + + + TDATA + + + S_AXI_TDATA + + + + + TLAST + + + S_AXI_TLAST + + + + + TVALID + + + S_AXI_TVALID + + + + + TREADY + + + S_AXI_TREADY + + + + + + reset + + + + + + + RST + + + reset + + + + + + clk + + + + + + + CLK + + + clk + + + + + + ASSOCIATED_BUSIF + S_AXI + + + ASSOCIATED_RESET + reset + + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + DummyStreamSlave + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + 3da6af3d + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + DummyStreamSlave + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + 3da6af3d + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + 66396a2b + + + + + + + S_AXI_TDATA + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_TVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_TREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_TLAST + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + clk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + reset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + SINK_MODE + Sink Mode + 0 + + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/dummyStreamSlave.v + verilogSource + CHECKSUM_3da6af3d + IMPORTED_FILE + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/dummyStreamSlave.v + verilogSource + IMPORTED_FILE + + + + xilinx_xpgui_view_fileset + + xgui/DummyStreamSlave_v1_0.tcl + tclSource + CHECKSUM_66396a2b + XGUI_VERSION_2 + + + + DummyStreamSlave + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + SINK_MODE + Sink Mode + 0 + + + Component_Name + DummyStreamSlave_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + artixuplus + kintexu + + + /UserIP + + DummyStreamSlave + package_project + 2 + 2025-08-19T11:16:24Z + + + 2023.2 + + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v new file mode 100755 index 0000000000..bac46af092 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v @@ -0,0 +1,21 @@ +module DummyStreamSlave # +( + parameter integer DATA_WIDTH = 32, + parameter integer STORAGE_IDX_WIDTH = 10, //// 4 Kb + parameter [0:0] SINK_MODE = 0 +) +( + // AXIS Slave Interface store in terface + input wire [DATA_WIDTH-1:0] S_AXI_TDATA, +// input wire [DATA_WIDTH/8-1:0] S_AXI_TKEEP, // <= tkeep added + input wire S_AXI_TVALID, + output wire S_AXI_TREADY, + input wire S_AXI_TLAST, + + input wire clk, + input wire reset +); + +assign S_AXI_TREADY = SINK_MODE; // Dummy implementation, always not ready + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl new file mode 100644 index 0000000000..6354d04f3c --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl @@ -0,0 +1,54 @@ +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + set Page_0 [ipgui::add_page $IPINST -name "Page 0"] + ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "SINK_MODE" -parent ${Page_0} + + +} + +proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to validate DATA_WIDTH + return true +} + +proc update_PARAM_VALUE.SINK_MODE { PARAM_VALUE.SINK_MODE } { + # Procedure called to update SINK_MODE when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.SINK_MODE { PARAM_VALUE.SINK_MODE } { + # Procedure called to validate SINK_MODE + return true +} + +proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to validate STORAGE_IDX_WIDTH + return true +} + + +proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} +} + +proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} +} + +proc update_MODELPARAM_VALUE.SINK_MODE { MODELPARAM_VALUE.SINK_MODE PARAM_VALUE.SINK_MODE } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.SINK_MODE}] ${MODELPARAM_VALUE.SINK_MODE} +} + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml new file mode 100644 index 0000000000..8a7851f1f3 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml @@ -0,0 +1,1600 @@ + + + user.org + user + MagicSeq + 1.0 + + + M_AXI + + + + + + + + + AWADDR + + + M_AXI_AWADDR + + + + + AWVALID + + + M_AXI_AWVALID + + + + + AWREADY + + + M_AXI_AWREADY + + + + + WDATA + + + M_AXI_WDATA + + + + + WSTRB + + + M_AXI_WSTRB + + + + + WVALID + + + M_AXI_WVALID + + + + + WREADY + + + M_AXI_WREADY + + + + + BRESP + + + M_AXI_BRESP + + + + + BVALID + + + M_AXI_BVALID + + + + + BREADY + + + M_AXI_BREADY + + + + + ARADDR + + + M_AXI_ARADDR + + + + + ARVALID + + + M_AXI_ARVALID + + + + + ARREADY + + + M_AXI_ARREADY + + + + + RDATA + + + M_AXI_RDATA + + + + + RRESP + + + M_AXI_RRESP + + + + + RVALID + + + M_AXI_RVALID + + + + + RREADY + + + M_AXI_RREADY + + + + + + S_AXI + + + + + + + + + AWADDR + + + S_AXI_AWADDR + + + + + AWVALID + + + S_AXI_AWVALID + + + + + AWREADY + + + S_AXI_AWREADY + + + + + WDATA + + + S_AXI_WDATA + + + + + WSTRB + + + S_AXI_WSTRB + + + + + WVALID + + + S_AXI_WVALID + + + + + WREADY + + + S_AXI_WREADY + + + + + BRESP + + + S_AXI_BRESP + + + + + BVALID + + + S_AXI_BVALID + + + + + BREADY + + + S_AXI_BREADY + + + + + ARADDR + + + S_AXI_ARADDR + + + + + ARVALID + + + S_AXI_ARVALID + + + + + ARREADY + + + S_AXI_ARREADY + + + + + RDATA + + + S_AXI_RDATA + + + + + RRESP + + + S_AXI_RRESP + + + + + RVALID + + + S_AXI_RVALID + + + + + RREADY + + + S_AXI_RREADY + + + + + + reset + + + + + + + RST + + + reset + + + + + + clk + + + + + + + CLK + + + clk + + + + + + ASSOCIATED_BUSIF + M_AXI:S_AXI + + + ASSOCIATED_RESET + reset + + + + + hw_intr + + + + + + + INTERRUPT + + + hw_intr + + + + + + SENSITIVITY + LEVEL_HIGH + + + + + + + M_AXI + M_AXI + 0x100000000 + 32 + + + + + S_AXI + S_AXI + + reg0 + reg0 + 0x0 + 0x10000 + 32 + register + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + MagicSeqTop + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + 2882be72 + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + MagicSeqTop + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + 2882be72 + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + 2750c49f + + + + + + + clk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + reset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_ARADDR + + in + + 15 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_ARVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_ARREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_RDATA + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_RRESP + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_RVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_RREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_AWADDR + + in + + 15 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_AWVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_AWREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_WDATA + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_WSTRB + + in + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 1 + + + + + S_AXI_WVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_WREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_BRESP + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_BVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_BREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_ARADDR + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_ARVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_ARREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_RDATA + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_RRESP + + in + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_RVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_RREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_AWADDR + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_AWVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_AWREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_WDATA + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_WSTRB + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_WVALID + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_WREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_BRESP + + in + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_BVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_BREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + slaveReprog + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + nslaveReset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + slaveMgsStoreReset + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + slaveMgsLoadReset + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + slaveMgsStoreInit + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + slaveMgsLoadInit + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + mgsFinExec + + in + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_slaveInit + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_slaveFinInit + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_slaveStartExec + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_slaveStartExecAccept + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + hw_ctrl_start + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + hw_intr_clear + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + hw_intr + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + GLOB_ADDR_WIDTH + Glob Addr Width + 32 + + + GLOB_DATA_WIDTH + Glob Data Width + 32 + + + ADDR_WIDTH + Addr Width + 16 + + + DATA_WIDTH + Data Width + 32 + + + BANK1_INDEX_WIDTH + Bank1 Index Width + 3 + + + BANK1_SRC_ADDR_WIDTH + Bank1 Src Addr Width + 32 + + + BANK1_SRC_SIZE_WIDTH + Bank1 Src Size Width + 26 + + + BANK1_DST_ADDR_WIDTH + Bank1 Dst Addr Width + 32 + + + BANK1_DST_SIZE_WIDTH + Bank1 Dst Size Width + 26 + + + BANK1_STATUS_WIDTH + Bank1 Status Width + 2 + + + BANK1_PROFILE_WIDTH + Bank1 Profile Width + 32 + + + BANK1_LD_MSK_WIDTH + Bank1 Ld Msk Width + 8 + + + BANK1_ST_MSK_WIDTH + Bank1 St Msk Width + 8 + + + BANK0_CONTROL_WIDTH + Bank0 Control Width + 4 + + + BANK0_STATUS_WIDTH + Bank0 Status Width + 4 + + + BANK0_CNT_WIDTH + Bank0 Cnt Width + 3 + + + BANK0_INTR_WIDTH + Bank0 Intr Width + 1 + + + BANK0_ROUNDTRIP_WIDTH + Bank0 Roundtrip Width + 16 + + + DMA_INIT_TASK_CNT + Dma Init Task Cnt + 8 + + + DMA_EXEC_TASK_CNT + Dma Exec Task Cnt + 1 + + + + + + choice_list_9ca20931 + LEVEL_HIGH + LEVEL_LOW + EDGE_RISING + EDGE_FALLING + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/m_axi_read.v + verilogSource + IMPORTED_FILE + + + src/m_axi_write.v + verilogSource + IMPORTED_FILE + + + src/magicSeqCore.v + verilogSource + IMPORTED_FILE + + + src/s_axi_read.v + verilogSource + IMPORTED_FILE + + + src/s_axi_write.v + verilogSource + IMPORTED_FILE + + + src/slot.v + verilogSource + IMPORTED_FILE + + + src/slotTable.v + verilogSource + IMPORTED_FILE + + + src/magicSeq.v + verilogSource + CHECKSUM_07379c0c + IMPORTED_FILE + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/m_axi_read.v + verilogSource + IMPORTED_FILE + + + src/m_axi_write.v + verilogSource + IMPORTED_FILE + + + src/magicSeqCore.v + verilogSource + IMPORTED_FILE + + + src/s_axi_read.v + verilogSource + IMPORTED_FILE + + + src/s_axi_write.v + verilogSource + IMPORTED_FILE + + + src/slot.v + verilogSource + IMPORTED_FILE + + + src/slotTable.v + verilogSource + IMPORTED_FILE + + + src/magicSeq.v + verilogSource + IMPORTED_FILE + + + + xilinx_xpgui_view_fileset + + xgui/MagicSeq_v1_0.tcl + tclSource + CHECKSUM_2750c49f + XGUI_VERSION_2 + + + + MagicSeq + + + GLOB_ADDR_WIDTH + Glob Addr Width + 32 + + + GLOB_DATA_WIDTH + Glob Data Width + 32 + + + ADDR_WIDTH + Addr Width + 16 + + + DATA_WIDTH + Data Width + 32 + + + BANK1_INDEX_WIDTH + Bank1 Index Width + 3 + + + BANK1_SRC_ADDR_WIDTH + Bank1 Src Addr Width + 32 + + + BANK1_SRC_SIZE_WIDTH + Bank1 Src Size Width + 26 + + + BANK1_DST_ADDR_WIDTH + Bank1 Dst Addr Width + 32 + + + BANK1_DST_SIZE_WIDTH + Bank1 Dst Size Width + 26 + + + BANK1_STATUS_WIDTH + Bank1 Status Width + 2 + + + BANK1_PROFILE_WIDTH + Bank1 Profile Width + 32 + + + BANK1_LD_MSK_WIDTH + Bank1 Ld Msk Width + 8 + + + BANK1_ST_MSK_WIDTH + Bank1 St Msk Width + 8 + + + BANK0_CONTROL_WIDTH + Bank0 Control Width + 4 + + + BANK0_STATUS_WIDTH + Bank0 Status Width + 4 + + + BANK0_CNT_WIDTH + Bank0 Cnt Width + 3 + + + BANK0_INTR_WIDTH + Bank0 Intr Width + 1 + + + BANK0_ROUNDTRIP_WIDTH + Bank0 Roundtrip Width + 16 + + + DMA_INIT_TASK_CNT + Dma Init Task Cnt + 8 + + + DMA_EXEC_TASK_CNT + Dma Exec Task Cnt + 1 + + + Component_Name + MagicSeqTop_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + artixuplus + kintexu + + + /UserIP + + MagicSeq + package_project + 3 + 2025-08-19T11:05:58Z + + + 2023.2 + + + + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v new file mode 100755 index 0000000000..e53b5aebf0 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v @@ -0,0 +1,48 @@ +module m_axi_read #( + parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface + parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface + + parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots + parameter BANK1_SRC_ADDR_WIDTH = 32, + parameter BANK1_SRC_SIZE_WIDTH = 26, + parameter BANK1_DST_ADDR_WIDTH = 32, + parameter BANK1_DST_SIZE_WIDTH = 26, + parameter BANK1_STATUS_WIDTH = 2, + parameter BANK1_PROFILE_WIDTH = 32, + parameter BANK1_LD_MSK_WIDTH = 8, + parameter BANK1_ST_MSK_WIDTH = 8, + + parameter BANK0_CONTROL_WIDTH = 4, + parameter BANK0_STATUS_WIDTH = 4, + parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer + + parameter DMA_INIT_TASK_CNT = 8, //// (baseAddr0 + size0) + (baseAddr1 + size1) + parameter DMA_EXEC_TASK_CNT = 1 +)( + +input wire clk, +input wire reset, +/** +------------ AXI4-Lite Master Read Interface +it is supposed to connect to the DMA +*/ + +// Read Address Channel +output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_ARADDR, +output wire M_AXI_ARVALID, +input wire M_AXI_ARREADY, + +// Read Data Channel +input wire [GLOB_ADDR_WIDTH-1:0] M_AXI_RDATA, ////// read data output acctually it is a reg +input wire [1:0] M_AXI_RRESP, +input wire M_AXI_RVALID, +output wire M_AXI_RREADY +); + + +assign M_AXI_ARADDR = 0; +assign M_AXI_ARVALID = 0; + +assign M_AXI_RREADY = 0; + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v new file mode 100755 index 0000000000..a29e2eb030 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v @@ -0,0 +1,205 @@ +module m_axi_write #( + parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface + parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface + + parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots + parameter BANK1_SRC_ADDR_WIDTH = 32, + parameter BANK1_SRC_SIZE_WIDTH = 26, + parameter BANK1_DST_ADDR_WIDTH = 32, + parameter BANK1_DST_SIZE_WIDTH = 26, + parameter BANK1_STATUS_WIDTH = 2, + parameter BANK1_PROFILE_WIDTH = 32, + parameter BANK1_LD_MSK_WIDTH = 8, + parameter BANK1_ST_MSK_WIDTH = 8, + + parameter BANK0_CONTROL_WIDTH = 4, + parameter BANK0_STATUS_WIDTH = 4, + parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer + + parameter DMA_INIT_TASK_CNT = 8, //// (reset interrupt + startReadChannel + baseAddr0 + size0) + (reset interrupt + startWriteChannel + baseAddr1 + size1) + parameter DMA_EXEC_TASK_CNT = 1 +)( + input wire clk, + input wire reset, + + // AXI Lite Write Address Channel + output reg [GLOB_ADDR_WIDTH-1:0] M_AXI_AWADDR, ///// actually it is wire + output wire M_AXI_AWVALID, + input wire M_AXI_AWREADY, + + // AXI Lite Write Data Channel + output reg [GLOB_DATA_WIDTH-1:0] M_AXI_WDATA, ///// actually it is wire + output wire[(GLOB_DATA_WIDTH/8)-1:0] M_AXI_WSTRB, + output wire M_AXI_WVALID, + input wire M_AXI_WREADY, + + // AXI Lite Write Response Channel + input wire [1:0] M_AXI_BRESP, + input wire M_AXI_BVALID, + output wire M_AXI_BREADY, + + // dma base addr + input wire [GLOB_ADDR_WIDTH-1: 0] ext_bank0_out_dmaBaseAddr, + + // slave input + + input wire[DMA_INIT_TASK_CNT-1: 0] slaveInit , ///// trigger slave dma to do somthing + output reg [DMA_INIT_TASK_CNT-1: 0] slaveFinInit, + + input wire[DMA_EXEC_TASK_CNT-1: 0] slaveStartExec , + output reg [DMA_EXEC_TASK_CNT-1: 0] slaveStartExecAccept, ///// the slave dma is ready to start + + input wire [BANK1_DST_ADDR_WIDTH -1:0] slave_bank1_out_src_addr, // actually it is a reg + input wire [BANK1_DST_SIZE_WIDTH -1:0] slave_bank1_out_src_size, // actually it is a reg + input wire [BANK1_DST_ADDR_WIDTH -1:0] slave_bank1_out_des_addr, + input wire [BANK1_DST_SIZE_WIDTH -1:0] slave_bank1_out_des_size, + input wire [BANK1_STATUS_WIDTH -1:0] slave_bank1_out_status , // actually it is a reg + input wire [BANK1_PROFILE_WIDTH -1:0] slave_bank1_out_profile // actually it is a reg + +); + + +/** +* This module supposed to connet to dma +* +* +**/ + +//////// READ CHANNEL + +wire[GLOB_ADDR_WIDTH-1: 0] dmSrcStatusADDR = ext_bank0_out_dmaBaseAddr + 32'h04; + +wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcCtrlADDR = ext_bank0_out_dmaBaseAddr + 32'h00; +wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcDataAddrADDR = ext_bank0_out_dmaBaseAddr + 32'h18; +wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcDataSizeADDR = ext_bank0_out_dmaBaseAddr + 32'h28; + +//////// WRITE CHANNEL + +wire[GLOB_ADDR_WIDTH-1: 0] dmDesStatusADDR = ext_bank0_out_dmaBaseAddr + 32'h34; + +wire[GLOB_ADDR_WIDTH-1: 0] dmaDesCtrlADDR = ext_bank0_out_dmaBaseAddr + 32'h30; +wire[GLOB_ADDR_WIDTH-1: 0] dmaDesDataAddrADDR = ext_bank0_out_dmaBaseAddr + 32'h48; +wire[GLOB_ADDR_WIDTH-1: 0] dmaDesDataSizeADDR = ext_bank0_out_dmaBaseAddr + 32'h58; + + +localparam STATUS_IDLE = 4'b0000; +localparam STATUS_WADDR = 4'b0001; +localparam STATUS_WDATA = 4'b0010; +localparam STATUS_RESP = 4'b0100; +localparam STATUS_UNLOCK = 4'b1000; + +/** +control main state machine +*/ + +reg[3:0] state; + +always @(posedge clk or negedge reset) begin + + if (~reset)begin + state = STATUS_IDLE; + end else begin + case(state) + STATUS_IDLE: begin + if ( (slaveInit != 0) | (slaveStartExec != 0)) begin state = STATUS_WADDR; end + end + STATUS_WADDR: begin + if (M_AXI_AWREADY) begin state = STATUS_WDATA; end + end + STATUS_WDATA: begin + if (M_AXI_WREADY) begin state = STATUS_RESP; end + end + STATUS_RESP: begin + if (M_AXI_BVALID) begin state = STATUS_UNLOCK; end + end + STATUS_UNLOCK: begin + state = STATUS_IDLE; + end + + default: begin + state = STATUS_IDLE; + end + endcase + end +end + +//// address channel +assign M_AXI_AWVALID = (state == STATUS_WADDR); +//// data channel +assign M_AXI_WSTRB = 4'b1111; +assign M_AXI_WVALID = (state == STATUS_WDATA); +//// resChannel +assign M_AXI_BREADY = (state == STATUS_RESP); + +///// manage address + +always @ (*) begin + + M_AXI_AWADDR = 0; + M_AXI_WDATA = 0; + + slaveFinInit = 0; + slaveStartExecAccept = 0; + + if (slaveInit != 0)begin + + if (state == STATUS_UNLOCK)begin //// STATUS_UNLOCK is one cycle + slaveFinInit = slaveInit; + end + + case(slaveInit) + + 8'b00000001: begin + M_AXI_AWADDR = dmSrcStatusADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0000}; //// start command + end + 8'b00000010: begin + M_AXI_AWADDR = dmDesStatusADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0000}; //// start command + end + //////////////////// set READ (RUN/SRCADDR/SRCSIZE) + 8'b00000100: begin + M_AXI_AWADDR = dmaSrcCtrlADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0001}; //// start command + end + 8'b00001000: begin + M_AXI_AWADDR = dmaSrcDataAddrADDR; + M_AXI_WDATA = slave_bank1_out_src_addr; + + end + 8'b00010000: begin + M_AXI_AWADDR = dmaSrcDataSizeADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - BANK1_DST_SIZE_WIDTH){1'b0}}, slave_bank1_out_src_size}; + end + //////////////////// set WRITE (RUN/DESADDR/DESSIZE) + 8'b00100000: begin + M_AXI_AWADDR = dmaDesCtrlADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0001}; //// start command + end + 8'b01000000: begin + M_AXI_AWADDR = dmaDesDataAddrADDR; + M_AXI_WDATA = slave_bank1_out_des_addr; + end + 8'b10000000: begin + M_AXI_AWADDR = dmaDesDataSizeADDR; + M_AXI_WDATA = {{(GLOB_DATA_WIDTH - BANK1_DST_SIZE_WIDTH){1'b0}}, slave_bank1_out_des_size}; + end + default: begin + M_AXI_AWADDR = 0; + M_AXI_WDATA = 0; + slaveFinInit = 0; + slaveStartExecAccept = 0; + end + endcase + end + // end else if (slaveStartExec != 0) begin + // M_AXI_AWADDR = dmaCtrlAddrADDR; + // M_AXI_WDATA = 1; + // if (state == STATUS_UNLOCK)begin + // slaveFinInit = slaveInit; + // end + // end + +end + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v new file mode 100755 index 0000000000..27810a721c --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v @@ -0,0 +1,634 @@ +module MagicSeqTop #( + + parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface + parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface + + parameter ADDR_WIDTH = 16, // Address width for AXI interface + parameter DATA_WIDTH = 32, // Data width for AXI interface + + parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots + parameter BANK1_SRC_ADDR_WIDTH = 32, + parameter BANK1_SRC_SIZE_WIDTH = 26, + parameter BANK1_DST_ADDR_WIDTH = 32, + parameter BANK1_DST_SIZE_WIDTH = 26, + parameter BANK1_STATUS_WIDTH = 2, + parameter BANK1_PROFILE_WIDTH = 32, + parameter BANK1_LD_MSK_WIDTH = 8, + parameter BANK1_ST_MSK_WIDTH = 8, + + parameter BANK0_CONTROL_WIDTH = 4, + parameter BANK0_STATUS_WIDTH = 4, + parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer + parameter BANK0_INTR_WIDTH = 1, /// the round counter for the sequencer + parameter BANK0_ROUNDTRIP_WIDTH = 16, /// the round trip counter for the sequencer + + + parameter DMA_INIT_TASK_CNT = 8, //// (baseAddr0 + size0) + (baseAddr1 + size1) + parameter DMA_EXEC_TASK_CNT = 1 + +) ( + +input wire clk, +input wire reset, +/** +PS ------------ AXI4-Lite slave Read Interface +it is supposed to connect to the PS +*/ + +// Read Address Channel +input wire [ADDR_WIDTH-1:0] S_AXI_ARADDR, +input wire S_AXI_ARVALID, +output wire S_AXI_ARREADY, + +// Read Data Channel +output wire [DATA_WIDTH-1:0] S_AXI_RDATA, ////// read data output acctually it is a reg +output wire [1:0] S_AXI_RRESP, +output wire S_AXI_RVALID, +input wire S_AXI_RREADY, + +/** +PS ------------ AXI4-Lite slave write Interface +it is supposed to connect to the PS +*/ + +// AXI Lite Write Address Channel +input wire [ADDR_WIDTH-1:0] S_AXI_AWADDR, +input wire S_AXI_AWVALID, +output wire S_AXI_AWREADY, + +// AXI Lite Write Data Channel +input wire [DATA_WIDTH-1:0] S_AXI_WDATA, +input wire [(DATA_WIDTH/8)-1:0] S_AXI_WSTRB, +input wire S_AXI_WVALID, +output wire S_AXI_WREADY, + +// AXI Lite Write Response Channel +output wire [1:0] S_AXI_BRESP, +output wire S_AXI_BVALID, +input wire S_AXI_BREADY, + +/** + ------------ AXI4-Lite master read Interface +it is supposed to connect to the PS +*/ +// Read Address Channel +output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_ARADDR, +output wire M_AXI_ARVALID, +input wire M_AXI_ARREADY, + +// Read Data Channel +input wire [GLOB_ADDR_WIDTH-1:0] M_AXI_RDATA, ////// read data output acctually it is a reg +input wire [1:0] M_AXI_RRESP, +input wire M_AXI_RVALID, +output wire M_AXI_RREADY, + +/** + ------------ AXI4-Lite master write Interface +it is supposed to connect to the PS +*/ + +output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_AWADDR, ///// actually it is wire +output wire M_AXI_AWVALID, +input wire M_AXI_AWREADY, + + // AXI Lite Write Data Channel +output wire[GLOB_DATA_WIDTH-1:0] M_AXI_WDATA, ///// actually it is wire +output wire[(GLOB_DATA_WIDTH/8)-1:0] M_AXI_WSTRB, +output wire M_AXI_WVALID, +input wire M_AXI_WREADY, + + // AXI Lite Write Response Channel +input wire [1:0] M_AXI_BRESP, +input wire M_AXI_BVALID, +output wire M_AXI_BREADY, + +output wire [(1 < + + user.org + user + MagicStreammerCore + 1.0 + + + M_AXI + + + + + + + TDATA + + + M_AXI_TDATA + + + + + TLAST + + + M_AXI_TLAST + + + + + TVALID + + + M_AXI_TVALID + + + + + TREADY + + + M_AXI_TREADY + + + + + + S_AXI + + + + + + + TDATA + + + S_AXI_TDATA + + + + + TLAST + + + S_AXI_TLAST + + + + + TVALID + + + S_AXI_TVALID + + + + + TREADY + + + S_AXI_TREADY + + + + + + reset + + + + + + + RST + + + reset + + + + + + clk + + + + + + + CLK + + + clk + + + + + + ASSOCIATED_BUSIF + M_AXI:S_AXI + + + ASSOCIATED_RESET + reset + + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + MagicStreammerCore + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + d9829fdc + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + MagicStreammerCore + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + d9829fdc + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + d79a4d11 + + + + + + + clk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + reset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_TDATA + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + S_AXI_TVALID + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_TREADY + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + S_AXI_TLAST + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + M_AXI_TDATA + + out + + 31 + 0 + + + + reg + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_TVALID + + out + + + reg + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + M_AXI_TREADY + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 1 + + + + + M_AXI_TLAST + + out + + + reg + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + storeReset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + loadReset + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + storeInit + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + loadInit + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + finStore + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_state + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_amt_store_bytes + + out + + 10 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + dbg_amt_load_bytes + + out + + 10 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + STATE_BIT_WIDTH + State Bit Width + 4 + + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/magicStreamer.v + verilogSource + CHECKSUM_d9829fdc + IMPORTED_FILE + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/magicStreamer.v + verilogSource + IMPORTED_FILE + + + + xilinx_xpgui_view_fileset + + xgui/MagicStreammerCore_v1_0.tcl + tclSource + CHECKSUM_d79a4d11 + XGUI_VERSION_2 + + + + MagicStreammerCore + + + DATA_WIDTH + Data Width + 32 + + + STORAGE_IDX_WIDTH + Storage Idx Width + 10 + + + STATE_BIT_WIDTH + State Bit Width + 4 + + + Component_Name + MagicStreammerCore_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + artixuplus + kintexu + + + /UserIP + + MagicStreammerCore + package_project + 2 + 2025-08-19T11:25:44Z + + + 2023.2 + + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v b/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v new file mode 100755 index 0000000000..da2f369d1f --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v @@ -0,0 +1,161 @@ +module MagicStreammerCore # +( + parameter integer DATA_WIDTH = 32, + parameter integer STORAGE_IDX_WIDTH = 10, //// 4 Kb + parameter integer STATE_BIT_WIDTH = 4 +) +( + input wire clk, + input wire reset, + + // AXIS Slave Interface store in terface + input wire [DATA_WIDTH-1:0] S_AXI_TDATA, +// input wire [DATA_WIDTH/8-1:0] S_AXI_TKEEP, // <= tkeep added //// we disable tkeep + input wire S_AXI_TVALID, + output wire S_AXI_TREADY, + input wire S_AXI_TLAST, + + // AXIS Master Interface load interface + output reg [DATA_WIDTH-1:0] M_AXI_TDATA, // it is supposed to be reg +// output wire [DATA_WIDTH/8-1:0] M_AXI_TKEEP, // it is supposed to be reg + output reg M_AXI_TVALID, // it is supposed to be reg + input wire M_AXI_TREADY, // it is supposed to be reg + output reg M_AXI_TLAST, // it is supposed to be reg + + // control signal + + input wire storeReset, + input wire loadReset, + input wire storeInit, + input wire loadInit, + + // store complete connect it to mgsFinExec + output wire finStore, + + // out put wire for debugging + output wire [STATE_BIT_WIDTH-1:0] dbg_state, + output wire [(STORAGE_IDX_WIDTH+1)-1:0] dbg_amt_store_bytes, + output wire [(STORAGE_IDX_WIDTH+1)-1:0] dbg_amt_load_bytes + +); + + + +///// declare state + +localparam STATUS_IDLE = 4'b0000; +localparam STATUS_STORE = 4'b0001; +localparam STATUS_LOAD = 4'b0010; + +localparam TRACKER_IDX_WIDTH = STORAGE_IDX_WIDTH + 1; ///// this is for tracker index width + +///// meta data +(* ram_style = "block" *) reg[DATA_WIDTH-1: 0] mainMem [0: ((1 << STORAGE_IDX_WIDTH) - 1)]; + +reg[STATE_BIT_WIDTH -1: 0] state; +reg[TRACKER_IDX_WIDTH-1: 0] amt_store_bytes; ///// store to this block +reg[TRACKER_IDX_WIDTH-1: 0] amt_load_bytes; ///// load to this block +reg storeIntr; + +///////////////////////////////////// +////// axi signal assign //////////// +///////////////////////////////////// + +///////// store +assign S_AXI_TREADY = (state == STATUS_STORE) && S_AXI_TVALID; +///////// load +////assign M_AXI_TKEEP = 4'b1111; +///////// interrupt signal +assign finStore = storeIntr; +/////////// debug signal +assign dbg_state = state; +assign dbg_amt_store_bytes = amt_store_bytes; +assign dbg_amt_load_bytes = amt_load_bytes; + +///////////////////////////////////// +////// control system //////////// +///////////////////////////////////// +always @(posedge clk, negedge reset) begin + + if (~reset) begin + state <= STATUS_IDLE; + amt_store_bytes <= 0; + amt_load_bytes <= 0; + storeIntr <= 0; + end else begin + case (state) + STATUS_IDLE : begin + if (storeReset) begin + amt_store_bytes <= 0; + storeIntr <= 0; + end else if (loadReset) begin + amt_load_bytes <= 0; + storeIntr <= 0; + end else if (storeInit) begin + state <= STATUS_STORE; + end else if (loadInit & (amt_store_bytes > 0)) begin + state <= STATUS_LOAD; + end + end + //////////// case store data to the internal memory + STATUS_STORE : begin + if (S_AXI_TVALID)begin //// we are sure that ready will send this time + amt_store_bytes <= amt_store_bytes + 1; + if (S_AXI_TLAST)begin + storeIntr <= 1; + state <= STATUS_IDLE; + end + end + end + STATUS_LOAD : begin + if (M_AXI_TREADY | (amt_load_bytes == 0)) begin //// last sending is success in this cycle/ send next + + if ( amt_load_bytes == amt_store_bytes )begin + /////// no data to send anymore + M_AXI_TVALID <= 0; + M_AXI_TLAST <= 0; + state <= STATUS_IDLE; + end else begin + M_AXI_TVALID <= 1; + M_AXI_TLAST <= (amt_load_bytes == (amt_store_bytes-1)); + amt_load_bytes <= amt_load_bytes + 1; + end + + end + ///// at here do nothing just wait for signal + + end + + + default: begin end + + endcase + end + +end + + + +///// M_DATA and MEM management + +always @(posedge clk) begin + if (state == STATUS_STORE)begin + if (S_AXI_TVALID)begin + mainMem[amt_store_bytes[STORAGE_IDX_WIDTH-1: 0]] <= S_AXI_TDATA; + end + + end else if (state == STATUS_LOAD) begin + + if (M_AXI_TREADY | (amt_load_bytes == 0))begin + if (amt_load_bytes == amt_store_bytes)begin + M_AXI_TDATA <= 48; + end else begin + M_AXI_TDATA <= mainMem[amt_load_bytes[STORAGE_IDX_WIDTH-1: 0]]; + end + end + + end +end + + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl new file mode 100644 index 0000000000..ca87eb5267 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl @@ -0,0 +1,54 @@ +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + set Page_0 [ipgui::add_page $IPINST -name "Page 0"] + ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STATE_BIT_WIDTH" -parent ${Page_0} + + +} + +proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { + # Procedure called to validate DATA_WIDTH + return true +} + +proc update_PARAM_VALUE.STATE_BIT_WIDTH { PARAM_VALUE.STATE_BIT_WIDTH } { + # Procedure called to update STATE_BIT_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STATE_BIT_WIDTH { PARAM_VALUE.STATE_BIT_WIDTH } { + # Procedure called to validate STATE_BIT_WIDTH + return true +} + +proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to validate STORAGE_IDX_WIDTH + return true +} + + +proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} +} + +proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} +} + +proc update_MODELPARAM_VALUE.STATE_BIT_WIDTH { MODELPARAM_VALUE.STATE_BIT_WIDTH PARAM_VALUE.STATE_BIT_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STATE_BIT_WIDTH}] ${MODELPARAM_VALUE.STATE_BIT_WIDTH} +} + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v new file mode 100644 index 0000000000..08b7bc8db3 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v @@ -0,0 +1,16 @@ +`timescale 1ns / 1ps + +module streamGrp #( + // hls4ml-streamGrp-gen-parameter +)( + + // hls4ml-streamGrp-gen-io + + input wire clk, + input wire nreset, + +); + + // hls4ml-streamGrp-gen-io + +endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp new file mode 100644 index 0000000000..b98be9ede3 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp @@ -0,0 +1,83 @@ +// hls-fpga-machine-learning insert include + + +template +void enqueue_atom2layer(hls::stream& src_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ + + dma_data_packet dma_tmp; + for (int i = 0; i < (SIZE/INPUT_LAYER_ARR::size); i++){ + INPUT_LAYER_ARR ctype; + for (int j = 0; j < INPUT_LAYER_ARR::size; j++){ + src_dma_stream.read(dma_tmp); + ctype[j] = dma_tmp.data; + isLastIndicate = dma_tmp.last; + } + raw_stream.write(ctype); + } + +} + +template +void enqueue_layerStream2layer(hls::stream& src_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ + + INPUT_LAYER_STREAM input_layer_stream_tmp; + for (unsigned i = 0; i < (SIZE/INPUT_LAYER_ARR::size); i++){ + INPUT_LAYER_ARR ctype; + src_dma_stream.read(input_layer_stream_tmp); + ctype = input_layer_stream_tmp.data; + isLastIndicate = input_layer_stream_tmp.last; + raw_stream.write(ctype); + } + input_layer_stream_tmp.last = 0; + +} + + +template +void dequeue_layer2atom(hls::stream& des_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ + dma_data_packet dma_tmp; + dma_tmp.last = 0; + for(unsigned i = 0; i < SIZE/OUTPUT_LAYER_ARR::size; ++i){ + OUTPUT_LAYER_ARR ctype = raw_stream.read(); + for(unsigned j = 0; j < OUTPUT_LAYER_ARR::size; ++j){ + dma_tmp.data = (ATOMIC_TYPE) (ctype[j]); + if(isLastIndicate){ + dma_tmp.last = (((i+1)*(j+1))==SIZE); + } + des_dma_stream.write(dma_tmp); + } + } + dma_tmp.last = 0; +} + +template +void dequeue_layer2layer(hls::stream& des_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ + + OUTPUT_LAYER_STREAM output_layer_stream_tmp; + output_layer_stream_tmp.last = 0; + for (unsigned i = 0; i < (SIZE/OUTPUT_LAYER_ARR::size); i++){ + OUTPUT_LAYER_ARR ctype = raw_stream.read(); + output_layer_stream_tmp.data = ctype; + if(isLastIndicate){ + output_layer_stream_tmp.last = ((i+1) == (SIZE/OUTPUT_LAYER_ARR::size)); + } + des_dma_stream.write(output_layer_stream_tmp); + } + +} + +void myproject_axi( + // hls-fpga-machine-learning insert multiIo + +) { + + // hls-fpga-machine-learning insert interface + + // hls-fpga-machine-learning insert local vars + + // hls-fpga-machine-learning insert enqueue + + // hls-fpga-machine-learning insert call + + // hls-fpga-machine-learning insert dequeue +} diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.h b/hls4ml/templates/vitis_unified_partial/myproject_axi.h new file mode 100644 index 0000000000..f3e1c14631 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.h @@ -0,0 +1,14 @@ +#ifndef MYPROJECT_AXI_H_ +#define MYPROJECT_AXI_H_ + +#include +// hls-fpga-machine-learning insert include + +// hls-fpga-machine-learning insert definitions + +void myproject_axi( + +// hls-fpga-machine-learning insert multi-io + +); +#endif \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp b/hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp new file mode 100644 index 0000000000..9a56f10d99 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/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_partial/myproject_test.cpp b/hls4ml/templates/vitis_unified_partial/myproject_test.cpp new file mode 100644 index 0000000000..689d4f055b --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/myproject_test.cpp @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firmware/myproject_axi.h" +#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_partial/workspace/projectName/vitis-comp.json b/hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json new file mode 100644 index 0000000000..c047eba31c --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json @@ -0,0 +1,9 @@ +{ + "name": "{HLS_NAME}", + "type": "HLS", + "configuration": { + "componentType": "HLS", + "configFiles": ["{CONFIG_FILE}"], + "work_dir": "unifiedPrj" + } +} \ No newline at end of file From c69fcf69f423b292cae670d62debc07180112d2e Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 19 Aug 2025 15:33:41 +0200 Subject: [PATCH 25/70] convert meta gen into class --- .../vitis_unified_partial_writer/__init__.py | 0 .../vitis_unified_partial_writer/meta_gen.py | 0 .../writer/vitis_unified_writer/meta_gen.py | 142 +++++++++--------- 3 files changed, 72 insertions(+), 70 deletions(-) create mode 100644 hls4ml/writer/vitis_unified_partial_writer/__init__.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/meta_gen.py diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index 064043fb0d..5c7912a4fe 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -10,99 +10,101 @@ ## file and directory ################################# ####################################################### -def getGmemWrapperFileName(model): - return f"{model.config.get_project_name()}_dm" +class MetaGen: -def getAxiWrapperFileName(model): - return f"{model.config.get_project_name()}_axi" + def getGmemWrapperFileName(self, model): + return f"{model.config.get_project_name()}_dm" -def getMainWrapperFileName(model): - return model.config.get_project_name() + def getAxiWrapperFileName(self, model): + return f"{model.config.get_project_name()}_axi" -def getMainFileName(model): - return f"{model.config.get_project_name()}" + def getMainWrapperFileName(self, model): + return model.config.get_project_name() -def getVitisUnifiedWorkingDirectoryDir(model): - return os.path.join(model.config.get_output_dir(), "unifiedWorkspace") + def getMainFileName(self, model): + return f"{model.config.get_project_name()}" -def getVitisHlsDir(model): - vitisWorkingDir = getVitisUnifiedWorkingDirectoryDir(model) - return os.path.join(vitisWorkingDir, model.config.get_project_name()) + def getVitisUnifiedWorkingDirectoryDir(self, model): + return os.path.join(model.config.get_output_dir(), "unifiedWorkspace") -def getVitisHlsExecDir(model): - hlsDir = getVitisHlsDir(model) - return os.path.join(hlsDir, "unifiedPrj") + def getVitisHlsDir(self, model): + vitisWorkingDir = self.getVitisUnifiedWorkingDirectoryDir(model) + return os.path.join(vitisWorkingDir, model.config.get_project_name()) -def getVitisLinkerDir(model): - vitisWorkingDir = getVitisUnifiedWorkingDirectoryDir(model) - return os.path.join(vitisWorkingDir, "linker") + def getVitisHlsExecDir(self, model): + hlsDir = self.getVitisHlsDir(model) + return os.path.join(hlsDir, "unifiedPrj") -def getXOfileName(model): - return f"{getGemTopFuncName(model)}.xo" + def getVitisLinkerDir(self, model): + vitisWorkingDir = self.getVitisUnifiedWorkingDirectoryDir(model) + return os.path.join(vitisWorkingDir, "linker") -def getXOfilePath(model): - return os.path.join(getVitisHlsExecDir(model), getXOfileName(model)) + def getXOfileName(self, model): + return f"{self.getGemTopFuncName(model)}.xo" -####################################################### -## naming of variable function helper ################# -####################################################### + def getXOfilePath(self, model): + return os.path.join(self.getVitisHlsExecDir(model), self.getXOfileName(model)) + + ####################################################### + ## naming of variable function helper ################# + ####################################################### -####### FOR GMEM WRAPPER + ####### FOR GMEM WRAPPER -def getGmemIOPortName(tensorVar, isInput: bool, idx: int): - ioDirect = "in" if isInput else "out" - return f"gmem_{ioDirect}{str(idx)}_ptr_{tensorVar.name}" -def getGmemIOPortSizeName(tensorVar, isInput: bool, idx: int): - ioDirect = "in" if isInput else "out" - return f"gmem_{ioDirect}{str(idx)}_size_{tensorVar.name}" -def getGmemLocalStreamName(tensorVar, isInput: bool, idx: int): - ioDirect = "in" if isInput else "out" - return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" + def getGmemIOPortName(self, tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"gmem_{ioDirect}{str(idx)}_ptr_{tensorVar.name}" + def getGmemIOPortSizeName(self, tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"gmem_{ioDirect}{str(idx)}_size_{tensorVar.name}" + def getGmemLocalStreamName(self, tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" -def getDmaTypeName(): - return "dma_data_packet" + def getDmaTypeName(self): + return "dma_data_packet" -def getWrapperPortName(tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}" + def getWrapperPortName(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}" -def getTopModelName(model): - return f"{model.config.get_project_name()}" + def getTopModelName(self, model): + return f"{model.config.get_project_name()}" -def getGemTopFuncName(model): - return f"{model.config.get_project_name()}_gem" + def getGemTopFuncName(self, model): + return f"{model.config.get_project_name()}_gem" -def getAxisTopFuncName(model): - return f"{model.config.get_project_name()}_axi" + def getAxisTopFuncName(self, model): + return f"{model.config.get_project_name()}_axi" -### it is renamed for stitch layer -def renameType(tensorVar, layerIdx:int, isInput: bool): - return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" + ### it is renamed for stitch layer + def renameType(self, tensorVar, layerIdx:int, isInput: bool): + return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" -def get_inputSizeArrName(model): - return "N_IN_" + model.config.get_project_name() + def get_inputSizeArrName(self, model): + return "N_IN_" + model.config.get_project_name() -def get_outputSizeArrName(model): - return "N_OUT_" + model.config.get_project_name() + def get_outputSizeArrName(self, model): + return "N_OUT_" + model.config.get_project_name() -def get_axi_wrapper_type(tensorVar): - return f"{tensorVar.type.name}_packet" + def get_axi_wrapper_type(self, tensorVar): + return f"{tensorVar.type.name}_packet" -def get_axi_wrapper_dec(tensorVar): - return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {get_axi_wrapper_type(tensorVar)};" + def get_axi_wrapper_dec(self, tensorVar): + return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" -######################################################## -## axi_wrapper.h & axi_wrapper.cpp function helper #### -######################################################## -##### variable -def getWrapperPortNameLocal(tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_local" + ######################################################## + ## axi_wrapper.h & axi_wrapper.cpp function helper #### + ######################################################## + ##### variable + def getWrapperPortNameLocal(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_local" -def getWrapperTmpName(tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_tmp" + def getWrapperTmpName(self, tensorVar, isInput: bool): + ioStr = "in" if isInput else "out" + return f"par_{ioStr}_{tensorVar.name}_tmp" -def getWrapperIsLastCnt(idx): - return f"isLastCnt_{str(idx)}" \ No newline at end of file + def getWrapperIsLastCnt(self, idx): + return f"isLastCnt_{str(idx)}" \ No newline at end of file From b5084738fbe4a7ad3592579c0ecec71c3b4adf35 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 19 Aug 2025 21:35:40 +0200 Subject: [PATCH 26/70] refractor vitisUnified backend to be a multiple subclass and build axi wrapper for vitisUnified partial backend and build the skeleton code for other generation section --- .../templates/vitis_unified/myproject_axi.h | 3 +- .../vitis_unified_partial/myproject_axi.cpp | 27 +- .../driver_gen.py | 27 ++ .../vitis_unified_partial_writer/meta.py | 2 + .../vitis_unified_partial_writer/meta_gen.py | 102 ++++++ .../vitis_unified_partial_writer/mgs_gen.py | 18 + .../test_bridge_gen.py | 28 ++ .../test_cosim_gen.py | 26 ++ .../vitis_unified_partial_writer/wrap_gen.py | 133 ++++++++ .../writer/vitis_unified_writer/driver_gen.py | 101 +++--- .../writer/vitis_unified_writer/meta_gen.py | 98 +++--- hls4ml/writer/vitis_unified_writer/mm_gen.py | 123 ------- .../writer/vitis_unified_writer/stream_gen.py | 316 ------------------ .../vitis_unified_writer/test_bridge_gen.py | 173 +++++----- .../vitis_unified_writer/test_cosim_gen.py | 232 ++++++------- .../writer/vitis_unified_writer/wrap_gen.py | 126 +++++++ 16 files changed, 780 insertions(+), 755 deletions(-) create mode 100644 hls4ml/writer/vitis_unified_partial_writer/driver_gen.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/meta.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py create mode 100644 hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py delete mode 100644 hls4ml/writer/vitis_unified_writer/mm_gen.py delete mode 100644 hls4ml/writer/vitis_unified_writer/stream_gen.py create mode 100644 hls4ml/writer/vitis_unified_writer/wrap_gen.py diff --git a/hls4ml/templates/vitis_unified/myproject_axi.h b/hls4ml/templates/vitis_unified/myproject_axi.h index 2ccc3b7d23..43ee01d5df 100644 --- a/hls4ml/templates/vitis_unified/myproject_axi.h +++ b/hls4ml/templates/vitis_unified/myproject_axi.h @@ -3,8 +3,9 @@ #define MYPROJECT_AXI_H_ #include -// hls-fpga-machine-learning insert include +#include "ap_axi_sdata.h +#include "MY_PROJECT_AXI_INC.h" // hls-fpga-machine-learning insert definitions void myproject_axi( diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp index b98be9ede3..7906a89d76 100644 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp @@ -1,4 +1,7 @@ -// hls-fpga-machine-learning insert include +#include +#include +#include + template @@ -18,12 +21,12 @@ void enqueue_atom2layer(hls::stream& src_dma_stream, hls::strea } template -void enqueue_layerStream2layer(hls::stream& src_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ +void enqueue_layerStream2layer(hls::stream& src_mgs_stream, hls::stream& raw_stream, bool& isLastIndicate){ INPUT_LAYER_STREAM input_layer_stream_tmp; for (unsigned i = 0; i < (SIZE/INPUT_LAYER_ARR::size); i++){ INPUT_LAYER_ARR ctype; - src_dma_stream.read(input_layer_stream_tmp); + src_mgs_stream.read(input_layer_stream_tmp); ctype = input_layer_stream_tmp.data; isLastIndicate = input_layer_stream_tmp.last; raw_stream.write(ctype); @@ -51,7 +54,7 @@ void dequeue_layer2atom(hls::stream& des_dma_stream, hls::strea } template -void dequeue_layer2layer(hls::stream& des_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ +void dequeue_layer2layer(hls::stream& des_mgs_stream, hls::stream& raw_stream, bool& isLastIndicate){ OUTPUT_LAYER_STREAM output_layer_stream_tmp; output_layer_stream_tmp.last = 0; @@ -61,23 +64,23 @@ void dequeue_layer2layer(hls::stream& des_dma_stream, hls:: if(isLastIndicate){ output_layer_stream_tmp.last = ((i+1) == (SIZE/OUTPUT_LAYER_ARR::size)); } - des_dma_stream.write(output_layer_stream_tmp); + des_mgs_stream.write(output_layer_stream_tmp); } } -void myproject_axi( - // hls-fpga-machine-learning insert multiIo +void MY_PROJECT_TOP_FUNC( +// hls-fpga-machine-learning insert multi-io ) { - // hls-fpga-machine-learning insert interface +// hls-fpga-machine-learning insert interface - // hls-fpga-machine-learning insert local vars +// hls-fpga-machine-learning insert local vars - // hls-fpga-machine-learning insert enqueue +// hls-fpga-machine-learning insert enqueue - // hls-fpga-machine-learning insert call +// hls-fpga-machine-learning insert call - // hls-fpga-machine-learning insert dequeue +// hls-fpga-machine-learning insert dequeue } diff --git a/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py b/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py new file mode 100644 index 0000000000..cb69cacb6c --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py @@ -0,0 +1,27 @@ +import os +import stat +from pathlib import Path + + +from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +from hls4ml.writer.vitis_unified_writer.driver_gen import VitisUnified_DriverGen +from .meta_gen import VitisUnifiedPartial_MetaGen as mg + +class VitisUnifiedPartial_DriverGen(VitisUnified_DriverGen): + + + @classmethod + def write_driver(self, meta: VitisUnifiedWriterMeta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/driver/pynq/pynq_driver.py'), 'r') + fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') + + + for line in fin.readlines(): + newline = line + ##### TODO + fout.write(newline) + + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta.py b/hls4ml/writer/vitis_unified_partial_writer/meta.py new file mode 100644 index 0000000000..7bed812196 --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/meta.py @@ -0,0 +1,2 @@ + +### meta is using from vitis unified writer \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py index e69de29bb2..82c3899516 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py @@ -0,0 +1,102 @@ +from hls4ml.writer.vitis_unified_writer.meta_gen import VitisUnified_MetaGen + +class VitisUnifiedPartial_MetaGen(VitisUnified_MetaGen): + + ################################################## + ## file and directory ############################ + ################################################## + + @classmethod + def get_wrapper_file_name(self, model): + return f"{model.config.get_project_name()}_axi" + + ################################################## + ## naming function and variable ############### + ################################################## + + @classmethod + def get_io_port_name(self, tensorVar, isInput: bool, idx: int): + ioDirect = "in" if isInput else "out" + return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" + + @classmethod + def get_top_wrap_func_name(self, model): + return f"{model.config.get_project_name()}_axis" + + @classmethod + def get_input_size_arr_name(self, model): + return "N_IN_" + model.config.get_project_name() + + @classmethod + def get_output_size_arr_name(self, model): + return "N_OUT_" + model.config.get_project_name() + + @classmethod + def get_axi_wrapper_type(self, tensorVar): + return f"{tensorVar.type.name}_packet" + + @classmethod + def get_axi_wrapper_dec(self, tensorVar): + return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" + + @classmethod + def get_is_last_var(self, idx): + return f"isLast_{str(idx)}" + + @classmethod + def get_all_last_logic(self, amt): + isLastList = [self.get_is_last_var(idx) for idx in range(amt)] + return " & ".join(isLastList) + + ################################################## + ## generation function call ############### + ################################################## + + @classmethod + def get_enqueue_func_atom2stream(self, tensorVar, idx: int): + result = "enqueue_atom2layer<{INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( + INPUT_LAYER_ARR = tensorVar.type.name, + SIZE = str(tensorVar.size), + SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), + RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), + IS_LAST = self.get_is_last_var(idx), + ) + return result + + @classmethod ## rStream == raw stream (no tlast) + def get_enqueue_func_stream2rstream(self, tensorVar, idx: int): + result = "enqueue_layerStream2layer<{INPUT_LAYER_STREAM}, {INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( + INPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), + INPUT_LAYER_ARR = tensorVar.type.name, + SIZE = str(tensorVar.size), + SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), + RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), + IS_LAST = self.get_is_last_var(idx), + ) + return result + + @classmethod + def get_dequeue_func_rstream2atom(self, tensorVar, idx: int, lastcheck: str,out_dma_type: str = "float"): + result = "dequeue_layer2atom<{ATOMIC_TYPE}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK});".format( + ATOMIC_TYPE = out_dma_type, + OUTPUT_LAYER_ARR = tensorVar.type.name, + SIZE = str(tensorVar.size), + DES_STREAM = self.get_io_port_name(tensorVar, False, idx), + RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), + IS_LAST_CHECK = lastcheck + ) + return result + + @classmethod + def get_dequeue_func_rstream2stream(self, tensorVar, idx: int, lastcheck: str): + result = "dequeue_layer2layer><{OUTPUT_LAYER_STREAM}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK})".format( + OUTPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), + OUTPUT_LAYER_ARR = tensorVar.type.name, + SIZE = str(tensorVar.size), + DES_STREAM = self.get_io_port_name(tensorVar, False, idx), + RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), + IS_LAST_CHECK = lastcheck + ) + return result + + diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py new file mode 100644 index 0000000000..ff0ae86413 --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -0,0 +1,18 @@ +import os +import stat +from pathlib import Path + + +from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +from .meta_gen import VitisUnifiedPartial_MetaGen as mg + +class VitisUnifiedPartial_MgsGen(): + + @classmethod + def write_mgs(self, meta: VitisUnifiedWriterMeta, model): + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_mgs.cpp'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_mgs.cpp', 'w') + + diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py new file mode 100644 index 0000000000..26d38e3acf --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py @@ -0,0 +1,28 @@ +import os + +from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +from hls4ml.writer.vitis_unified_writer.test_bridge_gen import VitisUnified_BridgeGen +from .meta_gen import VitisUnifiedPartial_MetaGen as mg + +class VitisUnifiedPartial_BridgeGen(VitisUnified_BridgeGen): + + + def write_bridge(meta: VitisUnifiedWriterMeta, model): + + filedir = os.path.dirname(os.path.abspath(__file__)) + #### we will use the same bridge template file as VitisUnified_BridgeGen + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') + + indent = ' ' + + + for line in fin.readlines(): + + #### TODO we will do the code next time + newline = line + fout.write(newline) + + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py new file mode 100644 index 0000000000..eef408f64d --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py @@ -0,0 +1,26 @@ +import os + +from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +from hls4ml.writer.vitis_unified_writer.test_cosim_gen import VitisUnified_TestGen +from .meta_gen import VitisUnifiedPartial_MetaGen as mg + + +class VitisUnifiedPartial_TestGen(VitisUnified_TestGen): + + @classmethod + def write_wrapper(self, meta, model): + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + + + filedir = os.path.dirname(os.path.abspath(__file__)) + #### we use the same file as vitis unified + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + + + fout.write("//// generated by Vitis Unified Backend\n") + + for line in f.readlines(): + newline = line + #### TODO we will do it next + fout.write(newline) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py new file mode 100644 index 0000000000..e474f0c136 --- /dev/null +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -0,0 +1,133 @@ +import os +from pathlib import Path +import stat +from shutil import copyfile + +from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +from hls4ml.writer.vitis_unified_writer.wrap_gen import VitisUnified_WrapperGen +from .meta_gen import VitisUnifiedPartial_MetaGen as mg + +class VitisUnifiedPartial_WrapperGen(VitisUnified_WrapperGen): + + @classmethod + def gen_io_str(self, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): + inputStreamList = [] + outputStreamList = [] + + + for inp_idx, inp in enumerate(inps): + inp_type = mg.get_dma_type_name() + if (meta.vitis_unified_config.isFreeInterimInput()) and \ + (meta.vitis_unified_config.getGraphIdx() != 0 ): + inp_type = mg.get_axi_wrapper_type(inp) + inputStreamList.append(f"{indent} hls::stream<{inp_type}>& {mg.get_io_port_name(inp, True, inp_idx)}") + + for out_idx, out in enumerate(outs): + out_type = mg.get_dma_type_name() + if (meta.vitis_unified_config.isFreeInterimOutput()) and \ + (meta.vitis_unified_config.getGraphIdx() != (meta.vitis_unified_config.getGraphAmtGraph()-1) ): + out_type = mg.get_axi_wrapper_type(out) + outputStreamList.append(f"{indent} hls::stream<{out_type}>& {mg.get_io_port_name(out, False, out_idx)}") + + return ", \n".join(inputStreamList) + ",\n" + ", \n".join() + + @classmethod + def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): + + inp_axis_t, out_axis_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + indent = ' ' + + ####################################### + ###### start write myproject_axi.cpp ## + ####################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.cpp'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_axi.cpp', 'w') + + + for line in fin.readlines(): + + if "MY_PROJECT_AXI_INC" in line: + line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + elif "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) + elif "// hls-fpga-machine-learning insert multi-io" in line: + line = self.gen_io_str(indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" + elif "// hls-fpga-machine-learning insert interface" in line: + for inp_idx, inp in enumerate(inps): + line += f"{indent} #pragma HLS INTERFACE axis port={mg.get_io_port_name(inp, True, inp_idx)}\n" + for out_idx, out in enumerate(outs): + line += f"{indent} #pragma HLS INTERFACE axis port={mg.get_io_port_name(out, False, out_idx)}\n" + elif "// hls-fpga-machine-learning insert local vars" in line: + #### declare stream variable + for inp_idx, inp in enumerate(inps): + line += f"{indent} static hls::stream<{inp.type.name}> {mg.get_local_stream_name(inp, True, inp_idx)};\n" + for out_idx, out in enumerate(outs): + line += f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" + #### declare stream size + for inp_idx, inp in enumerate(inps): + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth={inp[inp_idx].pragma[1]}\n" + for out_idx, out in enumerate(outs): + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth={out[out_idx].pragma[1]}\n" + + + elif "// hls-fpga-machine-learning insert enqueue" in line: + for inp_idx, inp in enumerate(inps): + if meta.vitis_unified_config.isFreeInterimInput(): + line += mg.get_enqueue_func_stream2rstream(inp, inp_idx) + else: + line += mg.get_enqueue_func_atom2stream(inp, inp_idx) + + elif "// hls-fpga-machine-learning insert call" in line: + poolList = [] + for inp_idx, inp in enumerate(inps): + poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") + for out_idx, out in enumerate(outs): + poolList.append(f"{mg.get_local_stream_name(out, False, out_idx)}") + joinedIo = ", \n".join(poolList) + line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" + + elif "// hls-fpga-machine-learning insert dequeue" in line: + for out_idx, out in enumerate(outs): + if meta.vitis_unified_config.isFreeInterimOutput(): + line += mg.get_dequeue_func_rstream2stream(out, out_idx, + mg.get_all_last_logic(len(inps))) + "\n" + else: + line += mg.get_dequeue_func_rstream2atom(out, out_idx, mg.get_all_last_logic(len(inps)), + out_axis_t) + "\n" + + fout.write(line) + fin.close() + fout.close() + + ####################################### + ###### start write myproject_axi.h ## + ####################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.h'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_axi.h', 'w') + + for line in fin.readlines(): + if "MY_PROJECT_AXI_INC" in line: + line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + elif "// hls-fpga-machine-learning insert definitions" in line: + ##### make input + newline = '' + inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" + newline += f'constexpr unsigned {mg.get_input_size_arr_name(model)} [{len(inps)}] = {inputSizeStr};\n' + + ##### make output + outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" + newline += f'constexpr unsigned {mg.get_output_size_arr_name(model)} [{len(outs)}] = {outputSizeStr};\n' + newline += f'typedef hls::axis<{inp_axis_t}, 0, 0, 0, AXIS_ENABLE_LAST> dma_data_packet;\n' + #### incase the io is interim input + if meta.vitis_unified_config.isFreeInterimInput(): + for inp in inps: + newline += mg.get_axi_wrapper_dec(inp) + "\n" + #### incase the io is interim output + if meta.vitis_unified_config.isFreeInterimOutput(): + for out in outs: + newline += mg.get_axi_wrapper_dec(out) + "\n" + diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py index ddd12c559c..60c0471715 100644 --- a/hls4ml/writer/vitis_unified_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -4,52 +4,55 @@ from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg - -def write_driver(meta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py'), 'r') - fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') - - inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - - strideInPtrAddr = 4*3 - strideOutPtrAddr = 4*3 - strideInSizeAddr = 4*2 - strideOutSizeAddr = 4*2 - - startInPtrAddr = 0x10 - startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) - startInSizeAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) - startOutSizeAddr = startInSizeAddr + strideInSizeAddr * len(inps) - - def genHexAddrList(startAddr, stride, size, indent): - addrs = [f"{indent}{hex(startAddr + inp_idx * stride)}" for inp_idx in range(size)] - return addrs - - indentAmt = 3 - indentStr = indentAmt * " " if indentAmt > 0 else "" - - for line in fin.readlines(): - - if "#### hls-driver-input-dbg-name" in line: - input_names = [ f'{indentStr}"{mg.getGmemIOPortName(inp, True, idx)}"' for idx, inp in enumerate(inps) ] - line += ",\n".join(input_names) + "\n" - if "#### hls-driver-input-ptr" in line: - line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" - if "#### hls-driver-input-size" in line: - line += ",\n".join(genHexAddrList(startInSizeAddr, strideInSizeAddr, len(inps), indentStr)) + "\n" - if "#### hls-driver-output-dbg-name" in line: - output_names = [ f'{indentStr}"{mg.getGmemIOPortName(out, False, idx)}"' for idx, out in enumerate(outs) ] - line += ",\n".join(output_names) + "\n" - if "#### hls-driver-output-ptr" in line: - line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" - if "#### hls-driver-output-size" in line: - line += ",\n".join(genHexAddrList(startOutSizeAddr, strideOutSizeAddr, len(outs), indentStr)) + "\n" - if "" in line: - line = line.replace("", mg.getGemTopFuncName(model)) - - fout.write(line) - - fin.close() - fout.close() \ No newline at end of file +from .meta_gen import VitisUnified_MetaGen as mg + +class VitisUnified_DriverGen: + + @classmethod + def write_driver(self, meta, model): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py'), 'r') + fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') + + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + + strideInPtrAddr = 4*3 + strideOutPtrAddr = 4*3 + strideInSizeAddr = 4*2 + strideOutSizeAddr = 4*2 + + startInPtrAddr = 0x10 + startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) + startInSizeAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) + startOutSizeAddr = startInSizeAddr + strideInSizeAddr * len(inps) + + def genHexAddrList(startAddr, stride, size, indent): + addrs = [f"{indent}{hex(startAddr + inp_idx * stride)}" for inp_idx in range(size)] + return addrs + + indentAmt = 3 + indentStr = indentAmt * " " if indentAmt > 0 else "" + + for line in fin.readlines(): + + if "#### hls-driver-input-dbg-name" in line: + input_names = [ f'{indentStr}"{mg.get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inps) ] + line += ",\n".join(input_names) + "\n" + if "#### hls-driver-input-ptr" in line: + line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" + if "#### hls-driver-input-size" in line: + line += ",\n".join(genHexAddrList(startInSizeAddr, strideInSizeAddr, len(inps), indentStr)) + "\n" + if "#### hls-driver-output-dbg-name" in line: + output_names = [ f'{indentStr}"{mg.get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outs) ] + line += ",\n".join(output_names) + "\n" + if "#### hls-driver-output-ptr" in line: + line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" + if "#### hls-driver-output-size" in line: + line += ",\n".join(genHexAddrList(startOutSizeAddr, strideOutSizeAddr, len(outs), indentStr)) + "\n" + if "" in line: + line = line.replace("", mg.get_top_wrap_func_name(model)) + + fout.write(line) + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index 5c7912a4fe..6915c0c16a 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -10,40 +10,46 @@ ## file and directory ################################# ####################################################### -class MetaGen: +class VitisUnified_MetaGen: - def getGmemWrapperFileName(self, model): + @classmethod + def get_wrapper_file_name(self, model): return f"{model.config.get_project_name()}_dm" - def getAxiWrapperFileName(self, model): - return f"{model.config.get_project_name()}_axi" - - def getMainWrapperFileName(self, model): + @classmethod + def get_main_wrapper_file_name(self, model): return model.config.get_project_name() - def getMainFileName(self, model): - return f"{model.config.get_project_name()}" + @classmethod + def get_main_file_name(self, model): + return model.config.get_project_name() - def getVitisUnifiedWorkingDirectoryDir(self, model): + @classmethod + def get_vitis_unified_working_directory_dir(self, model): return os.path.join(model.config.get_output_dir(), "unifiedWorkspace") - def getVitisHlsDir(self, model): - vitisWorkingDir = self.getVitisUnifiedWorkingDirectoryDir(model) + @classmethod + def get_vitis_hls_dir(self, model): + vitisWorkingDir = self.get_vitis_unified_working_directory_dir(model) return os.path.join(vitisWorkingDir, model.config.get_project_name()) - def getVitisHlsExecDir(self, model): - hlsDir = self.getVitisHlsDir(model) + @classmethod + def get_vitis_hls_exec_dir(self, model): + hlsDir = self.get_vitis_hls_dir(model) return os.path.join(hlsDir, "unifiedPrj") - def getVitisLinkerDir(self, model): - vitisWorkingDir = self.getVitisUnifiedWorkingDirectoryDir(model) + @classmethod + def get_vitis_linker_dir(self, model): + vitisWorkingDir = self.get_vitis_unified_working_directory_dir(model) return os.path.join(vitisWorkingDir, "linker") - def getXOfileName(self, model): - return f"{self.getGemTopFuncName(model)}.xo" + @classmethod + def get_xo_file_name(self, model): + return f"{self.get_top_wrap_func_name(model)}.xo" - def getXOfilePath(self, model): - return os.path.join(self.getVitisHlsExecDir(model), self.getXOfileName(model)) + @classmethod + def get_xo_file_path(self, model): + return os.path.join(self.get_vitis_hls_exec_dir(model), self.get_xo_file_name(model)) ####################################################### ## naming of variable function helper ################# @@ -51,60 +57,38 @@ def getXOfilePath(self, model): ####### FOR GMEM WRAPPER - def getGmemIOPortName(self, tensorVar, isInput: bool, idx: int): + @classmethod + def get_io_port_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" return f"gmem_{ioDirect}{str(idx)}_ptr_{tensorVar.name}" - def getGmemIOPortSizeName(self, tensorVar, isInput: bool, idx: int): + @classmethod + def get_io_port_size_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" return f"gmem_{ioDirect}{str(idx)}_size_{tensorVar.name}" - def getGmemLocalStreamName(self, tensorVar, isInput: bool, idx: int): + @classmethod + def get_local_stream_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" - def getDmaTypeName(self): + @classmethod + def get_dma_type_name(self): return "dma_data_packet" - def getWrapperPortName(self, tensorVar, isInput: bool): + @classmethod + def get_wrapper_port_name(self, tensorVar, isInput: bool): ioStr = "in" if isInput else "out" return f"par_{ioStr}_{tensorVar.name}" - def getTopModelName(self, model): + @classmethod + def get_top_model_name(self, model): return f"{model.config.get_project_name()}" - def getGemTopFuncName(self, model): + @classmethod + def get_top_wrap_func_name(self, model): return f"{model.config.get_project_name()}_gem" - def getAxisTopFuncName(self, model): - return f"{model.config.get_project_name()}_axi" - ### it is renamed for stitch layer - def renameType(self, tensorVar, layerIdx:int, isInput: bool): + @classmethod + def rename_type(self, tensorVar, layerIdx: int, isInput: bool): return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" - def get_inputSizeArrName(self, model): - return "N_IN_" + model.config.get_project_name() - - def get_outputSizeArrName(self, model): - return "N_OUT_" + model.config.get_project_name() - - def get_axi_wrapper_type(self, tensorVar): - return f"{tensorVar.type.name}_packet" - - def get_axi_wrapper_dec(self, tensorVar): - return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" - - - ######################################################## - ## axi_wrapper.h & axi_wrapper.cpp function helper #### - ######################################################## - ##### variable - def getWrapperPortNameLocal(self, tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_local" - - def getWrapperTmpName(self, tensorVar, isInput: bool): - ioStr = "in" if isInput else "out" - return f"par_{ioStr}_{tensorVar.name}_tmp" - - def getWrapperIsLastCnt(self, idx): - return f"isLastCnt_{str(idx)}" \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/mm_gen.py b/hls4ml/writer/vitis_unified_writer/mm_gen.py deleted file mode 100644 index 09c20c4ac7..0000000000 --- a/hls4ml/writer/vitis_unified_writer/mm_gen.py +++ /dev/null @@ -1,123 +0,0 @@ -import os -from pathlib import Path -import stat -from shutil import copyfile - -from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg - -################################################################################ -###### main function ########################################################### -################################################################################ - -def genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs): - - inputPtrList = [] - outputPtrList = [] - inputSizeList = [] - outputSizeList = [] - - for inp_idx, inp in enumerate(inps): - inputPtrList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(inp, True, inp_idx)}") - inputSizeList.append(f"{indent} int {mg.getGmemIOPortSizeName(inp, True, inp_idx)}") - - for out_idx, out in enumerate(outs): - outputPtrList.append(f"{indent} {inp_gmem_t}* {mg.getGmemIOPortName(out, False, out_idx)}") - outputSizeList.append(f"{indent} int {mg.getGmemIOPortSizeName(out, False, out_idx)}") - - - line = ", ".join(inputPtrList) + ",\n" - line += ", ".join(outputPtrList) + ",\n" - line += ", ".join(inputSizeList) + ",\n" - line += ", ".join(outputSizeList) - - return line - - -def write_gmem_wrapper(meta: VitisUnifiedWriterMeta, model): - - inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - indent = ' ' - - ###################################### - ###### start write myproject_dm.cpp ## - ###################################### - - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') - - for line in fin.readlines(): - - if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.getMainWrapperFileName(model)) - if "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) - elif "DMX_BUF_IN_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) - elif "DMX_BUF_OUT_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) - elif "// vitis-unified-wrapper-io" in line: - line = genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" - elif "// vitis-unified-wrapper-interface" in line: - for inp_idx, inp in enumerate(inps): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" - line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.getGmemIOPortSizeName(inp, True, inp_idx)} bundle = control\n" - for out_idx, out in enumerate(outs): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.getGmemIOPortName(out, False, out_idx)} bundle = gmem_out{out_idx}\n" - line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.getGmemIOPortSizeName(out, False, out_idx)} bundle = control\n" - elif "// vitis-unified-wrapper-stream-dec" in line: - - for inp_idx, inp in enumerate(inps): - line += f"{indent} static hls::stream<{inp.type.name}> {mg.getGmemLocalStreamName(inp, True, inp_idx)};\n" - for out_idx, out in enumerate(outs): - line += f"{indent} static hls::stream<{out.type.name}> {mg.getGmemLocalStreamName(out, False, out_idx)};\n" - - elif "// vitis-unified-wrapper-stream-config" in line: - for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS STREAM variable={mg.getGmemLocalStreamName(inp, True, inp_idx)} depth=DMX_BUF_IN_SZ\n" - for out_idx, out in enumerate(outs): - line += f"#pragma HLS STREAM variable={mg.getGmemLocalStreamName(out, False, out_idx)} depth=DMX_BUF_OUT_SZ\n" - - elif "// vitis-unified-wrapper-load" in line: - for inp_idx, inp in enumerate(inps): - line += f"load_input({mg.getGmemIOPortName(inp, True, inp_idx)}, {mg.getGmemLocalStreamName(inp, True, inp_idx)}, {mg.getGmemIOPortSizeName(inp, True, inp_idx)});\n" - elif "// vitis-unified-wrapper-compute" in line: - poolList = [] - for inp_idx, inp in enumerate(inps): - poolList.append(f"{mg.getGmemLocalStreamName(inp, True, inp_idx)}") - for out_idx, out in enumerate(outs): - poolList.append(f"{mg.getGmemLocalStreamName(out, False, out_idx)}") - joinedIo = ", \n".join(poolList) - line += f"{indent} {mg.getTopModelName(model)}({joinedIo});\n" - - elif "// vitis-unified-wrapper-store" in line: - for out_idx, out in enumerate(outs): - line += f"store_result({mg.getGmemIOPortName(out, False, out_idx)}, {mg.getGmemLocalStreamName(out, False, out_idx)}, {mg.getGmemIOPortSizeName(out, False, out_idx)});\n" - - fout.write(line) - - - fin.close() - fout.close() - - ###################################### - ###### start write myproject_dm.h ## - ###################################### - - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.h'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.h', 'w') - - for line in fin.readlines(): - - if "FILENAME" in line: - line = line.replace("FILENAME", mg.getGmemWrapperFileName(model).upper()) - elif "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("MY_PROJECT_TOP_FUNC", mg.getGemTopFuncName(model)) - elif "// vitis-unified-wrapper-io" in line: - line += genIoStr(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" - fout.write(line) - - fin.close() - fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/stream_gen.py b/hls4ml/writer/vitis_unified_writer/stream_gen.py deleted file mode 100644 index a6d136a260..0000000000 --- a/hls4ml/writer/vitis_unified_writer/stream_gen.py +++ /dev/null @@ -1,316 +0,0 @@ -import os -from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg - - -def write_axi_wrapper_io(meta: VitisUnifiedWriterMeta, inps, outs): - inputList = [] - outputList = [] - for inp in inps: - streamType = mg.get_axi_wrapper_type(inp) if meta.vitis_unified_config.isFreeInterimInput() else "dma_data_packet" - inputList.append(f'hls::stream<{streamType}>& {mg.getWrapperPortName(inp, True)}') - for out in outs: - streamType = mg.get_axi_wrapper_type(out) if meta.vitis_unified_config.isFreeInterimOutput() else "dma_data_packet" - outputList.append(f'hls::stream<{streamType}> & {mg.getWrapperPortName(out, False)}') - - if len(inputList) == 0 or len(outputList) == 0: - raise Exception("No input or output stream found") - newline = "/////// inputs\n" + ",\n ".join(inputList) + ",\n\n ///outputs\n " + ", ".join(outputList) + "\n" - return newline -##### content in axi_wrapper.cpp -def write_axi_wrapper_interface(meta: VitisUnifiedWriterMeta, model, inps, outs): - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline = '' - indent = " " - for inp in inps: - portname = mg.getWrapperPortName(inp, True) - newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' - for out in outs: - portname = mg.getWrapperPortName(out, False) - newline += indent + f'#pragma HLS INTERFACE axis port={portname}\n' - if model.config.get_config_value("IOType") == 'io_stream': - newline += indent + '#pragma HLS INTERFACE ap_ctrl_none port=return\n' - newline += indent + '#pragma HLS DATAFLOW\n' - return newline - else: - raise Exception("vitis_unified supports only axi_stream @ interface retriever") - -def write_axi_local_vars(meta: VitisUnifiedWriterMeta, model, inps, outs): - - ####### build local stream variable - - newline = '///// wrinting local stream vars /////\n' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - indent = " " - ##### loop to build local stream to send data into the system - newline += '///////// build input vars ///////////\n' - for idx, inp in enumerate(inps): - newline += f" bool {mg.getWrapperIsLastCnt(idx)} = false;\n" - portname = mg.getWrapperPortNameLocal(inp, True) - newline += indent + f'hls::stream<{inp.type.name}> {portname}("{portname}");\n' - newline += '///////// build output vars ///////////\n' - for out in outs: - portname = mg.getWrapperPortNameLocal(out, False) - newline += indent + f'hls::stream<{out.type.name}> {portname}("{portname}");\n' - - ####### set stream DEPTH - - newline += '///////// set the stream depth ///////////\n' - ##### loop to set depth - - for inpIdx, inp in enumerate(inps): - portname = mg.getWrapperPortNameLocal(inp, True) - newline += indent + f'#pragma HLS STREAM variable={portname} depth={inps[inpIdx].pragma[1]}\n' - for outIdx, out in enumerate(outs): - portname = mg.getWrapperPortNameLocal(out, False) - newline += indent + f'#pragma HLS STREAM variable={portname} depth={model.get_output_variables()[outIdx].pragma[1]}\n' - - return newline - - else: - raise Exception("vitis_unified supports only axi_stream @ local vars") - - -def write_axi_wrapper_each_enqueue(meta: VitisUnifiedWriterMeta, model, inps, idx): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'dma_data_packet {mg.getWrapperTmpName(inps[idx], True)};\n' - newline += indent + f"{mg.getWrapperTmpName(inps[idx], True)}.last = 0;\n" - ### newline += indent + f'{inps[idx].type.name}\n' - newline += indent + f'for(unsigned i = 0; i < {mg.get_inputSizeArrName(model)}[' +str(idx) +']/' + inps[idx].type.name + '::size; ++i){\n' - newline += indent + indent + inps[idx].type.name + ' ctype;\n' - newline += indent + indent + 'for(unsigned j = 0; j < '+ inps[idx].type.name + '::size; ++j){\n' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline += indent + indent + indent + mg.getWrapperPortName(inps[idx], True) + f'.read({mg.getWrapperTmpName(inps[idx], True)});\n' - newline += indent + indent + indent + "ctype[j] = " + mg.getWrapperTmpName(inps[idx], True) + ".data;\n" - newline += indent + indent + indent + mg.getWrapperIsLastCnt(idx) + " = " + mg.getWrapperTmpName(inps[idx], True) + ".last;\n" - else: - raise Exception("vitis_unified supports only axi_stream @ each enqueue") - - newline += indent + indent + '}\n' - newline += indent + indent + mg.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" - newline += indent + '}\n' - newline += indent + mg.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" - - else: - raise Exception("vitis_unified supports only io_stream @ each enqueue") - - return newline - -def write_free_axi_wrapper_each_enqueue(meta: VitisUnifiedWriterMeta, model, inps, idx): - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// enqueue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'{mg.get_axi_wrapper_type(inps[idx])} {mg.getWrapperTmpName(inps[idx], True)};\n' - newline += indent + f"{mg.getWrapperTmpName(inps[idx], True)}.last = 0;\n" - newline += indent + f'for(unsigned i = 0; i < {mg.get_inputSizeArrName(model)}[' + str(idx) + ']/' + inps[ - idx].type.name + '::size; ++i){\n' - newline += indent + indent + inps[idx].type.name + ' ctype;\n' - newline += indent + indent + mg.getWrapperPortName(inps[idx], True) + f'.read({mg.getWrapperTmpName(inps[idx], True)});\n' - newline += indent + indent + "ctype = " + mg.getWrapperTmpName(inps[idx], True) + ".data;\n" - newline += indent + indent + mg.getWrapperIsLastCnt(idx) + " = " + mg.getWrapperTmpName(inps[idx], True) + ".last;\n" - newline += indent + indent + mg.getWrapperPortNameLocal(inps[idx], True) + ".write(ctype);\n" - newline += indent + '}\n' - newline += indent + mg.getWrapperTmpName(inps[idx], True) + ".last = 0;\n" - else: - raise Exception("vitis_unified supports only io_stream @ each free axi enqueue") - - return newline - -def write_axi_wrapper_dequeue(meta: VitisUnifiedWriterMeta, model, inputs, outs, idx, out_axi_t): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'dma_data_packet {mg.getWrapperTmpName(outs[idx], False)};\n' - newline += indent + f"{mg.getWrapperTmpName(outs[idx], False)}.last = 0;\n" - ####### the tmp must copy from input to prevent dma get stuck - newline += indent + f'for(unsigned i = 0; i < {mg.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' - newline += indent + indent + outs[idx].type.name + ' ctype = ' + mg.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' - newline += indent + indent + 'for(unsigned j = 0; j < ' + outs[idx].type.name + '::size; ++j){\n' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline += indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f'.data = ({out_axi_t}) (ctype[j]);\n' - poolLastCondition = " & ".join([mg.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) - newline += indent + indent + indent + f"if({poolLastCondition}){{\n" - newline += indent + indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f".last = (((i+1)*(j+1))=={mg.get_outputSizeArrName(model)}[{str(idx)}]);\n" - newline += indent + indent + indent + "}\n" - newline += indent + indent + indent + mg.getWrapperPortName(outs[idx], False) + f'.write({mg.getWrapperTmpName(outs[idx], False)});\n' - newline += indent + indent + "}\n" - newline += indent + "}\n" - newline += indent + mg.getWrapperTmpName(outs[idx], False) + ".last = 0;\n" - else: - raise Exception("vitis_unified supports only axi_stream @ each dequeue") - else: - raise Exception("vitis_unified supports only io_stream @ each dequeue") - - return newline - -def write_free_axi_wrapper_dequeue(meta: VitisUnifiedWriterMeta, model, inputs, outs, idx, out_axi_t): - - io_type = model.config.get_config_value("IOType") - indent = " " - newline = "\n\n\n" - if io_type == 'io_stream': - newline += '////////////// dequeue number ' + str(idx) + ' //////////////\n' - newline += indent + "///// temp var \n" - newline += indent + f'{mg.get_axi_wrapper_type(outs[idx])} {mg.getWrapperTmpName(outs[idx], False)};\n' - newline += indent + f"{mg.getWrapperTmpName(outs[idx], False)}.last = 0;\n" - ####### the tmp must copy from input to prevent dma get stuck - newline += indent + f'for(unsigned i = 0; i < {mg.get_outputSizeArrName(model)}[' +str(idx) +']/' + outs[idx].type.name + '::size; ++i){\n' - newline += indent + indent + outs[idx].type.name + ' ctype = ' + mg.getWrapperPortNameLocal(outs[idx], False) + '.read();\n' - newline += indent + indent + mg.getWrapperTmpName(outs[idx], False) + ".data = ctype;\n" - poolLastCondition = " & ".join([mg.getWrapperIsLastCnt(condIdx) for condIdx in range(len(inputs))]) - newline += indent + indent + f"if({poolLastCondition}){{\n" - newline += indent + indent + indent + mg.getWrapperTmpName(outs[idx], False) + f".last = ((i+1) == ({mg.get_outputSizeArrName(model)}[{str(idx)}] / {outs[idx].type.name + '::size'} ));\n" - newline += indent + indent + "}\n" - newline += indent + indent + mg.getWrapperPortName(outs[idx],False) + f'.write({mg.getWrapperTmpName(outs[idx], False)});\n' - newline += indent + "}\n" - else: - raise Exception("vitis_unified supports only io_stream @ each dequeue") - - return newline - -def write_axi_wrapper_insert_call(meta, model, inps, outs): - io_type = model.config.get_config_value("IOType") - indent = " " - newline = indent + f'{model.config.get_project_name()}' + "(" - inputList = [] - outputList = [] - for inp in inps: - inputList.append(mg.getWrapperPortNameLocal(inp, True)) - for out in outs: - outputList.append(mg.getWrapperPortNameLocal(out, False)) - newline += ", ".join(inputList) + ", " + ", ".join(outputList) + ");\n" - return newline - -######################################################## -##### main function #################################### -######################################################## - -def write_axi_wrapper(meta: VitisUnifiedWriterMeta, model): - ''' - We we want to have multi io system - ''' - inp_axi_t, out_axi_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - indent = ' ' - - print("------------------------------- input write wrapper is -------------------------") - print([inp.name for inp in inps]) - print(model.inputs) - print("------------------------------- output write wrapper is -------------------------") - print([out.name for out in outs]) - print(model.outputs) - print("-----------------------------------------------------------------------------------") - - ###################### - # myproject_axi.h - ###################### - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_axi.h')) - fout = open(f'{model.config.get_output_dir()}/firmware/{mg.getAxiWrapperFileName(model)}.h', 'w') - - for line in f.readlines(): - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - elif '// hls-fpga-machine-learning insert include' in line: - newline = f'#include "{model.config.get_project_name()}.h"\n' - newline += '#include "ap_axi_sdata.h"\n' - elif 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - elif '// hls-fpga-machine-learning insert definitions' in line: - - ##### make input - newline = '' - inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" - newline += f'constexpr unsigned {mg.get_inputSizeArrName(model)} [{len(inps)}] = {inputSizeStr};\n' - - ##### make output - outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" - newline += f'constexpr unsigned {mg.get_outputSizeArrName(model)} [{len(outs)}] = {outputSizeStr};\n' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline += 'typedef hls::axis dma_data_packet;\n' - else: - newline += f'typedef {inp_axi_t} input_axi_t;\n' - newline += f'typedef {out_axi_t} output_axi_t;\n' - #### incase the io is interim input - if meta.vitis_unified_config.isFreeInterimInput(): - for inp in inps: - newline += mg.get_axi_wrapper_dec(inp) + "\n" - #### incase the io is interim output - if meta.vitis_unified_config.isFreeInterimOutput(): - for out in outs: - newline += mg.get_axi_wrapper_dec(out) + "\n" - elif '// hls-fpga-machine-learning insert multi-io' in line: - newline = '' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline += write_axi_wrapper_io(meta, inps, outs) - else: - raise Exception("vitis_unified supports only axi_stream") - - else: - newline = line - - #### TODO add stream - - fout.write(newline) - f.close() - fout.close() - - ###################### - # myproject_axi.cpp - ###################### - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_axi.cpp')) - fout = open(f'{model.config.get_output_dir()}/firmware/{mg.getAxiWrapperFileName(model)}.cpp', 'w') - - io_type = model.config.get_config_value("IOType") - - for line in f.readlines(): - if 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - elif '// hls-fpga-machine-learning insert include' in line: - newline = f'#include "{model.config.get_project_name()}_axi.h"\n' - elif '// hls-fpga-machine-learning insert multiIo' in line: - newline = '' - if meta.vitis_unified_config.get_interface() == 'axi_stream': - newline += write_axi_wrapper_io(meta, inps, outs) - else: - raise Exception("vitis_unified supports only axi_stream") - elif '// hls-fpga-machine-learning insert interface' in line: - newline = write_axi_wrapper_interface(meta, model, inps, outs) - elif '// hls-fpga-machine-learning insert local vars' in line: - newline = write_axi_local_vars(meta, model, inps, outs) - elif '// hls-fpga-machine-learning insert enqueue' in line: - newline = '' - if meta.vitis_unified_config.isFreeInterimInput(): - for idx, inp in enumerate(inps): - newline += write_free_axi_wrapper_each_enqueue(meta, model, inps, idx) + '\n' - else: - for idx, inp in enumerate(inps): - newline += write_axi_wrapper_each_enqueue(meta, model, inps, idx) + '\n' - elif '// hls-fpga-machine-learning insert call' in line: - newline = '////// call the main variable\n' - newline += write_axi_wrapper_insert_call(meta, model, inps, outs) - elif '// hls-fpga-machine-learning insert dequeue' in line: - newline = '' - if meta.vitis_unified_config.isFreeInterimOutput(): - for idx, out in enumerate(outs): - newline += write_free_axi_wrapper_dequeue(meta, model, inps, outs, idx, out_axi_t) - else: - for idx, out in enumerate(outs): - newline += write_axi_wrapper_dequeue(meta, model, inps, outs, idx, out_axi_t) - else: - newline = line - fout.write(newline) - f.close() - fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 8b46384d4c..0bd96aa777 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -1,107 +1,112 @@ import os from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg +from .meta_gen import VitisUnified_MetaGen as mg -def write_bridge(meta: VitisUnifiedWriterMeta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) - fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') +class VitisUnified_BridgeGen: - 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'] + @classmethod + def write_bridge(meta: VitisUnifiedWriterMeta, model): - indent = ' ' + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) + fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') - for line in fin.readlines(): - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + 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'] - elif 'myproject' in line: - newline = line.replace('myproject', format(model.config.get_project_name())) + indent = ' ' - elif 'PROJECT_FILE_NAME' in line: - newline = line.replace('PROJECT_FILE_NAME', format(mg.getGmemWrapperFileName(model))) + for line in fin.readlines(): + newline = "" + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - 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 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) - elif '// hls-fpga-machine-learning insert header' in line: + elif 'PROJECT_FILE_NAME' in line: + newline = line.replace('PROJECT_FILE_NAME', format(mg.get_wrapper_file_name(model))) - dtype = line.split('#', 1)[1].strip() + 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' - input_ios = [] - output_ios = [] + elif '// hls-fpga-machine-learning insert header' in line: + dtype = line.split('#', 1)[1].strip() - for idx, inp in enumerate(model_inputs): - input_ios.append(f"{dtype} {mg.getGmemIOPortName(inp, True, idx)}[{inp.size_cpp()}]") - for idx, out in enumerate(model_outputs): - output_ios.append(f"{dtype} {mg.getGmemIOPortName(out, False, idx)}[{out.size_cpp()}]") + input_ios = [] + output_ios = [] - inputs_str = ', '.join(input_ios) - outputs_str = ', '.join(output_ios) - - newline = '' - newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + '\n' - - elif '// hls-fpga-machine-learning insert wrapper' in line: - dtype = line.split('#', 1)[1].strip() - if dtype == 'float': - newline = '' - input_vars = [] - input_sizes = [] - output_vars = [] - otuput_sizes = [] for idx, inp in enumerate(model_inputs): - input_vars.append(mg.getGmemIOPortName(inp, True, idx)) - input_sizes.append(inp.size_cpp()) + input_ios.append(f"{dtype} {mg.get_io_port_name(inp, True, idx)}[{inp.size_cpp()}]") for idx, out in enumerate(model_outputs): - output_vars.append(mg.getGmemIOPortName(out, False, idx)) - otuput_sizes.append(out.size_cpp()) + output_ios.append(f"{dtype} {mg.get_io_port_name(out, False, idx)}[{out.size_cpp()}]") - inputs_str = ', '.join(input_vars) - input_size_str = ', '.join(input_sizes) - outputs_str = ', '.join(output_vars) - output_size_str = ', '.join(otuput_sizes) + inputs_str = ', '.join(input_ios) + outputs_str = ', '.join(output_ios) newline = '' - newline += indent + mg.getGemTopFuncName(model) + "(\n" newline += indent + inputs_str + ',\n' - newline += indent + outputs_str + ',\n' - newline += indent + input_size_str + ',\n' - newline += indent + output_size_str + '\n' - newline += indent + ");\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): - vars = layer.get_variables() - for var in vars: - 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) - - fin.close() - fout.close() \ No newline at end of file + newline += indent + outputs_str + '\n' + + elif '// hls-fpga-machine-learning insert wrapper' in line: + dtype = line.split('#', 1)[1].strip() + if dtype == 'float': + newline = '' + input_vars = [] + input_sizes = [] + output_vars = [] + otuput_sizes = [] + + for idx, inp in enumerate(model_inputs): + input_vars.append(mg.get_io_port_name(inp, True, idx)) + input_sizes.append(inp.size_cpp()) + for idx, out in enumerate(model_outputs): + output_vars.append(mg.get_io_port_name(out, False, idx)) + otuput_sizes.append(out.size_cpp()) + + inputs_str = ', '.join(input_vars) + input_size_str = ', '.join(input_sizes) + outputs_str = ', '.join(output_vars) + output_size_str = ', '.join(otuput_sizes) + + newline = '' + newline += indent + mg.get_top_model_name(model) + "(\n" + newline += indent + inputs_str + ',\n' + newline += indent + outputs_str + ',\n' + newline += indent + input_size_str + ',\n' + newline += indent + output_size_str + '\n' + newline += indent + ");\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): + vars = layer.get_variables() + for var in vars: + 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) + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 89ef867a6d..71ee10e2d1 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -1,115 +1,121 @@ import os from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg - -def write_wrapper_test(meta, model): - - - #### warning we have to fix to float because the system locked by template - inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') - - 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 partial backend\n") - - for line in f.readlines(): - indent = ' ' * (len(line) - len(line.lstrip(' '))) - - #Insert numbers - if 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - 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 - offset = 0 - for inputIdx, inp in enumerate(model_inputs): - ##### input should be float - newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template - inputPortName=mg.getGmemIOPortName(inp, True, inputIdx), - startIdx=str(offset) - ) - offset += inp.size() - for outputIdx, out in enumerate(model_outputs): - newline += f" float {mg.getGmemIOPortName(out, False, outputIdx)}[{out.size()}];\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] - - for inpIdx, inp in enumerate(model_inputs): - input_ios.append(mg.getGmemIOPortName(inp, True, inpIdx)) - input_ios.append(str(inp.size())) - - for outIdx, out in enumerate(model_outputs): - output_ios.append(mg.getGmemIOPortName(out, False, outIdx)) - output_ios.append(str(out.size())) - - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) - top_level = indent + f'{mg.getGemTopFuncName(model)}({all_vars});\n' - newline += top_level - - elif '// hls-fpga-machine-learning insert predictions' in line: - newline = line - for outIdx, out in enumerate(model_outputs): - #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' - newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 - for inpIdx, inp in enumerate(model_inputs): - newline += indent + f'float {mg.getGmemIOPortName(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' - - for outIdx, out in enumerate(model_outputs): - newline += indent + f"float {mg.getGmemIOPortName(out, False, outIdx)}[{str(out.size())}] = {{}};\n" - - elif ( - '// hls-fpga-machine-learning insert output' in line - or '// hls-fpga-machine-learning insert quantized' in line - or '// hls-fpga-machine-learning insert tb-output' in line - ): - - newline = line - tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' - keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - newline += "/// warning keep is forced to be true\n" - - for outIdx, out in enumerate(model_outputs): - newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' - .format( actualType = "float", - arrName = mg.get_outputSizeArrName(model), - arrIdx = str(outIdx), - portName = mg.getGmemIOPortName(out, False, outIdx), - des = dest, - keepOutput = keep_output)) - - 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) - f.close() - fout.close() +from .meta_gen import VitisUnified_MetaGen as mg + + +class VitisUnified_TestGen: + + @classmethod + def write_wrapper_test(self, meta, model): + + + #### warning we have to fix to float because the system locked by template + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + + 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 f.readlines(): + indent = ' ' * (len(line) - len(line.lstrip(' '))) + + #Insert numbers + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + 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 + offset = 0 + for inputIdx, inp in enumerate(model_inputs): + ##### input should be float + newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + inputPortName=mg.c(inp, True, inputIdx), + startIdx=str(offset) + ) + offset += inp.size() + for outputIdx, out in enumerate(model_outputs): + newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\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] + + for inpIdx, inp in enumerate(model_inputs): + input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) + input_ios.append(str(inp.size())) + + for outIdx, out in enumerate(model_outputs): + output_ios.append(mg.get_io_port_name(out, False, outIdx)) + output_ios.append(str(out.size())) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) + top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' + newline += top_level + + elif '// hls-fpga-machine-learning insert predictions' in line: + newline = line + for outIdx, out in enumerate(model_outputs): + #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + #### TODO fix this size retrieve + newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 + for inpIdx, inp in enumerate(model_inputs): + newline += indent + f'float {mg.get_io_port_name(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' + + for outIdx, out in enumerate(model_outputs): + newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\n" + + elif ( + '// hls-fpga-machine-learning insert output' in line + or '// hls-fpga-machine-learning insert quantized' in line + or '// hls-fpga-machine-learning insert tb-output' in line + ): + + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' + keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" + newline += "/// warning keep is forced to be true\n" + + for outIdx, out in enumerate(model_outputs): + #### TODO fix this size retrieve + newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + .format( actualType = "float", + arrName = mg.get_outputSizeArrName(model), + arrIdx = str(outIdx), + portName = mg.get_io_port_name(out, False, outIdx), + des = dest, + keepOutput = keep_output)) + + 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) + f.close() + fout.close() diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py new file mode 100644 index 0000000000..fe669fe1a5 --- /dev/null +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -0,0 +1,126 @@ +import os +from pathlib import Path +import stat +from shutil import copyfile + +from .meta import VitisUnifiedWriterMeta +from .meta_gen import VitisUnified_MetaGen as mg + +################################################################################ +###### main function ########################################################### +################################################################################ + +class VitisUnified_WrapperGen: + + @classmethod + def gen_io_str(self, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): + + inputPtrList = [] + outputPtrList = [] + inputSizeList = [] + outputSizeList = [] + + for inp_idx, inp in enumerate(inps): + inputPtrList.append(f"{indent} {inp_gmem_t}* {mg.get_io_port_name(inp, True, inp_idx)}") + inputSizeList.append(f"{indent} int {mg.get_io_port_size_name(inp, True, inp_idx)}") + + for out_idx, out in enumerate(outs): + outputPtrList.append(f"{indent} {out_gmem_t}* {mg.get_io_port_name(out, False, out_idx)}") + outputSizeList.append(f"{indent} int {mg.get_io_port_size_name(out, False, out_idx)}") + + + line = ", ".join(inputPtrList) + ",\n" + line += ", ".join(outputPtrList) + ",\n" + line += ", ".join(inputSizeList) + ",\n" + line += ", ".join(outputSizeList) + + return line + + @classmethod + def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): + + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + indent = ' ' + + ###################################### + ###### start write myproject_dm.cpp ## + ###################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') + + for line in fin.readlines(): + + if "MY_PROJECT_AXI_INC" in line: + line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + if "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) + elif "DMX_BUF_IN_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) + elif "DMX_BUF_OUT_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) + elif "// vitis-unified-wrapper-io" in line: + line = self.gen_io_str(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" + elif "// vitis-unified-wrapper-interface" in line: + for inp_idx, inp in enumerate(inps): + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" + line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(inp, True, inp_idx)} bundle = control\n" + for out_idx, out in enumerate(outs): + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx}\n" + line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(out, False, out_idx)} bundle = control\n" + elif "// vitis-unified-wrapper-stream-dec" in line: + + for inp_idx, inp in enumerate(inps): + line += f"{indent} static hls::stream<{inp.type.name}> {mg.get_local_stream_name(inp, True, inp_idx)};\n" + for out_idx, out in enumerate(outs): + line += f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" + + elif "// vitis-unified-wrapper-stream-config" in line: + for inp_idx, inp in enumerate(inps): + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth=DMX_BUF_IN_SZ\n" + for out_idx, out in enumerate(outs): + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth=DMX_BUF_OUT_SZ\n" + + elif "// vitis-unified-wrapper-load" in line: + for inp_idx, inp in enumerate(inps): + line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, {mg.get_io_port_size_name(inp, True, inp_idx)});\n" + elif "// vitis-unified-wrapper-compute" in line: + poolList = [] + for inp_idx, inp in enumerate(inps): + poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") + for out_idx, out in enumerate(outs): + poolList.append(f"{mg.get_local_stream_name(out, False, out_idx)}") + joinedIo = ", \n".join(poolList) + line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" + + elif "// vitis-unified-wrapper-store" in line: + for out_idx, out in enumerate(outs): + line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, {mg.get_io_port_size_name(out, False, out_idx)});\n" + + fout.write(line) + + + fin.close() + fout.close() + + ###################################### + ###### start write myproject_dm.h ## + ###################################### + + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.h'), 'r') + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.h', 'w') + + for line in fin.readlines(): + + if "FILENAME" in line: + line = line.replace("FILENAME", mg.get_wrapper_file_name(model).upper()) + elif "MY_PROJECT_TOP_FUNC" in line: + line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) + elif "// vitis-unified-wrapper-io" in line: + line += self.gen_io_str(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" + fout.write(line) + + fin.close() + fout.close() \ No newline at end of file From 548a8f088d8f92e05d7b44eac2b004f96117d9ae Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 12:43:52 +0200 Subject: [PATCH 27/70] divert tot use mg and add mgs group generator --- .../vitis_unified/vitis_unified_backend.py | 21 +- .../vitis_unified/vitis_unified_config.py | 8 - .../vitis_unified_partial/__init__.py | 0 .../vitis_unified_partial_backend.py | 107 ++++++++ .../vitis_unified_partial_config.py | 42 +++ .../ips/magic_stream_grp_gen/streamGrp.v | 2 +- .../driver_gen.py | 3 +- .../vitis_unified_partial_writer/mgs_gen.py | 60 ++++- .../test_bridge_gen.py | 3 +- .../test_cosim_gen.py | 3 +- .../vitis_unified_partial_writer/wrap_gen.py | 25 +- .../writer/vitis_unified_writer/build_gen.py | 245 +++++++++--------- .../writer/vitis_unified_writer/driver_gen.py | 3 +- .../vitis_unified_writer/test_bridge_gen.py | 4 +- .../vitis_unified_writer/test_cosim_gen.py | 3 +- .../writer/vitis_unified_writer/wrap_gen.py | 8 +- 16 files changed, 362 insertions(+), 175 deletions(-) create mode 100644 hls4ml/backends/vitis_unified_partial/__init__.py create mode 100644 hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py create mode 100644 hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 5ee6c70850..8f1d5f6ace 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -8,7 +8,7 @@ from hls4ml.model.flow import register_flow from hls4ml.report import parse_vivado_report -from hls4ml.writer.vitis_unified_writer import meta_gen as mg +from hls4ml.writer.vitis_unified_writer.meta_gen import VitisUnified_MetaGen as mg class VitisUnifiedBackend(VitisBackend): @@ -95,21 +95,21 @@ def build( csynth_cmd = ( "v++ -c --mode hls --config {configPath} --work_dir unifiedPrj" ).format(configPath=hls_config_file) - csynth_cwd = mg.getVitisHlsDir(model) + csynth_cwd = mg.get_vitis_hls_dir(model) ##### util template (used in csim/cosim/package) util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" ##### package command package_cmd = util_command.format(op="package", configPath=hls_config_file) - package_cwd = mg.getVitisHlsDir(model) + package_cwd = mg.get_vitis_hls_dir(model) cosim_cmd = util_command.format(op="cosim" , configPath=hls_config_file) - cosim_cwd = mg.getVitisHlsDir(model) + cosim_cwd = mg.get_vitis_hls_dir(model) csim_cmd = util_command.format(op="csim" , configPath=hls_config_file) - csim_cwd = mg.getVitisHlsDir(model) + csim_cwd = mg.get_vitis_hls_dir(model) kerlink_cmd = "./buildAcc.sh" - kerlink_cwd = mg.getVitisLinkerDir(model) + kerlink_cwd = mg.get_vitis_linker_dir(model) if synth: self.run_term_command(model, "csynth", csynth_cmd, log_to_stdout, csynth_cwd) @@ -144,9 +144,9 @@ def create_initial_config( xpfmPath ='/tools/Xilinx/Vitis/2023.2/base_platforms/' 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', input_interim_type ='io_stream', #### it should be io_stream or io_free_stream/ io_stream - output_interim_type ='io_stream' + output_interim_type ='io_stream', + **_ ): - board = board if board is not None else 'pynq-z2' if input_interim_type not in ['io_free_stream', 'io_stream']: raise Exception(f'input_interim_type should be io_free_stream or io_stream, but got {input_interim_type}') @@ -169,11 +169,6 @@ def create_initial_config( config['UnifiedConfig']['bufOutSize'] = gmemBuf_out_size config['UnifiedConfig']['XPFMPath'] = xpfmPath - config['MultiGraphConfig'] = {} - config['MultiGraphConfig']['IOInterimType'] = {} - config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type - config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type - return config def get_default_flow(self): diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index e57a40cf1d..d47a5be59e 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -10,8 +10,6 @@ def __init__(self, config, model_inputs, model_outputs): self.config = config.config # self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') # self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) - self.freeInterimInput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Input") == "io_free_stream" - self.freeInterimOutput = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get("Output") == "io_free_stream" # if self.board in self.supported_boards.keys(): # board_info = self.supported_boards[self.board] # self.part = board_info['part'] @@ -160,12 +158,6 @@ def get_input_type(self): def get_output_type(self): return self.output_type - def isFreeInterimInput(self): - return self.freeInterimInput - - def isFreeInterimOutput(self): - return self.freeInterimOutput - def get_tcl_file_path(self): board_info = self.get_board_info(self.board) tcl_scripts = board_info.get('tcl_scripts', None) diff --git a/hls4ml/backends/vitis_unified_partial/__init__.py b/hls4ml/backends/vitis_unified_partial/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py new file mode 100644 index 0000000000..31186cc238 --- /dev/null +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -0,0 +1,107 @@ +import os +import sys +import subprocess +from shutil import copy2 + + +from hls4ml.backends import VitisUnifiedBackend, VivadoBackend +from hls4ml.model.flow import register_flow +from hls4ml.report import parse_vivado_report + +from hls4ml.writer.vitis_unified_partial_writer.meta_gen import VitisUnifiedPartial_MetaGen as mg + + +class VitisUnifiedPartialBackend(VitisUnifiedBackend): + + def __init__(self): + super(VivadoBackend, self).__init__(name='VitisUnifiedPartial') + self._register_layer_attributes() + self._register_flows() + + + def build( + self, + model, + reset=False, + csim=False, + synth=False, + cosim=False, + validation=False, + export=False, + vsynth=False, + fifo_opt=False, + bitfile=False, + log_to_stdout=True + ): + + ##### do magic streamer generation + + + pass + + # super().build( + # model, + # reset, + # csim, + # synth, + # cosim, + # validation, + # export, + # vsynth, + # fifo_opt, + # bitfile, + # log_to_stdout + # ) + + def create_initial_config( + self, + board='pynq-z2', + part=None, + clock_period=5, + clock_uncertainty='12.5%', + io_type='io_parallel', + interface='axi_stream', + driver='python', + input_type='float', + output_type='float', + gmemBuf_in_size=12, + gmemBuf_out_size=12, + xpfmPath='/tools/Xilinx/Vitis/2023.2/base_platforms/' + 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', + input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream + output_interim_type='io_stream', + **_ + ): + + config = super().create_initial_config( + board=board, + part=part, + clock_period=clock_period, + clock_uncertainty=clock_uncertainty, + io_type=io_type, + interface=interface, + driver=driver, + input_type=input_type, + output_type=output_type, + gmemBuf_in_size=1, + gmemBuf_out_size=1, + xpfmPath=xpfmPath + ) + + config['MultiGraphConfig'] = {} + config['MultiGraphConfig']['amtGraph'] = -1 # it should be set by the multigraph system + config['MultiGraphConfig']['graphIdx'] = -1 # -1 means unset yet or it is multigraph stitcher + config['MultiGraphConfig']['MgsMeta'] = [] #### it should be only used for stitcher + + + config['MultiGraphConfig']['IOInterimType'] = {} + config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type + config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type + + + + def _register_flows(self): + vitis_ip = 'vitis:ip' + writer_passes = ['make_stamp', 'vitisunifiedpartial:write_hls'] + self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name) + self._default_flow = vitis_ip \ No newline at end of file diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py new file mode 100644 index 0000000000..ae38e914a9 --- /dev/null +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py @@ -0,0 +1,42 @@ +import json +import os + +import numpy as np + +from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig + + +class VitisUnifiedPartialConfig(VitisUnifiedConfig): + + + def __init__(self, config, model_inputs, model_outputs): + + super().__init__(config, model_inputs, model_outputs) + + self.free_interim_input = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get( + "Input") == "io_free_stream" + self.free_interim_output = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get( + "Output") == "io_free_stream" + + self.amt_graph = self.config.get('MultiGraphConfig', {}).get('amtGraph', -1) + self.graph_idx = self.config.get('MultiGraphConfig', {}).get('graphIdx', -1) + + self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('mgsMeta', None) + + + def is_free_interim_input(self): + return self.free_interim_input + + def is_free_interim_output(self): + return self.free_interim_output + + def get_amt_graph(self): + return self.amt_graph + + def get_graph_idx(self): + return self.graph_idx + + def get_mgs_meta_list(self): + ### it is supposed to return [(dataWidth, IndexWidth, ...), ... ] + return self.mgs_meta + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v index 08b7bc8db3..8ec8af7eb8 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v @@ -11,6 +11,6 @@ module streamGrp #( ); - // hls4ml-streamGrp-gen-io + // hls4ml-streamGrp-gen-create-module endmodule \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py b/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py index cb69cacb6c..e520e5e076 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py @@ -5,13 +5,12 @@ from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta from hls4ml.writer.vitis_unified_writer.driver_gen import VitisUnified_DriverGen -from .meta_gen import VitisUnifiedPartial_MetaGen as mg class VitisUnifiedPartial_DriverGen(VitisUnified_DriverGen): @classmethod - def write_driver(self, meta: VitisUnifiedWriterMeta, model): + def write_driver(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/driver/pynq/pynq_driver.py'), 'r') fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index ff0ae86413..fb6219991a 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -12,7 +12,63 @@ class VitisUnifiedPartial_MgsGen(): def write_mgs(self, meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_mgs.cpp'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_mgs.cpp', 'w') + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v'), 'r') + fout = open(f'{model.config.get_output_dir()}/ips/magic_stream_grp_gen/myproject_mgs.cpp', 'w') + metaList = meta.vitis_unified_config.get_mgs_meta_list() + #### v------ mgs0 v--------- mgs1 + #### [(data width, indexWidth, ....), (data width, indexWidth, ....)] + for line in fin.readlines(): + newline = line + + if "// hls4ml-streamGrp-gen-parameter" in line: + parameterList = [] + for idx, (data_width, index_width, *_) in enumerate(metaList): + parameterList.append(f"parameter DATA_WIDTH_{idx} = {data_width}") + parameterList.append(f"parameter INDEX_WIDTH_{idx} = {index_width}") + + parameterStr = ",\n".join(parameterList) + newline += parameterStr + "\n" + + elif "// hls4ml-streamGrp-gen-io" in line: + ioList = [] + for idx in range(len(metaList)): + ioList.append(f"//io for MGS{str(idx)}") + ioList.append(f"input wire [DATA_WIDTH-1:0] S{str(idx)}_AXI_TDATA" ) + ioList.append(f"input wire S{str(idx)}_AXI_TVALID") + ioList.append(f"output wire S{str(idx)}_AXI_TREADY") + ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) + ioList.append(f"output wire [DATA_WIDTH-1:0] M{str(idx)}_AXI_TDATA" ) + ioList.append(f"output wire M{str(idx)}_AXI_TVALID") + ioList.append(f"input wire M{str(idx)}_AXI_TREADY") + ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) + + newline += ",\n".join(ioList) + "\n" + + + elif "// hls4ml-streamGrp-gen-create-module" in line: + + + for idx in range(len(metaList)): + newline += f"//create module for MGS{str(idx)}" + newline += f"MagicStreammerCore #(\n" + newline += f" .clk(clk),\n" + newline += f" .reset(nreset)\n" + newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" + newline += f" .INDEX_WIDTH(INDEX_WIDTH_{idx})\n" + newline += f")\n" + newline += f"MGS{str(idx)} (\n" + newline += f" .S_AXI_TDATA(S{str(idx)}_AXI_TDATA),\n" + newline += f" .S_AXI_TVALID(S{str(idx)}_AXI_TVALID),\n" + newline += f" .S_AXI_TREADY(S{str(idx)}_AXI_TREADY),\n" + newline += f" .S_AXI_TLAST(S{str(idx)}_AXI_TLAST),\n" + newline += f" .M_AXI_TDATA(M{str(idx)}_AXI_TDATA),\n" + newline += f" .M_AXI_TVALID(M{str(idx)}_AXI_TVALID),\n" + newline += f" .M_AXI_TREADY(M{str(idx)}_AXI_TREADY),\n" + newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST)\n" + newline += f");\n" + + + + fout.write(newline) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py index 26d38e3acf..44432f1702 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py @@ -2,12 +2,11 @@ from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta from hls4ml.writer.vitis_unified_writer.test_bridge_gen import VitisUnified_BridgeGen -from .meta_gen import VitisUnifiedPartial_MetaGen as mg class VitisUnifiedPartial_BridgeGen(VitisUnified_BridgeGen): - def write_bridge(meta: VitisUnifiedWriterMeta, model): + def write_bridge(meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) #### we will use the same bridge template file as VitisUnified_BridgeGen diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py index eef408f64d..d61ad187d9 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py @@ -2,13 +2,12 @@ from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta from hls4ml.writer.vitis_unified_writer.test_cosim_gen import VitisUnified_TestGen -from .meta_gen import VitisUnifiedPartial_MetaGen as mg class VitisUnifiedPartial_TestGen(VitisUnified_TestGen): @classmethod - def write_wrapper(self, meta, model): + def write_wrapper(self, meta, model, mg): inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py index e474f0c136..a8695f4778 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -10,29 +10,29 @@ class VitisUnifiedPartial_WrapperGen(VitisUnified_WrapperGen): @classmethod - def gen_io_str(self, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): + def gen_io_str(self, mg,indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): inputStreamList = [] outputStreamList = [] for inp_idx, inp in enumerate(inps): inp_type = mg.get_dma_type_name() - if (meta.vitis_unified_config.isFreeInterimInput()) and \ + if (meta.vitis_unified_config.is_free_interim_input()) and \ (meta.vitis_unified_config.getGraphIdx() != 0 ): inp_type = mg.get_axi_wrapper_type(inp) inputStreamList.append(f"{indent} hls::stream<{inp_type}>& {mg.get_io_port_name(inp, True, inp_idx)}") for out_idx, out in enumerate(outs): out_type = mg.get_dma_type_name() - if (meta.vitis_unified_config.isFreeInterimOutput()) and \ + if (meta.vitis_unified_config.is_free_interim_output()) and \ (meta.vitis_unified_config.getGraphIdx() != (meta.vitis_unified_config.getGraphAmtGraph()-1) ): out_type = mg.get_axi_wrapper_type(out) outputStreamList.append(f"{indent} hls::stream<{out_type}>& {mg.get_io_port_name(out, False, out_idx)}") - return ", \n".join(inputStreamList) + ",\n" + ", \n".join() + return ", \n".join(inputStreamList) + ",\n" + ", \n".join(outputStreamList) @classmethod - def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): + def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): inp_axis_t, out_axis_t, inps, outs = meta.vitis_unified_config.get_corrected_types() indent = ' ' @@ -53,7 +53,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): elif "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) elif "// hls-fpga-machine-learning insert multi-io" in line: - line = self.gen_io_str(indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" + line = self.gen_io_str(mg, indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" elif "// hls-fpga-machine-learning insert interface" in line: for inp_idx, inp in enumerate(inps): line += f"{indent} #pragma HLS INTERFACE axis port={mg.get_io_port_name(inp, True, inp_idx)}\n" @@ -74,7 +74,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): elif "// hls-fpga-machine-learning insert enqueue" in line: for inp_idx, inp in enumerate(inps): - if meta.vitis_unified_config.isFreeInterimInput(): + if meta.vitis_unified_config.is_free_interim_input(): line += mg.get_enqueue_func_stream2rstream(inp, inp_idx) else: line += mg.get_enqueue_func_atom2stream(inp, inp_idx) @@ -90,7 +90,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): elif "// hls-fpga-machine-learning insert dequeue" in line: for out_idx, out in enumerate(outs): - if meta.vitis_unified_config.isFreeInterimOutput(): + if meta.vitis_unified_config.is_free_interim_output(): line += mg.get_dequeue_func_rstream2stream(out, out_idx, mg.get_all_last_logic(len(inps))) + "\n" else: @@ -123,11 +123,16 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): newline += f'constexpr unsigned {mg.get_output_size_arr_name(model)} [{len(outs)}] = {outputSizeStr};\n' newline += f'typedef hls::axis<{inp_axis_t}, 0, 0, 0, AXIS_ENABLE_LAST> dma_data_packet;\n' #### incase the io is interim input - if meta.vitis_unified_config.isFreeInterimInput(): + if meta.vitis_unified_config.is_free_interim_input(): for inp in inps: newline += mg.get_axi_wrapper_dec(inp) + "\n" #### incase the io is interim output - if meta.vitis_unified_config.isFreeInterimOutput(): + if meta.vitis_unified_config.is_free_interim_output(): for out in outs: newline += mg.get_axi_wrapper_dec(out) + "\n" + fout.write(line) + + + fin.close() + fout.close() diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 409fe31e8e..93d1359c21 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -4,127 +4,124 @@ from .meta import VitisUnifiedWriterMeta -from . import meta_gen as mg - -# def write_driver(meta, model): -# print("[partial reconfig] we are not supporting write_driver this yet") - - -def write_bridge_build_script(meta: VitisUnifiedWriterMeta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) - fout = open(f"{model.config.get_output_dir()}/build_lib.sh", 'w') - - for line in fin.readlines(): - if 'myproject' in line: - line = line.replace('myproject', format(model.config.get_project_name())) - if 'mystamp' in line: - line = line.replace('mystamp', model.config.get_config_value('Stamp')) - - fout.write(line) - - fin.close() - fout.close() - - #### change permission - 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_cfg(meta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') - fout = open(f"{model.config.get_output_dir()}/hls_kernel_config.cfg", 'w') - - 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}", mg.getGemTopFuncName(model)) - if "{FILE_NAME_DM}" in line: - line = line.replace("{FILE_NAME_DM}", mg.getGmemWrapperFileName(model)) - if "{FILE_NAME_AXIS}" in line: - line = line.replace("{FILE_NAME_AXIS}", mg.getAxiWrapperFileName(model)) - if "{FILE_NAME_BASE}" in line: - line = line.replace("{FILE_NAME_BASE}", mg.getMainFileName(model)) - - - fout.write(line) - - fin.close() - fout.close() - -def build_unified_project_ske(meta, model, workspaceDir = None): - if workspaceDir is None: - workspaceDir = mg.getVitisUnifiedWorkingDirectoryDir(model) - hlsDir = mg.getVitisHlsDir(model) - execDir = mg.getVitisHlsExecDir(model) - vitisComp = os.path.join(str(hlsDir), "vitis-comp.json") - - ###### create my own project for this graph - os.makedirs(workspaceDir, exist_ok=True) - os.makedirs(hlsDir , exist_ok=True) - os.makedirs(execDir , exist_ok=True) - ###### create project vitis-comp.json to - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, "../../templates/vitis_unified/workspace/projectName/vitis-comp.json"), 'r') - fout = open(vitisComp, 'w') - - for line in fin.readlines(): - if "{HLS_NAME}" in line: - line = line.replace("{HLS_NAME}", model.config.get_project_name()) - if "{CONFIG_FILE}" in line: - line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_kernel_config.cfg") - fout.write(line) - - fin.close() - fout.close() - -def write_launch_vitis_linker_dir(meta, model): - os.makedirs(mg.getVitisLinkerDir(model), exist_ok=True) - -def write_launch_vitis_linker_launcher(meta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh'), 'r') - fout = open(f"{mg.getVitisLinkerDir(model)}/buildAcc.sh", 'w') - - for line in fin.readlines(): - if "{PLATFORM_XPFM}" in line: - line = line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.get_XPFMPath()) - if "{KERNEL_XO}" in line: - line = line.replace("{KERNEL_XO}", mg.getXOfilePath(model)) - if "{PROJECT_NAME}" in line: - line = line.replace("{PROJECT_NAME}", model.config.get_project_name()) - - fout.write(line) - - fin.close() - fout.close() - - link_lib_dst = Path(f"{mg.getVitisLinkerDir(model)}/buildAcc.sh").resolve() - link_lib_dst.chmod(link_lib_dst.stat().st_mode | stat.S_IEXEC) - - - -def write_launch_vitis_linker_cfg(meta, model): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg'), 'r') - fout = open(f"{mg.getVitisLinkerDir(model)}/buildConfig.cfg", 'w') - - for line in fin.readlines(): - if "{CLK}" in line: - line = line.replace("{CLK}", str(100_000_000))#model.config.get_config_value('ClockPeriod')) - if "{KERNEL_NAME}" in line: - line = line.replace("{KERNEL_NAME}", mg.getGemTopFuncName(model)) - if "{GUI_STATUS}" in line: - line = line.replace("{GUI_STATUS}", "true") - line="" - fout.write(line) - - fin.close() - fout.close() \ No newline at end of file + +class VitisUnified_BuildGen: + + def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) + fout = open(f"{model.config.get_output_dir()}/build_lib.sh", 'w') + + for line in fin.readlines(): + if 'myproject' in line: + line = line.replace('myproject', format(model.config.get_project_name())) + if 'mystamp' in line: + line = line.replace('mystamp', model.config.get_config_value('Stamp')) + + fout.write(line) + + fin.close() + fout.close() + + #### change permission + 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_cfg(self, meta, model, mg): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') + fout = open(f"{model.config.get_output_dir()}/hls_kernel_config.cfg", 'w') + + 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}", mg.get_top_wrap_func_name(model)) + if "{FILE_NAME_DM}" in line: + line = line.replace("{FILE_NAME_DM}", mg.get_wrapper_file_name(model)) + if "{FILE_NAME_AXIS}" in line: + line = line.replace("{FILE_NAME_AXIS}", mg.get_wrapper_file_name(model)) + if "{FILE_NAME_BASE}" in line: + line = line.replace("{FILE_NAME_BASE}", mg.get_main_file_name(model)) + + + fout.write(line) + + fin.close() + fout.close() + + def build_unified_project_ske(self, meta, model, mg, workspaceDir = None): + if workspaceDir is None: + workspaceDir = mg.get_vitis_unified_working_directory_dir(model) + hlsDir = mg.get_vitis_hls_dir(model) + execDir = mg.get_vitis_hls_dir(model) + vitisComp = os.path.join(str(hlsDir), "vitis-comp.json") + + ###### create my own project for this graph + os.makedirs(workspaceDir, exist_ok=True) + os.makedirs(hlsDir , exist_ok=True) + os.makedirs(execDir , exist_ok=True) + ###### create project vitis-comp.json to + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, "../../templates/vitis_unified/workspace/projectName/vitis-comp.json"), 'r') + fout = open(vitisComp, 'w') + + for line in fin.readlines(): + if "{HLS_NAME}" in line: + line = line.replace("{HLS_NAME}", model.config.get_project_name()) + if "{CONFIG_FILE}" in line: + line = line.replace("{CONFIG_FILE}", f"{model.config.get_output_dir()}/hls_kernel_config.cfg") + fout.write(line) + + fin.close() + fout.close() + + def write_launch_vitis_linker_dir(self, meta, model, mg): + os.makedirs(mg.get_vitis_linker_dir(model), exist_ok=True) + + def write_launch_vitis_linker_launcher(self, meta, model, mg): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh'), 'r') + fout = open(f"{mg.get_vitis_linker_dir(model)}/buildAcc.sh", 'w') + + for line in fin.readlines(): + if "{PLATFORM_XPFM}" in line: + line = line.replace("{PLATFORM_XPFM}", meta.vitis_unified_config.get_XPFMPath()) + if "{KERNEL_XO}" in line: + line = line.replace("{KERNEL_XO}", mg.get_xo_file_path(model)) + if "{PROJECT_NAME}" in line: + line = line.replace("{PROJECT_NAME}", model.config.get_project_name()) + + fout.write(line) + + fin.close() + fout.close() + + link_lib_dst = Path(f"{mg.get_vitis_linker_dir(model)}/buildAcc.sh").resolve() + link_lib_dst.chmod(link_lib_dst.stat().st_mode | stat.S_IEXEC) + + + + def write_launch_vitis_linker_cfg(self, meta, model, mg): + filedir = os.path.dirname(os.path.abspath(__file__)) + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg'), 'r') + fout = open(f"{mg.get_vitis_linker_dir(model)}/buildConfig.cfg", 'w') + + for line in fin.readlines(): + if "{CLK}" in line: + line = line.replace("{CLK}", str(100_000_000))#model.config.get_config_value('ClockPeriod')) + if "{KERNEL_NAME}" in line: + line = line.replace("{KERNEL_NAME}", mg.get_top_wrap_func_name(model)) + if "{GUI_STATUS}" in line: + line = line.replace("{GUI_STATUS}", "true") + line="" + fout.write(line) + + fin.close() + fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py index 60c0471715..2f4ad4db06 100644 --- a/hls4ml/writer/vitis_unified_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -4,12 +4,11 @@ from .meta import VitisUnifiedWriterMeta -from .meta_gen import VitisUnified_MetaGen as mg class VitisUnified_DriverGen: @classmethod - def write_driver(self, meta, model): + def write_driver(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py'), 'r') fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 0bd96aa777..8970bd4bda 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -1,12 +1,10 @@ import os from .meta import VitisUnifiedWriterMeta -from .meta_gen import VitisUnified_MetaGen as mg - class VitisUnified_BridgeGen: @classmethod - def write_bridge(meta: VitisUnifiedWriterMeta, model): + def write_bridge(meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 71ee10e2d1..dc7e1d6418 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -1,12 +1,11 @@ import os from .meta import VitisUnifiedWriterMeta -from .meta_gen import VitisUnified_MetaGen as mg class VitisUnified_TestGen: @classmethod - def write_wrapper_test(self, meta, model): + def write_wrapper_test(self, meta, model, mg): #### warning we have to fix to float because the system locked by template diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index fe669fe1a5..6889f0f83b 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -13,7 +13,7 @@ class VitisUnified_WrapperGen: @classmethod - def gen_io_str(self, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): + def gen_io_str(self, mg, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): inputPtrList = [] outputPtrList = [] @@ -37,7 +37,7 @@ def gen_io_str(self, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): return line @classmethod - def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): + def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() indent = ' ' @@ -61,7 +61,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): elif "DMX_BUF_OUT_SZ" in line: line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) elif "// vitis-unified-wrapper-io" in line: - line = self.gen_io_str(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" + line = self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: for inp_idx, inp in enumerate(inps): line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" @@ -119,7 +119,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model): elif "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) elif "// vitis-unified-wrapper-io" in line: - line += self.gen_io_str(indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" + line += self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" fout.write(line) fin.close() From abf830fe9df0f83fd309a5cd7dfce0edfbebbeef Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 14:02:52 +0200 Subject: [PATCH 28/70] add sub-writer override for vitis unified/unified partial --- hls4ml/writer/__init__.py | 2 + .../vitis_unified_partial_writer/__init__.py | 50 ++++++++++++++++ .../vitis_unified_partial_writer/mgs_gen.py | 18 +++++- .../writer/vitis_unified_writer/__init__.py | 60 +++++++++++-------- .../writer/vitis_unified_writer/build_gen.py | 8 ++- 5 files changed, 110 insertions(+), 28 deletions(-) diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 48897ce1a7..caf77d2a4d 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -4,6 +4,7 @@ from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter from hls4ml.writer.vitis_writer import VitisWriter from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter +from hls4ml.writer.vitis_unified_partial_writer import VitisUnifiedPartialWriter from hls4ml.writer.vivado_accelerator_writer import VivadoAcceleratorWriter from hls4ml.writer.vivado_writer import VivadoWriter from hls4ml.writer.writers import Writer, get_writer, register_writer # noqa: F401 @@ -12,6 +13,7 @@ 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_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index e69de29bb2..02b88624bd 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -0,0 +1,50 @@ + +from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter + + +class VitisUnifiedPartialWriter(VitisUnifiedWriter): + + def __init__(self): + super().__init__() + + #from .build_gen import VitisUnifiedPartial_BuildGen + from .driver_gen import VitisUnifiedPartial_DriverGen + from .meta_gen import VitisUnifiedPartial_MetaGen + from .test_bridge_gen import VitisUnifiedPartial_BridgeGen + from .test_cosim_gen import VitisUnifiedPartial_TestGen + from .wrap_gen import VitisUnifiedPartial_WrapperGen + + from .mgs_gen import VitisUnifiedPartial_MagicArchGen + + + + ################################################# + ######### override the vitisUnified Writer ###### + ################################################# + + self.dg = VitisUnifiedPartial_DriverGen + self.mg = VitisUnifiedPartial_MetaGen + self.tbg = VitisUnifiedPartial_BridgeGen + self.tcg = VitisUnifiedPartial_TestGen + self.wg = VitisUnifiedPartial_WrapperGen + + ################################################# + ######### override the vitisUnified Writer ###### + ################################################# + + self.magic_gen = VitisUnifiedPartial_MagicArchGen + + def generate_config(self, model): + from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig + self.writer_meta.vitis_unified_config = VitisUnifiedPartialConfig( + model.config, model.get_input_variables(), model.get_output_variables() + ) + + + def write_hls(self, model, is_multigraph=False): + + super().write_hls(model, is_multigraph) + + if is_multigraph: + self.magic_gen.copyMagicArchIp(self.writer_meta, model) + self.magic_gen.write_mgs(self.writer_meta, model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index fb6219991a..3ad582aa6c 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -1,18 +1,32 @@ import os +import shutil import stat from pathlib import Path from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta -from .meta_gen import VitisUnifiedPartial_MetaGen as mg -class VitisUnifiedPartial_MgsGen(): +class VitisUnifiedPartial_MagicArchGen(): + + + @classmethod + def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): + + magic_arch_src_folder_path = '../../templates/vitis_unified_partial/ips' + magic_arch_des_folder_path = f'{model.config.get_output_dir()}/ips' + + if os.path.exists(magic_arch_des_folder_path): + shutil.rmtree(magic_arch_des_folder_path) + shutil.copytree(magic_arch_src_folder_path, magic_arch_des_folder_path, dirs_exist_ok=True) + + @classmethod def write_mgs(self, meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v'), 'r') + fout = open(f'{model.config.get_output_dir()}/ips/magic_stream_grp_gen/myproject_mgs.cpp', 'w') metaList = meta.vitis_unified_config.get_mgs_meta_list() diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 3516b7cee0..b7c2ba0673 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -4,15 +4,6 @@ from shutil import copyfile from hls4ml.writer.vitis_writer import VitisWriter - -from . import build_gen as bg -from . import meta_gen as mtg -from . import mm_gen as mmg -from . import stream_gen as sg -from . import test_bridge_gen as tbg -from . import test_cosim_gen as tcg -from . import driver_gen as dg - from .meta import VitisUnifiedWriterMeta @@ -23,6 +14,23 @@ def __init__(self): super().__init__() self.writer_meta = VitisUnifiedWriterMeta() + from .build_gen import VitisUnified_BuildGen + from .driver_gen import VitisUnified_DriverGen + from .meta_gen import VitisUnified_MetaGen + from .test_bridge_gen import VitisUnified_BridgeGen + from .test_cosim_gen import VitisUnified_TestGen + from .wrap_gen import VitisUnified_WrapperGen + + self.bg = VitisUnified_BuildGen + self.dg = VitisUnified_DriverGen + self.mg = VitisUnified_MetaGen + self.tbg = VitisUnified_BridgeGen + self.tcg = VitisUnified_TestGen + self.wg = VitisUnified_WrapperGen + + + + def write_board_script_override(self, model): pass def write_build_prj_override(self, model): @@ -32,34 +40,38 @@ def write_build_opts(self, model): def write_tar(self, model): pass - def write_bridge(self, model): - tbg.write_bridge(self.writer_meta, model) + def write_bridge(self, model): ### test bench gen + self.tbg.write_bridge(self.writer_meta, model) def write_build_script(self, model): #### for bridge simulation - bg.write_bridge_build_script(self.writer_meta, model) + self.bg.write_bridge_build_script(self.writer_meta, model, self.mg) #### for hls kernel generation - bg.build_unified_project_ske(self.writer_meta, model) - bg.write_hls_kernel_cfg(self.writer_meta, model) + self.bg.build_unified_project_ske(self.writer_meta, model, self.mg) + self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg) #### for v++ to link hls to the system - bg.write_launch_vitis_linker_dir(self.writer_meta, model) - bg.write_launch_vitis_linker_launcher(self.writer_meta, model) - bg.write_launch_vitis_linker_cfg(self.writer_meta, model) - - def write_hls(self, model, is_multigraph=False): + self.bg.write_launch_vitis_linker_dir(self.writer_meta, model, self.mg) + self.bg.write_launch_vitis_linker_launcher(self.writer_meta, model, self.mg) + self.bg.write_launch_vitis_linker_cfg(self.writer_meta, model, self.mg) + def generate_config(self, model): from hls4ml.backends import VitisUnifiedConfig - self.writer_meta.vitis_unified_config = VitisUnifiedConfig( model.config, model.get_input_variables(), model.get_output_variables() ) + + def write_hls(self, model, is_multigraph=False): + + self.generate_config(model) + + super().write_hls(model) - mmg.write_gmem_wrapper (self.writer_meta, model) - sg.write_axi_wrapper (self.writer_meta, model) + self.wg.write_wrapper(self.writer_meta, model, self.mg) + ######### - dg .write_driver (self.writer_meta, model) - tcg.write_wrapper_test (self.writer_meta, model) + self.dg .write_driver (self.writer_meta, model, self.mg) + self.tcg.write_wrapper_test (self.writer_meta, model, self.mg) #self.write_new_tar(model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 93d1359c21..3162cee95b 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -7,6 +7,7 @@ class VitisUnified_BuildGen: + @classmethod def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/build_lib.sh')) @@ -27,6 +28,7 @@ def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): 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) + @classmethod def write_hls_kernel_cfg(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') @@ -56,6 +58,7 @@ def write_hls_kernel_cfg(self, meta, model, mg): fin.close() fout.close() + @classmethod def build_unified_project_ske(self, meta, model, mg, workspaceDir = None): if workspaceDir is None: workspaceDir = mg.get_vitis_unified_working_directory_dir(model) @@ -82,9 +85,11 @@ def build_unified_project_ske(self, meta, model, mg, workspaceDir = None): fin.close() fout.close() + @classmethod def write_launch_vitis_linker_dir(self, meta, model, mg): os.makedirs(mg.get_vitis_linker_dir(model), exist_ok=True) + @classmethod def write_launch_vitis_linker_launcher(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh'), 'r') @@ -106,8 +111,7 @@ def write_launch_vitis_linker_launcher(self, meta, model, mg): link_lib_dst = Path(f"{mg.get_vitis_linker_dir(model)}/buildAcc.sh").resolve() link_lib_dst.chmod(link_lib_dst.stat().st_mode | stat.S_IEXEC) - - + @classmethod def write_launch_vitis_linker_cfg(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg'), 'r') From 485c1c825825ea07e6e0b224d7b472b7c63aaee1 Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 14:09:44 +0200 Subject: [PATCH 29/70] register backend and writer --- hls4ml/backends/__init__.py | 4 ++++ hls4ml/writer/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 08fca7fb39..800d3935c0 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -14,10 +14,14 @@ from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig +from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_backend import VitisUnifiedPartialBackend +from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig + register_backend('Vivado', VivadoBackend) register_backend('VivadoAccelerator', VivadoAcceleratorBackend) register_backend('Vitis', VitisBackend) register_backend('VitisUnified', VitisUnifiedBackend) +register_backend('VitisUnifiedPartial', VitisUnifiedPartialBackend) register_backend('Quartus', QuartusBackend) register_backend('Catapult', CatapultBackend) register_backend('SymbolicExpression', SymbolicExpressionBackend) diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index caf77d2a4d..903867afa8 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -13,7 +13,7 @@ register_writer('VivadoAccelerator', VivadoAcceleratorWriter) register_writer('Vitis', VitisWriter) register_writer('VitisUnified', VitisUnifiedWriter) - +register_writer('VitisUnifiedPartial', VitisUnifiedPartialWriter) register_writer('Quartus', QuartusWriter) register_writer('oneAPI', OneAPIWriter) register_writer('Catapult', CatapultWriter) From d78a50ddf166cc58bee636c1d59b8fb371fa1023 Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 14:46:40 +0200 Subject: [PATCH 30/70] fix minor missing syntax --- .../vitis_unified_partial_backend.py | 10 ++- .../vitis_unified_partial_config.py | 4 +- .../driver/pynq/pynq_driver.py | 69 +++++++++++++++++++ .../vitis_unified_partial_writer/__init__.py | 2 +- .../vitis_unified_partial_writer/mgs_gen.py | 3 +- .../test_cosim_gen.py | 2 +- .../vitis_unified_partial_writer/wrap_gen.py | 4 +- .../writer/vitis_unified_writer/__init__.py | 8 ++- .../vitis_unified_writer/test_bridge_gen.py | 2 +- .../vitis_unified_writer/test_cosim_gen.py | 2 +- 10 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index 31186cc238..c54902fa61 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -70,9 +70,14 @@ def create_initial_config( 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream output_interim_type='io_stream', + init_mgs_meta=None, **_ ): + if init_mgs_meta is None: + init_mgs_meta = list() + if init_mgs_meta is None: + init_mgs_meta = [] config = super().create_initial_config( board=board, part=part, @@ -91,13 +96,16 @@ def create_initial_config( config['MultiGraphConfig'] = {} config['MultiGraphConfig']['amtGraph'] = -1 # it should be set by the multigraph system config['MultiGraphConfig']['graphIdx'] = -1 # -1 means unset yet or it is multigraph stitcher - config['MultiGraphConfig']['MgsMeta'] = [] #### it should be only used for stitcher + print(f"mgs initial is set to {init_mgs_meta}") + config['MultiGraphConfig']['MgsMeta'] = init_mgs_meta if init_mgs_meta is not None else [] #### it should be only used for stitcher config['MultiGraphConfig']['IOInterimType'] = {} config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type + return config + def _register_flows(self): diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py index ae38e914a9..593ffa6663 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py @@ -21,7 +21,9 @@ def __init__(self, config, model_inputs, model_outputs): self.amt_graph = self.config.get('MultiGraphConfig', {}).get('amtGraph', -1) self.graph_idx = self.config.get('MultiGraphConfig', {}).get('graphIdx', -1) - self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('mgsMeta', None) + self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('MgsMeta', None) + + def is_free_interim_input(self): diff --git a/hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py new file mode 100644 index 0000000000..980883ab7b --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py @@ -0,0 +1,69 @@ +# 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 +import numpy as np +import os +import subprocess +import re +import time + + +class MyDfxCtrl(DefaultIP): + def __init__(self, description): + super().__init__(description=description) + + self.REG_ADDR_AP_CTRL = 0x00 + + self.INP_PORT_NAMEs = [ + #### hls-driver-input-dbg-name + ] + + self.REG_ADDR_INP_PTRs = [ + #### hls-driver-input-ptr + ] + self.REG_ADDR_INP_SZs = [ + #### hls-driver-input-size + ] + + self.OUT_PORT_NAMEs = [ + #### hls-driver-output-dbg-name + ] + + self.REG_ADDR_OUT_PTRs = [ + #### hls-driver-output-ptr + ] + + self.REG_ADDR_OUT_SZs = [ + #### hls-driver-output-size + ] + + bindto = ['xilinx.com:hls::1.0'] + + ######## TODO interrupt + + + def setSingleBit(self, addr, idx): + self.write(addr, 1 << idx) + + def ctrlStart(self): + self.write(0x00, 0x01) # ap_start = 1 + + def waitUntilDone(self): + while (self.read(0x00) & 0x2) == 0: # Wait for ap_done + time.sleep(0.001) + + def setInput(self, idx, buffer): + + print(f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {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) + self.write(self.REG_ADDR_INP_SZs[idx], buffer.size) + buffer.flush() + + def setOutput(self, idx, buffer): + + print(f"input {self.OUT_PORT_NAMEs[idx]} will be set to addr: {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) + self.write(self.REG_ADDR_OUT_SZs[idx], buffer.size) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index 02b88624bd..44993904ca 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -45,6 +45,6 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model, is_multigraph) - if is_multigraph: + if True: self.magic_gen.copyMagicArchIp(self.writer_meta, model) self.magic_gen.write_mgs(self.writer_meta, model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index 3ad582aa6c..bd4c2c3f89 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -12,7 +12,8 @@ class VitisUnifiedPartial_MagicArchGen(): @classmethod def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): - magic_arch_src_folder_path = '../../templates/vitis_unified_partial/ips' + filedir = os.path.dirname(os.path.abspath(__file__)) + magic_arch_src_folder_path = os.path.join(filedir, '../../templates/vitis_unified_partial/ips') magic_arch_des_folder_path = f'{model.config.get_output_dir()}/ips' if os.path.exists(magic_arch_des_folder_path): diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py index d61ad187d9..959ed9ce44 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py @@ -7,7 +7,7 @@ class VitisUnifiedPartial_TestGen(VitisUnified_TestGen): @classmethod - def write_wrapper(self, meta, model, mg): + def write_wrapper_test(self, meta, model, mg): inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py index a8695f4778..4519cde426 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -67,9 +67,9 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): line += f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" #### declare stream size for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth={inp[inp_idx].pragma[1]}\n" + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth={inp.pragma[1]}\n" for out_idx, out in enumerate(outs): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth={out[out_idx].pragma[1]}\n" + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth={out.pragma[1]}\n" elif "// hls-fpga-machine-learning insert enqueue" in line: diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index b7c2ba0673..005e79e287 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -41,7 +41,7 @@ def write_tar(self, model): pass def write_bridge(self, model): ### test bench gen - self.tbg.write_bridge(self.writer_meta, model) + self.tbg.write_bridge(self.writer_meta, model, self.mg) def write_build_script(self, model): #### for bridge simulation @@ -60,6 +60,11 @@ def generate_config(self, model): model.config, model.get_input_variables(), model.get_output_variables() ) + def make_export_path(self, model): + export_path = f'{model.config.get_output_dir()}/export' + if not os.path.exists(export_path): + os.makedirs(export_path) + def write_hls(self, model, is_multigraph=False): self.generate_config(model) @@ -70,6 +75,7 @@ def write_hls(self, model, is_multigraph=False): ######### + self.make_export_path(model) self.dg .write_driver (self.writer_meta, model, self.mg) self.tcg.write_wrapper_test (self.writer_meta, model, self.mg) diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 8970bd4bda..75f8ee0f03 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -4,7 +4,7 @@ class VitisUnified_BridgeGen: @classmethod - def write_bridge(meta: VitisUnifiedWriterMeta, model, mg): + def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index dc7e1d6418..16b3adbfec 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -38,7 +38,7 @@ def write_wrapper_test(self, meta, model, mg): for inputIdx, inp in enumerate(model_inputs): ##### input should be float newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template - inputPortName=mg.c(inp, True, inputIdx), + inputPortName=mg.get_io_port_name(inp, True, inputIdx), startIdx=str(offset) ) offset += inp.size() From d23e591553d809eb8f4ddab077d3f35982ff2cbf Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 17:37:53 +0200 Subject: [PATCH 31/70] fix wrap_gen syntax bug + add include ap_axi_sdata.h for wrapgen + add automatic magic streamer composer --- hls4ml/templates/vitis_unified/build_lib.sh | 7 +- .../templates/vitis_unified/myproject_axi.cpp | 18 - .../templates/vitis_unified/myproject_axi.h | 16 - .../streamGrp.v | 2 +- .../ips/magic_streamer_grp_prj/composer.tcl | 20 + .../vitis_unified_partial/myproject_axi.cpp | 4 +- .../vitis_unified_partial/myproject_axi.h | 13 +- .../templates/vivado/ap_types/ap_axi_sdata.h | 402 ++++++++++++++++++ .../vitis_unified_partial_writer/meta_gen.py | 10 +- .../vitis_unified_partial_writer/mgs_gen.py | 42 +- .../test_bridge_gen.py | 14 +- .../vitis_unified_partial_writer/wrap_gen.py | 25 +- .../writer/vitis_unified_writer/build_gen.py | 6 +- 13 files changed, 504 insertions(+), 75 deletions(-) delete mode 100644 hls4ml/templates/vitis_unified/myproject_axi.cpp delete mode 100644 hls4ml/templates/vitis_unified/myproject_axi.h rename hls4ml/templates/vitis_unified_partial/ips/{magic_stream_grp_gen => magic_stream_grp_src}/streamGrp.v (89%) create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl create mode 100755 hls4ml/templates/vivado/ap_types/ap_axi_sdata.h diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh index fd7f3c2cdb..a2b0d636e3 100644 --- a/hls4ml/templates/vitis_unified/build_lib.sh +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -11,7 +11,8 @@ CFLAGS="$CFLAGS -D$VITIS_UNIFIED_FLAGS" INCFLAGS="-Ifirmware/ap_types/" -PROJECT=myproject +PROJECT=myprojectBaseName +WRAPPER_NAME=myprojectWrapName LIB_STAMP=mystamp BASEDIR="$(cd "$(dirname "$0")" && pwd)" WEIGHTS_DIR="\"${BASEDIR}/firmware/weights\"" @@ -24,7 +25,7 @@ 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/${PROJECT}_dm.cpp -o ${PROJECT}_dm.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 ${PROJECT}_dm.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${WRAPPER_NAME}.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so rm -f *.o \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_axi.cpp b/hls4ml/templates/vitis_unified/myproject_axi.cpp deleted file mode 100644 index 35abb02e26..0000000000 --- a/hls4ml/templates/vitis_unified/myproject_axi.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// hls-fpga-machine-learning insert include - -void myproject_axi( - - // hls-fpga-machine-learning insert multiIo - -) { - - // hls-fpga-machine-learning insert interface - - // hls-fpga-machine-learning insert local vars - - // hls-fpga-machine-learning insert enqueue - - // hls-fpga-machine-learning insert call - - // hls-fpga-machine-learning insert dequeue -} diff --git a/hls4ml/templates/vitis_unified/myproject_axi.h b/hls4ml/templates/vitis_unified/myproject_axi.h deleted file mode 100644 index 43ee01d5df..0000000000 --- a/hls4ml/templates/vitis_unified/myproject_axi.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef MYPROJECT_AXI_H_ -#define MYPROJECT_AXI_H_ - -#include - -#include "ap_axi_sdata.h -#include "MY_PROJECT_AXI_INC.h" -// hls-fpga-machine-learning insert definitions - -void myproject_axi( - -// hls-fpga-machine-learning insert multi-io - -); -#endif \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_src/streamGrp.v similarity index 89% rename from hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v rename to hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_src/streamGrp.v index 8ec8af7eb8..872ad7a517 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_src/streamGrp.v @@ -7,7 +7,7 @@ module streamGrp #( // hls4ml-streamGrp-gen-io input wire clk, - input wire nreset, + input wire nreset ); diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl new file mode 100644 index 0000000000..eab3004dd9 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl @@ -0,0 +1,20 @@ +create_project mgs_ip_prj . -part xczu9eg-ffvb1156-2-e +set_property board_part xilinx.com:zcu102:part0:3.4 [current_project] +add_files -norecurse ../magic_stream_grp_src/streamGrp.v +update_compile_order -fileset sources_1 +add_files -norecurse ../magic_streamer/src/magicStreamer.v + + + + +ipx::package_project -root_dir ../magic_streamer_grp_ip -vendor user.org -library user -taxonomy /UserIP -import_files + + +set_property core_revision 2 [ipx::current_core] +ipx::create_xgui_files [ipx::current_core] +ipx::update_checksums [ipx::current_core] +ipx::check_integrity [ipx::current_core] + +ipx::save_core [ipx::current_core] +set_property ip_repo_paths ../magic_streamer_grp_ip [current_project] +update_ip_catalog \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp index 7906a89d76..0031e383b0 100644 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp @@ -2,7 +2,7 @@ #include #include - +#include "WRAPPER_FILE_NAME.h" template void enqueue_atom2layer(hls::stream& src_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ @@ -78,6 +78,8 @@ void MY_PROJECT_TOP_FUNC( // hls-fpga-machine-learning insert local vars +// hls-fpga-machine-learning insert isLast vars + // hls-fpga-machine-learning insert enqueue // hls-fpga-machine-learning insert call diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.h b/hls4ml/templates/vitis_unified_partial/myproject_axi.h index f3e1c14631..be2955f956 100644 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.h +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.h @@ -1,14 +1,19 @@ -#ifndef MYPROJECT_AXI_H_ -#define MYPROJECT_AXI_H_ +#ifndef FILENAME_H +#define FILENAME_H #include +#include "MY_PROJECT_AXI_INC.h" +#include "ap_axi_sdata.h" + // hls-fpga-machine-learning insert include // hls-fpga-machine-learning insert definitions -void myproject_axi( +void MY_PROJECT_TOP_FUNC( -// hls-fpga-machine-learning insert multi-io +// vitis-unified-wrapper-io ); + + #endif \ No newline at end of file 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/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py index 82c3899516..639f6dbe67 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py @@ -17,7 +17,7 @@ def get_wrapper_file_name(self, model): @classmethod def get_io_port_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" - return f"stream_{ioDirect}{str(idx)}_{tensorVar.name}" + return f"streamIo_{ioDirect}{str(idx)}_{tensorVar.name}" @classmethod def get_top_wrap_func_name(self, model): @@ -56,7 +56,7 @@ def get_all_last_logic(self, amt): def get_enqueue_func_atom2stream(self, tensorVar, idx: int): result = "enqueue_atom2layer<{INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( INPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size), + SIZE = str(tensorVar.size()), SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), IS_LAST = self.get_is_last_var(idx), @@ -68,7 +68,7 @@ def get_enqueue_func_stream2rstream(self, tensorVar, idx: int): result = "enqueue_layerStream2layer<{INPUT_LAYER_STREAM}, {INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( INPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), INPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size), + SIZE = str(tensorVar.size()), SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), IS_LAST = self.get_is_last_var(idx), @@ -80,7 +80,7 @@ def get_dequeue_func_rstream2atom(self, tensorVar, idx: int, lastcheck: str,out_ result = "dequeue_layer2atom<{ATOMIC_TYPE}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK});".format( ATOMIC_TYPE = out_dma_type, OUTPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size), + SIZE = str(tensorVar.size()), DES_STREAM = self.get_io_port_name(tensorVar, False, idx), RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), IS_LAST_CHECK = lastcheck @@ -92,7 +92,7 @@ def get_dequeue_func_rstream2stream(self, tensorVar, idx: int, lastcheck: str): result = "dequeue_layer2layer><{OUTPUT_LAYER_STREAM}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK})".format( OUTPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), OUTPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size), + SIZE = str(tensorVar.size()), DES_STREAM = self.get_io_port_name(tensorVar, False, idx), RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), IS_LAST_CHECK = lastcheck diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index bd4c2c3f89..ef2a6f11b9 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -20,6 +20,14 @@ def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): shutil.rmtree(magic_arch_des_folder_path) shutil.copytree(magic_arch_src_folder_path, magic_arch_des_folder_path, dirs_exist_ok=True) + ##### delete the magic streamer grp generated ip first + magic_stream_grp_ip_path = f'{model.config.get_output_dir()}/ips/magic_streamer_grp_ip' + + if os.path.exists(magic_stream_grp_ip_path): + shutil.rmtree(magic_stream_grp_ip_path) + os.makedirs(magic_stream_grp_ip_path) + + @classmethod @@ -28,7 +36,7 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v'), 'r') - fout = open(f'{model.config.get_output_dir()}/ips/magic_stream_grp_gen/myproject_mgs.cpp', 'w') + fout = open(f'{model.config.get_output_dir()}/ips/magic_stream_grp_gen/streamGrpGen.v', 'w') metaList = meta.vitis_unified_config.get_mgs_meta_list() #### v------ mgs0 v--------- mgs1 @@ -43,35 +51,33 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): parameterList.append(f"parameter DATA_WIDTH_{idx} = {data_width}") parameterList.append(f"parameter INDEX_WIDTH_{idx} = {index_width}") - parameterStr = ",\n".join(parameterList) - newline += parameterStr + "\n" + parameterStr = ",\n".join(parameterList) + newline += parameterStr + "\n" elif "// hls4ml-streamGrp-gen-io" in line: ioList = [] for idx in range(len(metaList)): ioList.append(f"//io for MGS{str(idx)}") - ioList.append(f"input wire [DATA_WIDTH-1:0] S{str(idx)}_AXI_TDATA" ) - ioList.append(f"input wire S{str(idx)}_AXI_TVALID") - ioList.append(f"output wire S{str(idx)}_AXI_TREADY") - ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) - ioList.append(f"output wire [DATA_WIDTH-1:0] M{str(idx)}_AXI_TDATA" ) - ioList.append(f"output wire M{str(idx)}_AXI_TVALID") - ioList.append(f"input wire M{str(idx)}_AXI_TREADY") - ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) + ioList.append(f"input wire [DATA_WIDTH_{str(idx)} -1:0] S{str(idx)}_AXI_TDATA" ) + ioList.append(f"input wire S{str(idx)}_AXI_TVALID") + ioList.append(f"output wire S{str(idx)}_AXI_TREADY") + ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) + ioList.append(f"output wire [DATA_WIDTH_{str(idx)}-1:0] M{str(idx)}_AXI_TDATA" ) + ioList.append(f"output wire M{str(idx)}_AXI_TVALID") + ioList.append(f"input wire M{str(idx)}_AXI_TREADY") + ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) - newline += ",\n".join(ioList) + "\n" + newline += ",\n".join(ioList) + ",\n" elif "// hls4ml-streamGrp-gen-create-module" in line: for idx in range(len(metaList)): - newline += f"//create module for MGS{str(idx)}" + newline += f"//create module for MGS{str(idx)}\n" newline += f"MagicStreammerCore #(\n" - newline += f" .clk(clk),\n" - newline += f" .reset(nreset)\n" newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" - newline += f" .INDEX_WIDTH(INDEX_WIDTH_{idx})\n" + newline += f" .STORAGE_IDX_WIDTH(INDEX_WIDTH_{idx})\n" newline += f")\n" newline += f"MGS{str(idx)} (\n" newline += f" .S_AXI_TDATA(S{str(idx)}_AXI_TDATA),\n" @@ -81,7 +87,9 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): newline += f" .M_AXI_TDATA(M{str(idx)}_AXI_TDATA),\n" newline += f" .M_AXI_TVALID(M{str(idx)}_AXI_TVALID),\n" newline += f" .M_AXI_TREADY(M{str(idx)}_AXI_TREADY),\n" - newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST)\n" + newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST),\n" + newline += f" .clk(clk),\n" + newline += f" .reset(nreset)\n" newline += f");\n" diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py index 44432f1702..d083f7ac45 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py @@ -5,8 +5,8 @@ class VitisUnifiedPartial_BridgeGen(VitisUnified_BridgeGen): - - def write_bridge(meta: VitisUnifiedWriterMeta, model, mg): + @classmethod + def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) #### we will use the same bridge template file as VitisUnified_BridgeGen @@ -20,6 +20,16 @@ def write_bridge(meta: VitisUnifiedWriterMeta, model, mg): #### TODO we will do the code next time newline = line + + if 'MYPROJECT' in line: + newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) + + elif 'myproject' in line: + newline = line.replace('myproject', format(model.config.get_project_name())) + + elif 'PROJECT_FILE_NAME' in line: + newline = line.replace('PROJECT_FILE_NAME', format(mg.get_wrapper_file_name(model))) + fout.write(newline) diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py index 4519cde426..7f0c4c2348 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -48,10 +48,12 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): for line in fin.readlines(): - if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) - elif "MY_PROJECT_TOP_FUNC" in line: + # if "MY_PROJECT_AXI_INC" in line: + # line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + if "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) + elif "WRAPPER_FILE_NAME" in line: + line = line.replace("WRAPPER_FILE_NAME", mg.get_wrapper_file_name(model)) elif "// hls-fpga-machine-learning insert multi-io" in line: line = self.gen_io_str(mg, indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" elif "// hls-fpga-machine-learning insert interface" in line: @@ -71,6 +73,9 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): for out_idx, out in enumerate(outs): line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth={out.pragma[1]}\n" + elif "// hls-fpga-machine-learning insert isLast vars" in line: + for inp_idx in range(len(inps)): + line += f"bool {mg.get_is_last_var(inp_idx)} = false;\n" elif "// hls-fpga-machine-learning insert enqueue" in line: for inp_idx, inp in enumerate(inps): @@ -110,8 +115,14 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): fout = open(f'{model.config.get_output_dir()}/firmware/myproject_axi.h', 'w') for line in fin.readlines(): - if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + + newline = line + if "FILENAME" in line: + newline = line.replace("FILENAME", mg.get_wrapper_file_name(model).upper()) + if "MY_PROJECT_TOP_FUNC" in line: + newline = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) + elif "MY_PROJECT_AXI_INC" in line: + newline = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) elif "// hls-fpga-machine-learning insert definitions" in line: ##### make input newline = '' @@ -130,7 +141,9 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): if meta.vitis_unified_config.is_free_interim_output(): for out in outs: newline += mg.get_axi_wrapper_dec(out) + "\n" - fout.write(line) + elif "// vitis-unified-wrapper-io" in line: + newline = self.gen_io_str(mg, indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" + fout.write(newline) fin.close() diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 3162cee95b..0adbecb66c 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -14,8 +14,10 @@ def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): fout = open(f"{model.config.get_output_dir()}/build_lib.sh", 'w') for line in fin.readlines(): - if 'myproject' in line: - line = line.replace('myproject', format(model.config.get_project_name())) + if 'myprojectBaseName' in line: + line = line.replace('myprojectBaseName', format(model.config.get_project_name())) + if 'myprojectWrapName' in line: + line = line.replace('myprojectWrapName', mg.get_wrapper_file_name(model)) if 'mystamp' in line: line = line.replace('mystamp', model.config.get_config_value('Stamp')) From 6cce4ea8c41f2e808e50a5be2d9428400d44ff29 Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 20 Aug 2025 21:55:41 +0200 Subject: [PATCH 32/70] add magic streamer generator and auto invoker --- .../vitis_unified_partial_backend.py | 10 ++++- .../component.xml | 0 .../src/magicStreamer.v | 0 .../xgui/MagicStreammerCore_v1_0.tcl | 0 .../ips/magic_streamer_grp_prj/composer.tcl | 2 +- .../streamGrp.v | 0 .../vitis_unified_partial_writer/mgs_gen.py | 40 ++++++++++++++----- 7 files changed, 40 insertions(+), 12 deletions(-) rename hls4ml/templates/vitis_unified_partial/ips/{magic_steamer => magic_streamer}/component.xml (100%) rename hls4ml/templates/vitis_unified_partial/ips/{magic_steamer => magic_streamer}/src/magicStreamer.v (100%) rename hls4ml/templates/vitis_unified_partial/ips/{magic_steamer => magic_streamer}/xgui/MagicStreammerCore_v1_0.tcl (100%) rename hls4ml/templates/vitis_unified_partial/ips/{magic_stream_grp_src => magic_streamer_grp_src}/streamGrp.v (100%) diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index c54902fa61..eb54f9bf2a 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -31,10 +31,18 @@ def build( vsynth=False, fifo_opt=False, bitfile=False, - log_to_stdout=True + log_to_stdout=True, + compose_streamers=False ): ##### do magic streamer generation + if compose_streamers: + magic_stream_grp_ip_prj = f'{model.config.get_output_dir()}/ips/magic_streamer_grp_prj' + self.run_term_command(model, + "magic_streamer_ip_generation", + "vivado -mode gui -source composer.tcl", log_to_stdout, + magic_stream_grp_ip_prj + ) pass diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/component.xml similarity index 100% rename from hls4ml/templates/vitis_unified_partial/ips/magic_steamer/component.xml rename to hls4ml/templates/vitis_unified_partial/ips/magic_streamer/component.xml diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v similarity index 100% rename from hls4ml/templates/vitis_unified_partial/ips/magic_steamer/src/magicStreamer.v rename to hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl similarity index 100% rename from hls4ml/templates/vitis_unified_partial/ips/magic_steamer/xgui/MagicStreammerCore_v1_0.tcl rename to hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl index eab3004dd9..7dd73984bc 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl @@ -1,6 +1,6 @@ create_project mgs_ip_prj . -part xczu9eg-ffvb1156-2-e set_property board_part xilinx.com:zcu102:part0:3.4 [current_project] -add_files -norecurse ../magic_stream_grp_src/streamGrp.v +add_files -norecurse ../magic_streamer_grp_src/streamGrp.v update_compile_order -fileset sources_1 add_files -norecurse ../magic_streamer/src/magicStreamer.v diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_src/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v similarity index 100% rename from hls4ml/templates/vitis_unified_partial/ips/magic_stream_grp_src/streamGrp.v rename to hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index ef2a6f11b9..62b487bc53 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -34,9 +34,9 @@ def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): def write_mgs(self, meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_stream_grp_gen/streamGrp.v'), 'r') + fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v'), 'r') - fout = open(f'{model.config.get_output_dir()}/ips/magic_stream_grp_gen/streamGrpGen.v', 'w') + fout = open(f'{model.config.get_output_dir()}/ips/magic_streamer_grp_src/streamGrp.v', 'w') metaList = meta.vitis_unified_config.get_mgs_meta_list() #### v------ mgs0 v--------- mgs1 @@ -49,7 +49,7 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): parameterList = [] for idx, (data_width, index_width, *_) in enumerate(metaList): parameterList.append(f"parameter DATA_WIDTH_{idx} = {data_width}") - parameterList.append(f"parameter INDEX_WIDTH_{idx} = {index_width}") + parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx} = {index_width}") parameterStr = ",\n".join(parameterList) newline += parameterStr + "\n" @@ -59,13 +59,23 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): for idx in range(len(metaList)): ioList.append(f"//io for MGS{str(idx)}") ioList.append(f"input wire [DATA_WIDTH_{str(idx)} -1:0] S{str(idx)}_AXI_TDATA" ) - ioList.append(f"input wire S{str(idx)}_AXI_TVALID") - ioList.append(f"output wire S{str(idx)}_AXI_TREADY") - ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) + ioList.append(f"input wire S{str(idx)}_AXI_TVALID") + ioList.append(f"output wire S{str(idx)}_AXI_TREADY") + ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) ioList.append(f"output wire [DATA_WIDTH_{str(idx)}-1:0] M{str(idx)}_AXI_TDATA" ) - ioList.append(f"output wire M{str(idx)}_AXI_TVALID") - ioList.append(f"input wire M{str(idx)}_AXI_TREADY") - ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) + ioList.append(f"output wire M{str(idx)}_AXI_TVALID") + ioList.append(f"input wire M{str(idx)}_AXI_TREADY") + ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) + ioList.append("//--------- commanding ------------") + ioList.append(f"input wire storeReset_{str(idx)}") + ioList.append(f"input wire loadReset_{str(idx)}") + ioList.append(f"input wire storeInit_{str(idx)}") + ioList.append(f"input wire loadInit_{str(idx)}") + ioList.append(f"output wire finStore_{str(idx)}") + ioList.append("//----------debugging -------------") + ioList.append(f"output wire [4-1:0] dbg_state_{str(idx)}") + ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_store_bytes_{str(idx)}") + ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_load_bytes_{str(idx)}") newline += ",\n".join(ioList) + ",\n" @@ -77,7 +87,7 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): newline += f"//create module for MGS{str(idx)}\n" newline += f"MagicStreammerCore #(\n" newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" - newline += f" .STORAGE_IDX_WIDTH(INDEX_WIDTH_{idx})\n" + newline += f" .STORAGE_IDX_WIDTH(STORAGE_IDX_WIDTH_{idx})\n" newline += f")\n" newline += f"MGS{str(idx)} (\n" newline += f" .S_AXI_TDATA(S{str(idx)}_AXI_TDATA),\n" @@ -88,6 +98,16 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): newline += f" .M_AXI_TVALID(M{str(idx)}_AXI_TVALID),\n" newline += f" .M_AXI_TREADY(M{str(idx)}_AXI_TREADY),\n" newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST),\n" + newline += f"//------ command --------\n" + newline += f" .storeReset(storeReset_{str(idx)}),\n" + newline += f" .loadReset(loadReset_{str(idx)}),\n" + newline += f" .storeInit(storeInit_{str(idx)}),\n" + newline += f" .loadInit(loadInit_{str(idx)}),\n" + newline += f" .finStore(finStore_{str(idx)}),\n" + newline += f"//------ debugging ------\n" + newline += f" .dbg_state(dbg_state_{str(idx)}),\n" + newline += f" .dbg_amt_store_bytes(dbg_amt_store_bytes_{str(idx)}),\n" + newline += f" .dbg_amt_load_bytes(dbg_amt_load_bytes_{str(idx)}),\n" newline += f" .clk(clk),\n" newline += f" .reset(nreset)\n" newline += f");\n" From 7d99de6e5c1b29756118e81460f7ab0159a6150b Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 21 Aug 2025 12:20:33 +0200 Subject: [PATCH 33/70] add icap wraper and magic seq --- .../ips/magic_icap/component.xml | 333 ++++++++++++++++++ .../ips/magic_icap/src/icapWrapper.v | 61 ++++ .../ips/magic_icap/xgui/icapWrap_v1_0.tcl | 10 + .../ips/magic_seq/component.xml | 28 +- .../ips/magic_seq/src/magicSeq.v | 2 +- .../ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl | 16 - .../ips/magic_streamer_grp_src/streamGrp.v | 2 + .../vitis_unified_partial_writer/mgs_gen.py | 37 +- 8 files changed, 443 insertions(+), 46 deletions(-) create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml create mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v create mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml new file mode 100644 index 0000000000..029c716ca7 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml @@ -0,0 +1,333 @@ + + + user.org + user + icapWrap + 1.0 + + + ICAP + + + + + + + csib + + + CSIB + + + + + rdwrb + + + RDWRB + + + + + i + + + I + + + + + o + + + O + + + + + avail + + + AVAIL + + + + + prdone + + + PRDONE + + + + + prerror + + + PRERROR + + + + + + CLK + + + + + + + CLK + + + CLK + + + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + icapWrap + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + 074c58b5 + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + icapWrap + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + 074c58b5 + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + f92e9879 + + + + + + + CLK + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + AVAIL + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + O + + out + + 31 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + PRDONE + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + PRERROR + + out + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + CSIB + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + I + + in + + 31 + 0 + + + + std_logic_vector + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + RDWRB + + in + + + std_logic + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + + xilinx_anylanguagesynthesis_view_fileset + + src/icapWrapper.v + verilogSource + CHECKSUM_074c58b5 + IMPORTED_FILE + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + src/icapWrapper.v + verilogSource + IMPORTED_FILE + + + + xilinx_xpgui_view_fileset + + xgui/icapWrap_v1_0.tcl + tclSource + CHECKSUM_f92e9879 + XGUI_VERSION_2 + + + + icapWrap_v1_0 + + + Component_Name + icapWrap_v1_0 + + + + + + virtex7 + qvirtex7 + versal + kintex7 + kintex7l + qkintex7 + qkintex7l + akintex7 + artix7 + artix7l + aartix7 + qartix7 + zynq + qzynq + azynq + spartan7 + aspartan7 + virtexu + zynquplus + virtexuplus + virtexuplusHBM + virtexuplus58g + kintexuplus + artixuplus + kintexu + + + /UserIP + + icapWrap_v1_0 + package_project + 2 + 2025-08-21T08:13:00Z + + + 2023.2 + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v new file mode 100755 index 0000000000..6036c0244d --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v @@ -0,0 +1,61 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 06/22/2025 06:11:40 PM +// Design Name: +// Module Name: icapWrapper +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module icapWrap( + input CLK, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP avail" *) output AVAIL, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP o" *) output [31:0] O, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP prdone" *) output PRDONE, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP prerror" *) output PRERROR, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP csib" *) input CSIB, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP i" *) input [31:0] I, + (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP rdwrb" *) input RDWRB + ); + + + +// ICAPE3: Internal Configuration Access Port +// UltraScale +// Xilinx HDL Language Template, version 2023.2 + +ICAPE3 #( + .DEVICE_ID(32'h03628093), // Specifies the pre-programmed Device ID value to be used for simulation + // purposes. + .ICAP_AUTO_SWITCH("DISABLE"), // Enable switch ICAP using sync word. + .SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation + // model. +) +ICAPE3_inst ( + .AVAIL(AVAIL), // 1-bit output: Availability status of ICAP. + .O(O), // 32-bit output: Configuration data output bus. + .PRDONE(PRDONE), // 1-bit output: Indicates completion of Partial Reconfiguration. + .PRERROR(PRERROR), // 1-bit output: Indicates error during Partial Reconfiguration. + .CLK(CLK), // 1-bit input: Clock input. + .CSIB(CSIB), // 1-bit input: Active-Low ICAP enable. + .I(I), // 32-bit input: Configuration data input bus. + .RDWRB(RDWRB) // 1-bit input: Read/Write Select input. +); + +// End of ICAPE3_inst instantiation + + +endmodule diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl new file mode 100644 index 0000000000..0db18e9a9d --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl @@ -0,0 +1,10 @@ +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + ipgui::add_page $IPINST -name "Page 0" + + +} + + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml index 8a7851f1f3..d489175403 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml @@ -2,7 +2,7 @@ user.org user - MagicSeq + MagicSeqTop 1.0 @@ -357,7 +357,7 @@ SENSITIVITY - LEVEL_HIGH + LEVEL_HIGH @@ -398,7 +398,7 @@ viewChecksum - 2882be72 + 189b94c8 @@ -414,7 +414,7 @@ viewChecksum - 2882be72 + 189b94c8 @@ -428,7 +428,7 @@ viewChecksum - 2750c49f + 8684dac7 @@ -1337,7 +1337,7 @@ - choice_list_9ca20931 + choice_list_99a1d2b9 LEVEL_HIGH LEVEL_LOW EDGE_RISING @@ -1385,7 +1385,7 @@ src/magicSeq.v verilogSource - CHECKSUM_07379c0c + CHECKSUM_feefee95 IMPORTED_FILE @@ -1435,14 +1435,14 @@ xilinx_xpgui_view_fileset - xgui/MagicSeq_v1_0.tcl + xgui/MagicSeqTop_v1_0.tcl tclSource - CHECKSUM_2750c49f + CHECKSUM_8684dac7 XGUI_VERSION_2 - MagicSeq + MagicSeqTop GLOB_ADDR_WIDTH @@ -1581,17 +1581,17 @@ /UserIP - MagicSeq + MagicSeqTop package_project 3 - 2025-08-19T11:05:58Z + 2025-08-21T09:29:51Z 2023.2 - + - + diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v index 27810a721c..3af8df4627 100755 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v @@ -18,7 +18,7 @@ module MagicSeqTop #( parameter BANK0_CONTROL_WIDTH = 4, parameter BANK0_STATUS_WIDTH = 4, - parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer + parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer the BANK1_INDEX_WIDTH SHOULD BE EQUAL TO BANK0_CNT_WIDTH parameter BANK0_INTR_WIDTH = 1, /// the round counter for the sequencer parameter BANK0_ROUNDTRIP_WIDTH = 16, /// the round trip counter for the sequencer diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl index 71eeb969b4..24d2676d1e 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl @@ -3,26 +3,10 @@ proc init_gui { IPINST } { ipgui::add_param $IPINST -name "Component_Name" #Adding Page set Page_0 [ipgui::add_page $IPINST -name "Page 0"] - ipgui::add_param $IPINST -name "ADDR_WIDTH" -parent ${Page_0} ipgui::add_param $IPINST -name "BANK0_CNT_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK0_CONTROL_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK0_INTR_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK0_ROUNDTRIP_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK0_STATUS_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_DST_ADDR_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_DST_SIZE_WIDTH" -parent ${Page_0} ipgui::add_param $IPINST -name "BANK1_INDEX_WIDTH" -parent ${Page_0} ipgui::add_param $IPINST -name "BANK1_LD_MSK_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_PROFILE_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_SRC_ADDR_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_SRC_SIZE_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "BANK1_STATUS_WIDTH" -parent ${Page_0} ipgui::add_param $IPINST -name "BANK1_ST_MSK_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "DMA_EXEC_TASK_CNT" -parent ${Page_0} - ipgui::add_param $IPINST -name "DMA_INIT_TASK_CNT" -parent ${Page_0} - ipgui::add_param $IPINST -name "GLOB_ADDR_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "GLOB_DATA_WIDTH" -parent ${Page_0} } diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v index 872ad7a517..0ae634df5d 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v @@ -11,6 +11,8 @@ module streamGrp #( ); + // hls4ml-streamGrp-gen-logic-assign + // hls4ml-streamGrp-gen-create-module endmodule \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index 62b487bc53..f6466b987b 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -48,15 +48,15 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): if "// hls4ml-streamGrp-gen-parameter" in line: parameterList = [] for idx, (data_width, index_width, *_) in enumerate(metaList): - parameterList.append(f"parameter DATA_WIDTH_{idx} = {data_width}") - parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx} = {index_width}") + parameterList.append(f"parameter DATA_WIDTH_{idx+1} = {data_width}") + parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx+1} = {index_width}") parameterStr = ",\n".join(parameterList) newline += parameterStr + "\n" elif "// hls4ml-streamGrp-gen-io" in line: ioList = [] - for idx in range(len(metaList)): + for idx in range(1, len(metaList) + 1): ioList.append(f"//io for MGS{str(idx)}") ioList.append(f"input wire [DATA_WIDTH_{str(idx)} -1:0] S{str(idx)}_AXI_TDATA" ) ioList.append(f"input wire S{str(idx)}_AXI_TVALID") @@ -66,24 +66,31 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): ioList.append(f"output wire M{str(idx)}_AXI_TVALID") ioList.append(f"input wire M{str(idx)}_AXI_TREADY") ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) - ioList.append("//--------- commanding ------------") - ioList.append(f"input wire storeReset_{str(idx)}") - ioList.append(f"input wire loadReset_{str(idx)}") - ioList.append(f"input wire storeInit_{str(idx)}") - ioList.append(f"input wire loadInit_{str(idx)}") - ioList.append(f"output wire finStore_{str(idx)}") ioList.append("//----------debugging -------------") ioList.append(f"output wire [4-1:0] dbg_state_{str(idx)}") ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_store_bytes_{str(idx)}") ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_load_bytes_{str(idx)}") + ioList.append("//--------- Pool commanding ------------") + ioList.append("///// for load [Reset/Init] of dma will be ignore") + ioList.append("///// for store [Reset/Init] of dma will be ignore") + ioList.append(f"input wire[{len(metaList)}: 0] storeReset") + ioList.append(f"input wire[{len(metaList)}: 0] loadReset") + ioList.append(f"input wire[{len(metaList)}: 0] storeInit") + ioList.append(f"input wire[{len(metaList)}: 0] loadInit") + ioList.append(f"output wire[{len(metaList)}: 0] finStore") + ioList.append(f"input wire finStoreProxyDma") + newline += ",\n".join(ioList) + ",\n" + elif "// hls4ml-streamGrp-gen-logic-assign" in line: + newline += "assign finStore[0] = finStoreProxyDma;\n" + elif "// hls4ml-streamGrp-gen-create-module" in line: - for idx in range(len(metaList)): + for idx in range(1, len(metaList)+1): newline += f"//create module for MGS{str(idx)}\n" newline += f"MagicStreammerCore #(\n" newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" @@ -99,11 +106,11 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): newline += f" .M_AXI_TREADY(M{str(idx)}_AXI_TREADY),\n" newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST),\n" newline += f"//------ command --------\n" - newline += f" .storeReset(storeReset_{str(idx)}),\n" - newline += f" .loadReset(loadReset_{str(idx)}),\n" - newline += f" .storeInit(storeInit_{str(idx)}),\n" - newline += f" .loadInit(loadInit_{str(idx)}),\n" - newline += f" .finStore(finStore_{str(idx)}),\n" + newline += f" .storeReset (storeReset[{str(idx)}]),\n" + newline += f" .loadReset (loadReset [{str(idx)}]),\n" + newline += f" .storeInit (storeInit [{str(idx)}]),\n" + newline += f" .loadInit (loadInit [{str(idx)}]),\n" + newline += f" .finStore (finStore [{str(idx)}]),\n" newline += f"//------ debugging ------\n" newline += f" .dbg_state(dbg_state_{str(idx)}),\n" newline += f" .dbg_amt_store_bytes(dbg_amt_store_bytes_{str(idx)}),\n" From c1e24193a07bbb7fc6bc6973398db8dd29fc66ba Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 22 Aug 2025 21:01:09 +0200 Subject: [PATCH 34/70] add project builder tcl file copy --- .../board_support/mga_meta.tcl | 18 + .../board_support/zcu102/myDfxBackup.tcl | 773 ++++++++++++++++++ .../board_support/zcu102/project_builder.tcl | 770 +++++++++++++++++ .../vitis_unified_partial_writer/mgs_gen.py | 47 ++ 4 files changed, 1608 insertions(+) create mode 100644 hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl create mode 100644 hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl diff --git a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl new file mode 100644 index 0000000000..54abf15753 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl @@ -0,0 +1,18 @@ +variable HLS_CFG_AMT_MGS +set HLS_CFG_AMT_MGS VAL +variable HLS_CFG_MGS_INDEX +set HLS_CFG_MGS_INDEX VAL +variable HLS_CFG_BANK_IDX_WIDTH +set HLS_CFG_BANK_IDX_WIDTH VAL +variable HLS_CFG_MGS_WRAP_WIDTH +set HLS_CFG_MGS_WRAP_WIDTH VAL + + + + + + + + + + diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl new file mode 100644 index 0000000000..cbb6ac2581 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl @@ -0,0 +1,773 @@ +# Set the reference directory for source file relative paths (by default the value is script directory path) +set origin_dir "." + + +# Set the project name +set _xil_proj_name_ "dfx4ml" + +variable script_file +set script_file "dfx.tcl" + + + + +# Create project +create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xczu9eg-ffvb1156-2-e + +# Set the directory path for the new project +set proj_dir [get_property directory [current_project]] + +# Set project properties +set obj [current_project] + +set_property ip_repo_paths ../ips $obj +update_ip_catalog + +set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj + + +proc cr_bd_system {} { + + set design_name system + create_bd_design $design_name + + proc create_hier_cell_data_mover {parentCell nameHier amtMgs} { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + ############################################## + ##### Create pins ############################ + ############################################## + + ###### dma interface pin create + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_CTRL + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM + + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M0_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S0_AXI + + ###### mgs interface pin create + for {set i 1} {$i <= $amtMgs} {incr i} { + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M${i}_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S${i}_AXI + } + + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + create_bd_pin -dir I -from ${amtMgs} -to 0 storeReset + create_bd_pin -dir I -from ${amtMgs} -to 0 loadReset + create_bd_pin -dir I -from ${amtMgs} -to 0 storeInit + create_bd_pin -dir I -from ${amtMgs} -to 0 loadInit + create_bd_pin -dir O -from ${amtMgs} -to 0 finStore + + ############################################## + ##### Create instance ######################## + ############################################## + + ### create axi dma + 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 magic streamer group + set streamGrp_0 [ create_bd_cell -type ip -vlnv user.org:user:streamGrp:1.0 streamGrp_0 ] + + ############################################## + ##### Create connection ###################### + ############################################## + + + # Create interface connections + + #### only for dma + connect_bd_intf_net -intf_net axi_dma_0_M_AXIS_MM2S [get_bd_intf_pins M0_AXI ] [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] + connect_bd_intf_net -intf_net dfx_decoupler_4_s_intf_0 [get_bd_intf_pins S0_AXI ] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] + + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins M_AXI_MM2S ] [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins M_AXI_S2MM ] [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] + + + #### only for mgs + + for {set i 1} {$i <= $amtMgs} {incr i} { + connect_bd_intf_net -intf_net streamGrp_0_M${i}_AXI [get_bd_intf_pins M${i}_AXI] [get_bd_intf_pins streamGrp_0/M${i}_AXI] + connect_bd_intf_net -intf_net streamGrp_0_S${i}_AXI [get_bd_intf_pins S${i}_AXI] [get_bd_intf_pins streamGrp_0/S${i}_AXI] + } + + + connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins S_AXI_DMA_CTRL] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + + + #### Create port connections + connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins loadInit] [get_bd_pins streamGrp_0/loadInit] + connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins loadReset] [get_bd_pins streamGrp_0/loadReset] + connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins storeInit] [get_bd_pins streamGrp_0/storeInit] + connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins storeReset] [get_bd_pins streamGrp_0/storeReset] + connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins streamGrp_0/finStoreProxyDma] + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins streamGrp_0/nreset] [get_bd_pins axi_dma_0/axi_resetn] + connect_bd_net -net streamGrp_0_finStore [get_bd_pins streamGrp_0/finStore] [get_bd_pins finStore] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins streamGrp_0/clk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] + + #### return to old instance + current_bd_instance $oldCurInst + + + } + + proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs amtMgsIdx bank1Idx} { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + ############################################## + ##### Create pins ############################ + ############################################## + + ####### dfx controller + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DFX_CTRL + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DFX_LOADER + ####### magic sequencer + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DMA_CTRL + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_MGQ_CTRL + ####### interrupt controler + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_INTR_CTRL + + + # Create pins + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreReset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadReset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreInit + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadInit + create_bd_pin -dir I -from ${amtMgs} -to 0 mgsFinExec + create_bd_pin -dir O irq + create_bd_pin -dir O decup + + ############################################## + ##### Create instance ######################## + ############################################## + + set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeq:1.0 MagicSeq_0 ] + set_property -dict [list \ + CONFIG.BANK1_INDEX_WIDTH $bank1Idx \ + CONFIG.BANK0_CNT_WIDTH $bank1Idx \ + CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgsIdx+1}] \ + CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgsIdx+1}] \ + ] $MagicSeq_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: xlconstant_0 (magic seq) ) _1(dfx_controller), and set properties + set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ] + set_property CONFIG.CONST_VAL {0} $xlconstant_0 + set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ] + + + # Create instance: dfx_controller_0, and set properties + set dfx_controller_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_controller:1.0 dfx_controller_0 ] + + # build RM section dynamically + # Build RM list + set rm_list {} + set num_rms [expr {2**$bank1Idx}] + for {set i 0} {$i < [expr {2**$bank1Idx}]} {incr i} { + lappend rm_list "RM_$i {ID $i NAME RM_$i BS {0 {ID 0 ADDR 0 SIZE 0 CLEAR 0}} RESET_REQUIRED low}" + } + + # Convert to proper string + set rm_block [join $rm_list " "] + + set_property -dict [list \ + CONFIG.ALL_PARAMS [format {HAS_AXI_LITE_IF 1 \ + RESET_ACTIVE_LEVEL 0 \ + CP_FIFO_DEPTH 32 \ + CP_FIFO_TYPE lutram \ + CDC_STAGES 6 \ + VS { \ + VS_0 {ID 0 NAME VS_0 \ + RM { %s } \ + POR_RM RM_0 NUM_HW_TRIGGERS %d} \ + } \ + CP_FAMILY ultrascale_plus DIRTY 0} \ + $rm_block $num_rms] \ + CONFIG.GUI_VS_NUM_HW_TRIGGERS $num_rms \ + CONFIG.GUI_VS_NUM_RMS_ALLOCATED [expr {2**$bank1Idx}] \ + ] $dfx_controller_0 + + + # Create instance: icapWrap_0, and set properties + set icapWrap_0 [ create_bd_cell -type ip -vlnv user.org:user:icapWrap:1.0 icapWrap_0 ] + + ############################################## + ##### Create connection ###################### + ############################################## + + + # Create interface connections + + ##### connect DFX controller + connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins S_AXI_DFX_CTRL ] [get_bd_intf_pins dfx_controller_0/s_axi_reg] + connect_bd_intf_net -intf_net Conn2 [get_bd_intf_pins M_AXI_DFX_LOADER ] [get_bd_intf_pins dfx_controller_0/M_AXI_MEM] + connect_bd_intf_net -intf_net dfx_controller_0_ICAP [get_bd_intf_pins dfx_controller_0/ICAP] [get_bd_intf_pins icapWrap_0/ICAP] + ##### connect to magic sequencer + connect_bd_intf_net -intf_net MagicSeq_0_M_AXI [get_bd_intf_pins M_AXI_DMA_CTRL] [get_bd_intf_pins MagicSeq_0/M_AXI] + connect_bd_intf_net -intf_net axi_interconnect_1_M02_AXI [get_bd_intf_pins S_AXI_MGQ_CTRL] [get_bd_intf_pins MagicSeq_0/S_AXI] + ##### connect to interrupt controller + connect_bd_intf_net -intf_net axi_interconnect_1_M00_AXI [get_bd_intf_pins S_AXI_INTR_CTRL] [get_bd_intf_pins axi_intc_0/s_axi] + + + + # Create port connections + + ##### magic sequencer control + connect_bd_net -net MagicSeq_0_hw_intr [get_bd_pins MagicSeq_0/hw_intr] [get_bd_pins axi_intc_0/intr ] + connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins mgsLoadInit ] [get_bd_pins MagicSeq_0/slaveMgsLoadInit] + connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins mgsLoadReset ] [get_bd_pins MagicSeq_0/slaveMgsLoadReset] + connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins mgsStoreInit ] [get_bd_pins MagicSeq_0/slaveMgsStoreInit] + connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins mgsStoreReset ] [get_bd_pins MagicSeq_0/slaveMgsStoreReset] + connect_bd_net -net streamGrp_0_finStore [get_bd_pins mgsFinExec ] [get_bd_pins MagicSeq_0/mgsFinExec] + ##### interrupt controller connections + connect_bd_net -net axi_intc_0_irq [get_bd_pins irq] [get_bd_pins axi_intc_0/irq] + ##### magic sequencer dfx controller connections + connect_bd_net -net MagicSeq_0_slaveReprog [get_bd_pins MagicSeq_0/slaveReprog] [get_bd_pins dfx_controller_0/vsm_VS_0_hw_triggers] + connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_reset [get_bd_pins MagicSeq_0/nslaveReset] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_reset] + ##### dfx controller control connections + connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_decouple [get_bd_pins decup] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_decouple] + ##### connect constant values + connect_bd_net -net xlconstant_0_dout [get_bd_pins xlconstant_0/dout] [get_bd_pins MagicSeq_0/hw_intr_clear] [get_bd_pins MagicSeq_0/hw_ctrl_start] + connect_bd_net -net xlconstant_1_dout [get_bd_pins xlconstant_1/dout] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_shutdown_ack] + ##### reset + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins MagicSeq_0/reset] [get_bd_pins dfx_controller_0/icap_reset] [get_bd_pins dfx_controller_0/reset] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins MagicSeq_0/clk] [get_bd_pins dfx_controller_0/icap_clk] [get_bd_pins dfx_controller_0/clk] [get_bd_pins icapWrap_0/CLK] + + #### return to old instance + current_bd_instance $oldCurInst + + + } + + proc create_hier_cell_dfx_decup { parentCell nameHier amtMgs } { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + # Create pins + create_bd_pin -dir I decouple + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + + for {set i 0} {$i <= $amtMgs} {incr i} { + ### s connect to PR + ### rp connect to mgs + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 s_intf_${i} + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 rp_intf_${i} + + set dfx_decoupler_inst [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_decoupler:1.0 dfx_decoupler_${i} ] + set_property CONFIG.ALL_PARAMS {INTF {intf_0 {ID 0 VLNV xilinx.com:interface:axis_rtl:1.0}} ALWAYS_HAVE_AXI_CLK 1 HAS_SIGNAL_STATUS 0} [get_bd_cells dfx_decoupler_${i}] + + connect_bd_intf_net -intf_net dfx_decoupler_${i}_s [get_bd_intf_pins s_intf_${i} ] [get_bd_intf_pins dfx_decoupler_${i}/s_intf_0] + connect_bd_intf_net -intf_net dfx_decoupler_${i}_rp [get_bd_intf_pins rp_intf_${i}] [get_bd_intf_pins dfx_decoupler_${i}/rp_intf_0] + + connect_bd_net -net decupNet [get_bd_pins decouple] [get_bd_pins dfx_decoupler_${i}/decouple] + connect_bd_net -net clkNet [get_bd_pins clk ] [get_bd_pins dfx_decoupler_${i}/intf_0_aclk] + connect_bd_net -net nresetNet [get_bd_pins nreset ] [get_bd_pins dfx_decoupler_${i}/intf_0_arstn] + } + + + #### return to old instance + current_bd_instance $oldCurInst + + + + + } + + proc create_hier_cell_dfx_par { parentCell nameHier amtMgs dataWidths } { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + # Create pins + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + + for {set i 0} {$i <= $amtMgs} {incr i} { + ### s connect to PR + ### rp connect to mgs + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXI_${i} + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXI_${i} + + set DummyStreamMaster_${i} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${i} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamMaster_${i}] + set DummyStreamSlave_${i} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${i} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamSlave_${i}] + + + connect_bd_intf_net -intf_net DummyStreamMaster_${i} [get_bd_intf_pins M_AXI_${i} ] [get_bd_intf_pins DummyStreamMaster_${i}/M_AXI] + connect_bd_intf_net -intf_net DummyStreamSlave_${i} [get_bd_intf_pins S_AXI_${i} ] [get_bd_intf_pins DummyStreamSlave_${i}/S_AXI] + + connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${i}/clk] + connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${i}/reset] + connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${i}/clk] + connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${i}/reset] + } + + + #### return to old instance + current_bd_instance $oldCurInst + + } + + # set parentObj "" + # set parentType [get_property TYPE $parentObj] + + # set oldCurInst [current_bd_instance .] + + # current_bd_instance $parentObj + + + # ########################### + # ###### build the ip ####### + # ########################### + + # ###### set Cpu + # 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_INPUT_TYPE {cmos} \ + # CONFIG.PSU_MIO_22_POLARITY {Default} \ + # CONFIG.PSU_MIO_23_POLARITY {Default} \ + # CONFIG.PSU_MIO_26_POLARITY {Default} \ + # CONFIG.PSU_MIO_32_POLARITY {Default} \ + # CONFIG.PSU_MIO_33_POLARITY {Default} \ + # CONFIG.PSU_MIO_35_POLARITY {Default} \ + # CONFIG.PSU_MIO_36_POLARITY {Default} \ + # CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ + # MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ + # CONFIG.PSU__PMU__GPO1__ENABLE {0} \ + # CONFIG.PSU__PMU__GPO2__ENABLE {1} \ + # CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ + # CONFIG.PSU__PMU__GPO2__POLARITY {high} \ + # CONFIG.PSU__PMU__GPO3__ENABLE {0} \ + # 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ + # CONFIG.PSU__USE__M_AXI_GP2 {0} \ + # CONFIG.PSU__USE__S_AXI_GP0 {1} \ + # CONFIG.PSU__USE__S_AXI_GP1 {1} \ + # ] $zynq_ultra_ps_e_0 + + ###### set main control + set axi_interconnect_main_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_main_control ] + set_property CONFIG.NUM_MI {3} $axi_interconnect_main_control + + + ###### set dma control interconnect + set axi_interconnect_dma_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_dma_control ] + set_property -dict [list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {2} \ + ] $axi_interconnect_dma_control + + + ###### set smart memory reader interconnect + + # Create instance: smartconnect_reader, and set properties + set smartconnect_reader [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_reader] + + # Create instance: smartconnect_writer, and set properties + set smartconnect_writer [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_writer ] + set_property CONFIG.NUM_SI {1} $smartconnect_writer + + # Create instance: reseter + set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] + + + set AMT_MGS 2 + set MGS_IDX 2 + set BANK_IDX_WIDTH 2 + set MGS_WIDTH {32 64 128} + + + create_hier_cell_data_mover [current_bd_instance .] data_mover $AMT_MGS + create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $AMT_MGS $MGS_IDX $BANK_IDX_WIDTH + create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_s $AMT_MGS + create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $AMT_MGS + create_hier_cell_dfx_par [current_bd_instance .] dfx_par $AMT_MGS $MGS_WIDTH + + +} + + +cr_bd_system \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl new file mode 100644 index 0000000000..0fde3835d1 --- /dev/null +++ b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl @@ -0,0 +1,770 @@ +# Set the reference directory for source file relative paths (by default the value is script directory path) +set origin_dir "." + + +# Set the project name +set _xil_proj_name_ "dfx4ml" + +variable script_file +set script_file "project_builder.tcl" + +# Create project +create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xczu9eg-ffvb1156-2-e + +# Set the directory path for the new project +set proj_dir [get_property directory [current_project]] + +# Set project properties +set obj [current_project] + +set_property ip_repo_paths ../ips $obj +update_ip_catalog + +set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj + +source mgs_meta + +proc cr_bd_system {} { + + set design_name system + create_bd_design $design_name + + proc create_hier_cell_data_mover {parentCell nameHier amtMgs} { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + ############################################## + ##### Create pins ############################ + ############################################## + + ###### dma interface pin create + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_CTRL + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM + + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M0_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S0_AXI + + ###### mgs interface pin create + for {set i 1} {$i <= $amtMgs} {incr i} { + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M${i}_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S${i}_AXI + } + + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + create_bd_pin -dir I -from ${amtMgs} -to 0 storeReset + create_bd_pin -dir I -from ${amtMgs} -to 0 loadReset + create_bd_pin -dir I -from ${amtMgs} -to 0 storeInit + create_bd_pin -dir I -from ${amtMgs} -to 0 loadInit + create_bd_pin -dir O -from ${amtMgs} -to 0 finStore + + ############################################## + ##### Create instance ######################## + ############################################## + + ### create axi dma + 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 magic streamer group + set streamGrp_0 [ create_bd_cell -type ip -vlnv user.org:user:streamGrp:1.0 streamGrp_0 ] + + ############################################## + ##### Create connection ###################### + ############################################## + + + # Create interface connections + + #### only for dma + connect_bd_intf_net -intf_net axi_dma_0_M_AXIS_MM2S [get_bd_intf_pins M0_AXI ] [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] + connect_bd_intf_net -intf_net dfx_decoupler_4_s_intf_0 [get_bd_intf_pins S0_AXI ] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] + + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins M_AXI_MM2S ] [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins M_AXI_S2MM ] [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] + + + #### only for mgs + + for {set i 1} {$i <= $amtMgs} {incr i} { + connect_bd_intf_net -intf_net streamGrp_0_M${i}_AXI [get_bd_intf_pins M${i}_AXI] [get_bd_intf_pins streamGrp_0/M${i}_AXI] + connect_bd_intf_net -intf_net streamGrp_0_S${i}_AXI [get_bd_intf_pins S${i}_AXI] [get_bd_intf_pins streamGrp_0/S${i}_AXI] + } + + + connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins S_AXI_DMA_CTRL] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + + + #### Create port connections + connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins loadInit] [get_bd_pins streamGrp_0/loadInit] + connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins loadReset] [get_bd_pins streamGrp_0/loadReset] + connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins storeInit] [get_bd_pins streamGrp_0/storeInit] + connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins storeReset] [get_bd_pins streamGrp_0/storeReset] + connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins streamGrp_0/finStoreProxyDma] + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins streamGrp_0/nreset] [get_bd_pins axi_dma_0/axi_resetn] + connect_bd_net -net streamGrp_0_finStore [get_bd_pins streamGrp_0/finStore] [get_bd_pins finStore] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins streamGrp_0/clk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] + + #### return to old instance + current_bd_instance $oldCurInst + + + } + + proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs amtMgsIdx bank1Idx} { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + ############################################## + ##### Create pins ############################ + ############################################## + + ####### dfx controller + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DFX_CTRL + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DFX_LOADER + ####### magic sequencer + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DMA_CTRL + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_MGQ_CTRL + ####### interrupt controler + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_INTR_CTRL + + + # Create pins + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreReset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadReset + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreInit + create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadInit + create_bd_pin -dir I -from ${amtMgs} -to 0 mgsFinExec + create_bd_pin -dir O irq + create_bd_pin -dir O decup + + ############################################## + ##### Create instance ######################## + ############################################## + + set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeq:1.0 MagicSeq_0 ] + set_property -dict [list \ + CONFIG.BANK1_INDEX_WIDTH $bank1Idx \ + CONFIG.BANK0_CNT_WIDTH $bank1Idx \ + CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgsIdx+1}] \ + CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgsIdx+1}] \ + ] $MagicSeq_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: xlconstant_0 (magic seq) ) _1(dfx_controller), and set properties + set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ] + set_property CONFIG.CONST_VAL {0} $xlconstant_0 + set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ] + + + # Create instance: dfx_controller_0, and set properties + set dfx_controller_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_controller:1.0 dfx_controller_0 ] + + # build RM section dynamically + # Build RM list + set rm_list {} + set num_rms [expr {2**$bank1Idx}] + for {set i 0} {$i < [expr {2**$bank1Idx}]} {incr i} { + lappend rm_list "RM_$i {ID $i NAME RM_$i BS {0 {ID 0 ADDR 0 SIZE 0 CLEAR 0}} RESET_REQUIRED low}" + } + + # Convert to proper string + set rm_block [join $rm_list " "] + + set_property -dict [list \ + CONFIG.ALL_PARAMS [format {HAS_AXI_LITE_IF 1 \ + RESET_ACTIVE_LEVEL 0 \ + CP_FIFO_DEPTH 32 \ + CP_FIFO_TYPE lutram \ + CDC_STAGES 6 \ + VS { \ + VS_0 {ID 0 NAME VS_0 \ + RM { %s } \ + POR_RM RM_0 NUM_HW_TRIGGERS %d} \ + } \ + CP_FAMILY ultrascale_plus DIRTY 0} \ + $rm_block $num_rms] \ + CONFIG.GUI_VS_NUM_HW_TRIGGERS $num_rms \ + CONFIG.GUI_VS_NUM_RMS_ALLOCATED [expr {2**$bank1Idx}] \ + ] $dfx_controller_0 + + + # Create instance: icapWrap_0, and set properties + set icapWrap_0 [ create_bd_cell -type ip -vlnv user.org:user:icapWrap:1.0 icapWrap_0 ] + + ############################################## + ##### Create connection ###################### + ############################################## + + + # Create interface connections + + ##### connect DFX controller + connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins S_AXI_DFX_CTRL ] [get_bd_intf_pins dfx_controller_0/s_axi_reg] + connect_bd_intf_net -intf_net Conn2 [get_bd_intf_pins M_AXI_DFX_LOADER ] [get_bd_intf_pins dfx_controller_0/M_AXI_MEM] + connect_bd_intf_net -intf_net dfx_controller_0_ICAP [get_bd_intf_pins dfx_controller_0/ICAP] [get_bd_intf_pins icapWrap_0/ICAP] + ##### connect to magic sequencer + connect_bd_intf_net -intf_net MagicSeq_0_M_AXI [get_bd_intf_pins M_AXI_DMA_CTRL] [get_bd_intf_pins MagicSeq_0/M_AXI] + connect_bd_intf_net -intf_net axi_interconnect_1_M02_AXI [get_bd_intf_pins S_AXI_MGQ_CTRL] [get_bd_intf_pins MagicSeq_0/S_AXI] + ##### connect to interrupt controller + connect_bd_intf_net -intf_net axi_interconnect_1_M00_AXI [get_bd_intf_pins S_AXI_INTR_CTRL] [get_bd_intf_pins axi_intc_0/s_axi] + + + + # Create port connections + + ##### magic sequencer control + connect_bd_net -net MagicSeq_0_hw_intr [get_bd_pins MagicSeq_0/hw_intr] [get_bd_pins axi_intc_0/intr ] + connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins mgsLoadInit ] [get_bd_pins MagicSeq_0/slaveMgsLoadInit] + connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins mgsLoadReset ] [get_bd_pins MagicSeq_0/slaveMgsLoadReset] + connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins mgsStoreInit ] [get_bd_pins MagicSeq_0/slaveMgsStoreInit] + connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins mgsStoreReset ] [get_bd_pins MagicSeq_0/slaveMgsStoreReset] + connect_bd_net -net streamGrp_0_finStore [get_bd_pins mgsFinExec ] [get_bd_pins MagicSeq_0/mgsFinExec] + ##### interrupt controller connections + connect_bd_net -net axi_intc_0_irq [get_bd_pins irq] [get_bd_pins axi_intc_0/irq] + ##### magic sequencer dfx controller connections + connect_bd_net -net MagicSeq_0_slaveReprog [get_bd_pins MagicSeq_0/slaveReprog] [get_bd_pins dfx_controller_0/vsm_VS_0_hw_triggers] + connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_reset [get_bd_pins MagicSeq_0/nslaveReset] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_reset] + ##### dfx controller control connections + connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_decouple [get_bd_pins decup] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_decouple] + ##### connect constant values + connect_bd_net -net xlconstant_0_dout [get_bd_pins xlconstant_0/dout] [get_bd_pins MagicSeq_0/hw_intr_clear] [get_bd_pins MagicSeq_0/hw_ctrl_start] + connect_bd_net -net xlconstant_1_dout [get_bd_pins xlconstant_1/dout] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_shutdown_ack] + ##### reset + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins MagicSeq_0/reset] [get_bd_pins dfx_controller_0/icap_reset] [get_bd_pins dfx_controller_0/reset] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins MagicSeq_0/clk] [get_bd_pins dfx_controller_0/icap_clk] [get_bd_pins dfx_controller_0/clk] [get_bd_pins icapWrap_0/CLK] + + #### return to old instance + current_bd_instance $oldCurInst + + + } + + proc create_hier_cell_dfx_decup { parentCell nameHier amtMgs } { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + # Create pins + create_bd_pin -dir I decouple + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + + for {set i 0} {$i <= $amtMgs} {incr i} { + ### s connect to PR + ### rp connect to mgs + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 s_intf_${i} + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 rp_intf_${i} + + set dfx_decoupler_inst [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_decoupler:1.0 dfx_decoupler_${i} ] + set_property CONFIG.ALL_PARAMS {INTF {intf_0 {ID 0 VLNV xilinx.com:interface:axis_rtl:1.0}} ALWAYS_HAVE_AXI_CLK 1 HAS_SIGNAL_STATUS 0} [get_bd_cells dfx_decoupler_${i}] + + connect_bd_intf_net -intf_net dfx_decoupler_${i}_s [get_bd_intf_pins s_intf_${i} ] [get_bd_intf_pins dfx_decoupler_${i}/s_intf_0] + connect_bd_intf_net -intf_net dfx_decoupler_${i}_rp [get_bd_intf_pins rp_intf_${i}] [get_bd_intf_pins dfx_decoupler_${i}/rp_intf_0] + + connect_bd_net -net decupNet [get_bd_pins decouple] [get_bd_pins dfx_decoupler_${i}/decouple] + connect_bd_net -net clkNet [get_bd_pins clk ] [get_bd_pins dfx_decoupler_${i}/intf_0_aclk] + connect_bd_net -net nresetNet [get_bd_pins nreset ] [get_bd_pins dfx_decoupler_${i}/intf_0_arstn] + } + + + #### return to old instance + current_bd_instance $oldCurInst + + + + + } + + proc create_hier_cell_dfx_par { parentCell nameHier amtMgs dataWidths } { + + #### old system obj is cell and oldCurInstr is path + set parentObj [get_bd_cells $parentCell] + set oldCurInst [current_bd_instance .] + + set hierObj [create_bd_cell -type hier $nameHier] + current_bd_instance $hierObj + + # Create pins + create_bd_pin -dir I -type clk clk + create_bd_pin -dir I -type rst nreset + + for {set i 0} {$i <= $amtMgs} {incr i} { + ### s connect to PR + ### rp connect to mgs + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXI_${i} + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXI_${i} + + set DummyStreamMaster_${i} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${i} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamMaster_${i}] + set DummyStreamSlave_${i} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${i} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamSlave_${i}] + + + connect_bd_intf_net -intf_net DummyStreamMaster_${i} [get_bd_intf_pins M_AXI_${i} ] [get_bd_intf_pins DummyStreamMaster_${i}/M_AXI] + connect_bd_intf_net -intf_net DummyStreamSlave_${i} [get_bd_intf_pins S_AXI_${i} ] [get_bd_intf_pins DummyStreamSlave_${i}/S_AXI] + + connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${i}/clk] + connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${i}/reset] + connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${i}/clk] + connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${i}/reset] + } + + + #### return to old instance + current_bd_instance $oldCurInst + + } + + # set parentObj "" + # set parentType [get_property TYPE $parentObj] + + # set oldCurInst [current_bd_instance .] + + # current_bd_instance $parentObj + + + # ########################### + # ###### build the ip ####### + # ########################### + + # ###### set Cpu + # 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_INPUT_TYPE {cmos} \ + # CONFIG.PSU_MIO_22_POLARITY {Default} \ + # CONFIG.PSU_MIO_23_POLARITY {Default} \ + # CONFIG.PSU_MIO_26_POLARITY {Default} \ + # CONFIG.PSU_MIO_32_POLARITY {Default} \ + # CONFIG.PSU_MIO_33_POLARITY {Default} \ + # CONFIG.PSU_MIO_35_POLARITY {Default} \ + # CONFIG.PSU_MIO_36_POLARITY {Default} \ + # CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ + # MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ + # CONFIG.PSU__PMU__GPO1__ENABLE {0} \ + # CONFIG.PSU__PMU__GPO2__ENABLE {1} \ + # CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ + # CONFIG.PSU__PMU__GPO2__POLARITY {high} \ + # CONFIG.PSU__PMU__GPO3__ENABLE {0} \ + # 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ + # CONFIG.PSU__USE__M_AXI_GP2 {0} \ + # CONFIG.PSU__USE__S_AXI_GP0 {1} \ + # CONFIG.PSU__USE__S_AXI_GP1 {1} \ + # ] $zynq_ultra_ps_e_0 + + ###### set main control + set axi_interconnect_main_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_main_control ] + set_property CONFIG.NUM_MI {3} $axi_interconnect_main_control + + + ###### set dma control interconnect + set axi_interconnect_dma_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_dma_control ] + set_property -dict [list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {2} \ + ] $axi_interconnect_dma_control + + + ###### set smart memory reader interconnect + + # Create instance: smartconnect_reader, and set properties + set smartconnect_reader [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_reader] + + # Create instance: smartconnect_writer, and set properties + set smartconnect_writer [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_writer ] + set_property CONFIG.NUM_SI {1} $smartconnect_writer + + # Create instance: reseter + set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] + + + set AMT_MGS 2 + set MGS_IDX 2 + set BANK_IDX_WIDTH 2 + set MGS_WIDTH {32 64 128} + + + create_hier_cell_data_mover [current_bd_instance .] data_mover $HLS_CFG_AMT_MGS + create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $HLS_CFG_AMT_MGS $HLS_CFG_MGS_INDEX $HLS_CFG_BANK_IDX_WIDTH + create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_s $HLS_CFG_AMT_MGS + create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $HLS_CFG_AMT_MGS + create_hier_cell_dfx_par [current_bd_instance .] dfx_par $HLS_CFG_AMT_MGS $HLS_CFG_MGS_WRAP_WIDTH + +} + + +cr_bd_system \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index f6466b987b..45dea3503f 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -2,12 +2,59 @@ import shutil import stat from pathlib import Path +import math from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta class VitisUnifiedPartial_MagicArchGen(): + def gen_vivado_project(self, meta: VitisUnifiedWriterMeta, model, board_name = "zcu102"): + filedir = os.path.dirname(os.path.abspath(__file__)) + + vivado_project_des_folder_path = f'{model.config.get_output_dir()}/vivado_project' + + if not os.path.exists(vivado_project_des_folder_path): + os.makedirs(vivado_project_des_folder_path) + + #### copy project building script + vivado_project_src_script_path = os.path.join(filedir, + f'../../templates/vitis_unified_partial/board_support/{board_name}/project_builder.tcl') + des_project_script_path = f'{vivado_project_des_folder_path}/project_builder.tcl' + shutil.copyfile(vivado_project_src_script_path, des_project_script_path) + + #### copy mgs argument + vivado_project_src_meta_arg_path = os.path.join(filedir, + f'../../templates/vitis_unified_partial/board_support/mga_meta.tcl') + des_projectscript_meta_arg_path = f'{vivado_project_des_folder_path}/mga_meta.tcl' + + fin = open(vivado_project_src_meta_arg_path, 'r') + fout = open(des_projectscript_meta_arg_path, 'w') + + meta_list = meta.vitis_unified_config.get_mgs_meta_list() + amt_subGraph = meta.vitis_unified_config.get_amt_graph() + + meta_idx_width = str(max(0, int(math.ceil(math.log2(len(meta_list)))))) + graph_idx_width = str(max(0, int(math.ceil(math.log2(amt_subGraph))))) + + for line in fin.readlines(): + if "HLS_CFG_AMT_MGS" in line: + line = line.replace("VAL", str(len(meta_list))) + if "HLS_CFG_MGS_INDEX" in line: + line = line.replace("VAL", meta_idx_width) + if "HLS_CFG_BANK_IDX_WIDTH" in line: + line = line.replace("VAL", graph_idx_width) + if "HLS_CFG_MGS_WRAP_WIDTH" in line: + line = line.replace("VAL", "{ "+ ", ".join([str(width) for width, *_ in meta_list]) + " }") + fout.write(line) + + fin.close() + fout.close() + + + + + @classmethod def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): From ccd3d2aee9ac7f2f44ccb6312b2c673fdb763513 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 23 Aug 2025 17:37:30 +0200 Subject: [PATCH 35/70] integrating the zcu102 synthesis code --- .../vitis_unified/vitis_unified_config.py | 1 + .../vitis_unified_partial_backend.py | 13 +- .../vitis_unified_partial_config.py | 3 +- .../board_support/mga_meta.tcl | 2 - .../board_support/zcu102/myDfxBackup.tcl | 773 ------------------ .../board_support/zcu102/project_builder.tcl | 763 ++++++++--------- .../ips/magic_streamer_grp_prj/composer.tcl | 5 +- .../vitis_unified_partial_writer/__init__.py | 3 +- .../vitis_unified_partial_writer/mgs_gen.py | 19 +- 9 files changed, 412 insertions(+), 1170 deletions(-) delete mode 100644 hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index d47a5be59e..7f78b8d69a 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -8,6 +8,7 @@ class VitisUnifiedConfig: def __init__(self, config, model_inputs, model_outputs): self.config = config.config + self.board = "zcu102" # self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') # self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) # if self.board in self.supported_boards.keys(): diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index eb54f9bf2a..6c2ae59579 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -37,15 +37,19 @@ def build( ##### do magic streamer generation if compose_streamers: + #### generate magic sequencer wrapper magic_stream_grp_ip_prj = f'{model.config.get_output_dir()}/ips/magic_streamer_grp_prj' self.run_term_command(model, "magic_streamer_ip_generation", "vivado -mode gui -source composer.tcl", log_to_stdout, magic_stream_grp_ip_prj ) - - - pass + #### generate vivado project + magic_arch_prj = f"{model.config.get_output_dir()}/vivado_project" + self.run_term_command(model, + "magic_streamer_arch_generation", + "vivado -mode gui -source project_builder.tcl", log_to_stdout, + magic_arch_prj) # super().build( # model, @@ -79,6 +83,7 @@ def create_initial_config( input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream output_interim_type='io_stream', init_mgs_meta=None, + init_amt_graph=3, **_ ): @@ -102,7 +107,7 @@ def create_initial_config( ) config['MultiGraphConfig'] = {} - config['MultiGraphConfig']['amtGraph'] = -1 # it should be set by the multigraph system + config['MultiGraphConfig']['amtGraph'] = init_amt_graph # it should be set by the multigraph system config['MultiGraphConfig']['graphIdx'] = -1 # -1 means unset yet or it is multigraph stitcher print(f"mgs initial is set to {init_mgs_meta}") config['MultiGraphConfig']['MgsMeta'] = init_mgs_meta if init_mgs_meta is not None else [] #### it should be only used for stitcher diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py index 593ffa6663..3929c95976 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py @@ -24,7 +24,8 @@ def __init__(self, config, model_inputs, model_outputs): self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('MgsMeta', None) - + def get_dma_size(self): + return 32 def is_free_interim_input(self): return self.free_interim_input diff --git a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl index 54abf15753..c9ac26186a 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl @@ -1,7 +1,5 @@ variable HLS_CFG_AMT_MGS set HLS_CFG_AMT_MGS VAL -variable HLS_CFG_MGS_INDEX -set HLS_CFG_MGS_INDEX VAL variable HLS_CFG_BANK_IDX_WIDTH set HLS_CFG_BANK_IDX_WIDTH VAL variable HLS_CFG_MGS_WRAP_WIDTH diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl deleted file mode 100644 index cbb6ac2581..0000000000 --- a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/myDfxBackup.tcl +++ /dev/null @@ -1,773 +0,0 @@ -# Set the reference directory for source file relative paths (by default the value is script directory path) -set origin_dir "." - - -# Set the project name -set _xil_proj_name_ "dfx4ml" - -variable script_file -set script_file "dfx.tcl" - - - - -# Create project -create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xczu9eg-ffvb1156-2-e - -# Set the directory path for the new project -set proj_dir [get_property directory [current_project]] - -# Set project properties -set obj [current_project] - -set_property ip_repo_paths ../ips $obj -update_ip_catalog - -set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj - - -proc cr_bd_system {} { - - set design_name system - create_bd_design $design_name - - proc create_hier_cell_data_mover {parentCell nameHier amtMgs} { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - ############################################## - ##### Create pins ############################ - ############################################## - - ###### dma interface pin create - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_CTRL - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM - - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M0_AXI - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S0_AXI - - ###### mgs interface pin create - for {set i 1} {$i <= $amtMgs} {incr i} { - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M${i}_AXI - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S${i}_AXI - } - - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - create_bd_pin -dir I -from ${amtMgs} -to 0 storeReset - create_bd_pin -dir I -from ${amtMgs} -to 0 loadReset - create_bd_pin -dir I -from ${amtMgs} -to 0 storeInit - create_bd_pin -dir I -from ${amtMgs} -to 0 loadInit - create_bd_pin -dir O -from ${amtMgs} -to 0 finStore - - ############################################## - ##### Create instance ######################## - ############################################## - - ### create axi dma - 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 magic streamer group - set streamGrp_0 [ create_bd_cell -type ip -vlnv user.org:user:streamGrp:1.0 streamGrp_0 ] - - ############################################## - ##### Create connection ###################### - ############################################## - - - # Create interface connections - - #### only for dma - connect_bd_intf_net -intf_net axi_dma_0_M_AXIS_MM2S [get_bd_intf_pins M0_AXI ] [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] - connect_bd_intf_net -intf_net dfx_decoupler_4_s_intf_0 [get_bd_intf_pins S0_AXI ] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] - - connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins M_AXI_MM2S ] [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] - connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins M_AXI_S2MM ] [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] - - - #### only for mgs - - for {set i 1} {$i <= $amtMgs} {incr i} { - connect_bd_intf_net -intf_net streamGrp_0_M${i}_AXI [get_bd_intf_pins M${i}_AXI] [get_bd_intf_pins streamGrp_0/M${i}_AXI] - connect_bd_intf_net -intf_net streamGrp_0_S${i}_AXI [get_bd_intf_pins S${i}_AXI] [get_bd_intf_pins streamGrp_0/S${i}_AXI] - } - - - connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins S_AXI_DMA_CTRL] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] - - - #### Create port connections - connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins loadInit] [get_bd_pins streamGrp_0/loadInit] - connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins loadReset] [get_bd_pins streamGrp_0/loadReset] - connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins storeInit] [get_bd_pins streamGrp_0/storeInit] - connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins storeReset] [get_bd_pins streamGrp_0/storeReset] - connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins streamGrp_0/finStoreProxyDma] - connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins streamGrp_0/nreset] [get_bd_pins axi_dma_0/axi_resetn] - connect_bd_net -net streamGrp_0_finStore [get_bd_pins streamGrp_0/finStore] [get_bd_pins finStore] - connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins streamGrp_0/clk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] - - #### return to old instance - current_bd_instance $oldCurInst - - - } - - proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs amtMgsIdx bank1Idx} { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - ############################################## - ##### Create pins ############################ - ############################################## - - ####### dfx controller - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DFX_CTRL - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DFX_LOADER - ####### magic sequencer - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DMA_CTRL - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_MGQ_CTRL - ####### interrupt controler - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_INTR_CTRL - - - # Create pins - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreReset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadReset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreInit - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadInit - create_bd_pin -dir I -from ${amtMgs} -to 0 mgsFinExec - create_bd_pin -dir O irq - create_bd_pin -dir O decup - - ############################################## - ##### Create instance ######################## - ############################################## - - set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeq:1.0 MagicSeq_0 ] - set_property -dict [list \ - CONFIG.BANK1_INDEX_WIDTH $bank1Idx \ - CONFIG.BANK0_CNT_WIDTH $bank1Idx \ - CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgsIdx+1}] \ - CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgsIdx+1}] \ - ] $MagicSeq_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: xlconstant_0 (magic seq) ) _1(dfx_controller), and set properties - set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ] - set_property CONFIG.CONST_VAL {0} $xlconstant_0 - set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ] - - - # Create instance: dfx_controller_0, and set properties - set dfx_controller_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_controller:1.0 dfx_controller_0 ] - - # build RM section dynamically - # Build RM list - set rm_list {} - set num_rms [expr {2**$bank1Idx}] - for {set i 0} {$i < [expr {2**$bank1Idx}]} {incr i} { - lappend rm_list "RM_$i {ID $i NAME RM_$i BS {0 {ID 0 ADDR 0 SIZE 0 CLEAR 0}} RESET_REQUIRED low}" - } - - # Convert to proper string - set rm_block [join $rm_list " "] - - set_property -dict [list \ - CONFIG.ALL_PARAMS [format {HAS_AXI_LITE_IF 1 \ - RESET_ACTIVE_LEVEL 0 \ - CP_FIFO_DEPTH 32 \ - CP_FIFO_TYPE lutram \ - CDC_STAGES 6 \ - VS { \ - VS_0 {ID 0 NAME VS_0 \ - RM { %s } \ - POR_RM RM_0 NUM_HW_TRIGGERS %d} \ - } \ - CP_FAMILY ultrascale_plus DIRTY 0} \ - $rm_block $num_rms] \ - CONFIG.GUI_VS_NUM_HW_TRIGGERS $num_rms \ - CONFIG.GUI_VS_NUM_RMS_ALLOCATED [expr {2**$bank1Idx}] \ - ] $dfx_controller_0 - - - # Create instance: icapWrap_0, and set properties - set icapWrap_0 [ create_bd_cell -type ip -vlnv user.org:user:icapWrap:1.0 icapWrap_0 ] - - ############################################## - ##### Create connection ###################### - ############################################## - - - # Create interface connections - - ##### connect DFX controller - connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins S_AXI_DFX_CTRL ] [get_bd_intf_pins dfx_controller_0/s_axi_reg] - connect_bd_intf_net -intf_net Conn2 [get_bd_intf_pins M_AXI_DFX_LOADER ] [get_bd_intf_pins dfx_controller_0/M_AXI_MEM] - connect_bd_intf_net -intf_net dfx_controller_0_ICAP [get_bd_intf_pins dfx_controller_0/ICAP] [get_bd_intf_pins icapWrap_0/ICAP] - ##### connect to magic sequencer - connect_bd_intf_net -intf_net MagicSeq_0_M_AXI [get_bd_intf_pins M_AXI_DMA_CTRL] [get_bd_intf_pins MagicSeq_0/M_AXI] - connect_bd_intf_net -intf_net axi_interconnect_1_M02_AXI [get_bd_intf_pins S_AXI_MGQ_CTRL] [get_bd_intf_pins MagicSeq_0/S_AXI] - ##### connect to interrupt controller - connect_bd_intf_net -intf_net axi_interconnect_1_M00_AXI [get_bd_intf_pins S_AXI_INTR_CTRL] [get_bd_intf_pins axi_intc_0/s_axi] - - - - # Create port connections - - ##### magic sequencer control - connect_bd_net -net MagicSeq_0_hw_intr [get_bd_pins MagicSeq_0/hw_intr] [get_bd_pins axi_intc_0/intr ] - connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins mgsLoadInit ] [get_bd_pins MagicSeq_0/slaveMgsLoadInit] - connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins mgsLoadReset ] [get_bd_pins MagicSeq_0/slaveMgsLoadReset] - connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins mgsStoreInit ] [get_bd_pins MagicSeq_0/slaveMgsStoreInit] - connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins mgsStoreReset ] [get_bd_pins MagicSeq_0/slaveMgsStoreReset] - connect_bd_net -net streamGrp_0_finStore [get_bd_pins mgsFinExec ] [get_bd_pins MagicSeq_0/mgsFinExec] - ##### interrupt controller connections - connect_bd_net -net axi_intc_0_irq [get_bd_pins irq] [get_bd_pins axi_intc_0/irq] - ##### magic sequencer dfx controller connections - connect_bd_net -net MagicSeq_0_slaveReprog [get_bd_pins MagicSeq_0/slaveReprog] [get_bd_pins dfx_controller_0/vsm_VS_0_hw_triggers] - connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_reset [get_bd_pins MagicSeq_0/nslaveReset] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_reset] - ##### dfx controller control connections - connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_decouple [get_bd_pins decup] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_decouple] - ##### connect constant values - connect_bd_net -net xlconstant_0_dout [get_bd_pins xlconstant_0/dout] [get_bd_pins MagicSeq_0/hw_intr_clear] [get_bd_pins MagicSeq_0/hw_ctrl_start] - connect_bd_net -net xlconstant_1_dout [get_bd_pins xlconstant_1/dout] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_shutdown_ack] - ##### reset - connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins MagicSeq_0/reset] [get_bd_pins dfx_controller_0/icap_reset] [get_bd_pins dfx_controller_0/reset] - connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins MagicSeq_0/clk] [get_bd_pins dfx_controller_0/icap_clk] [get_bd_pins dfx_controller_0/clk] [get_bd_pins icapWrap_0/CLK] - - #### return to old instance - current_bd_instance $oldCurInst - - - } - - proc create_hier_cell_dfx_decup { parentCell nameHier amtMgs } { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - # Create pins - create_bd_pin -dir I decouple - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - - for {set i 0} {$i <= $amtMgs} {incr i} { - ### s connect to PR - ### rp connect to mgs - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 s_intf_${i} - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 rp_intf_${i} - - set dfx_decoupler_inst [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_decoupler:1.0 dfx_decoupler_${i} ] - set_property CONFIG.ALL_PARAMS {INTF {intf_0 {ID 0 VLNV xilinx.com:interface:axis_rtl:1.0}} ALWAYS_HAVE_AXI_CLK 1 HAS_SIGNAL_STATUS 0} [get_bd_cells dfx_decoupler_${i}] - - connect_bd_intf_net -intf_net dfx_decoupler_${i}_s [get_bd_intf_pins s_intf_${i} ] [get_bd_intf_pins dfx_decoupler_${i}/s_intf_0] - connect_bd_intf_net -intf_net dfx_decoupler_${i}_rp [get_bd_intf_pins rp_intf_${i}] [get_bd_intf_pins dfx_decoupler_${i}/rp_intf_0] - - connect_bd_net -net decupNet [get_bd_pins decouple] [get_bd_pins dfx_decoupler_${i}/decouple] - connect_bd_net -net clkNet [get_bd_pins clk ] [get_bd_pins dfx_decoupler_${i}/intf_0_aclk] - connect_bd_net -net nresetNet [get_bd_pins nreset ] [get_bd_pins dfx_decoupler_${i}/intf_0_arstn] - } - - - #### return to old instance - current_bd_instance $oldCurInst - - - - - } - - proc create_hier_cell_dfx_par { parentCell nameHier amtMgs dataWidths } { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - # Create pins - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - - for {set i 0} {$i <= $amtMgs} {incr i} { - ### s connect to PR - ### rp connect to mgs - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXI_${i} - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXI_${i} - - set DummyStreamMaster_${i} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${i} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamMaster_${i}] - set DummyStreamSlave_${i} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${i} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamSlave_${i}] - - - connect_bd_intf_net -intf_net DummyStreamMaster_${i} [get_bd_intf_pins M_AXI_${i} ] [get_bd_intf_pins DummyStreamMaster_${i}/M_AXI] - connect_bd_intf_net -intf_net DummyStreamSlave_${i} [get_bd_intf_pins S_AXI_${i} ] [get_bd_intf_pins DummyStreamSlave_${i}/S_AXI] - - connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${i}/clk] - connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${i}/reset] - connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${i}/clk] - connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${i}/reset] - } - - - #### return to old instance - current_bd_instance $oldCurInst - - } - - # set parentObj "" - # set parentType [get_property TYPE $parentObj] - - # set oldCurInst [current_bd_instance .] - - # current_bd_instance $parentObj - - - # ########################### - # ###### build the ip ####### - # ########################### - - # ###### set Cpu - # 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_INPUT_TYPE {cmos} \ - # CONFIG.PSU_MIO_22_POLARITY {Default} \ - # CONFIG.PSU_MIO_23_POLARITY {Default} \ - # CONFIG.PSU_MIO_26_POLARITY {Default} \ - # CONFIG.PSU_MIO_32_POLARITY {Default} \ - # CONFIG.PSU_MIO_33_POLARITY {Default} \ - # CONFIG.PSU_MIO_35_POLARITY {Default} \ - # CONFIG.PSU_MIO_36_POLARITY {Default} \ - # CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ - # MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ - # CONFIG.PSU__PMU__GPO1__ENABLE {0} \ - # CONFIG.PSU__PMU__GPO2__ENABLE {1} \ - # CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ - # CONFIG.PSU__PMU__GPO2__POLARITY {high} \ - # CONFIG.PSU__PMU__GPO3__ENABLE {0} \ - # 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ - # CONFIG.PSU__USE__M_AXI_GP2 {0} \ - # CONFIG.PSU__USE__S_AXI_GP0 {1} \ - # CONFIG.PSU__USE__S_AXI_GP1 {1} \ - # ] $zynq_ultra_ps_e_0 - - ###### set main control - set axi_interconnect_main_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_main_control ] - set_property CONFIG.NUM_MI {3} $axi_interconnect_main_control - - - ###### set dma control interconnect - set axi_interconnect_dma_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_dma_control ] - set_property -dict [list \ - CONFIG.NUM_MI {1} \ - CONFIG.NUM_SI {2} \ - ] $axi_interconnect_dma_control - - - ###### set smart memory reader interconnect - - # Create instance: smartconnect_reader, and set properties - set smartconnect_reader [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_reader] - - # Create instance: smartconnect_writer, and set properties - set smartconnect_writer [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_writer ] - set_property CONFIG.NUM_SI {1} $smartconnect_writer - - # Create instance: reseter - set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] - - - set AMT_MGS 2 - set MGS_IDX 2 - set BANK_IDX_WIDTH 2 - set MGS_WIDTH {32 64 128} - - - create_hier_cell_data_mover [current_bd_instance .] data_mover $AMT_MGS - create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $AMT_MGS $MGS_IDX $BANK_IDX_WIDTH - create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_s $AMT_MGS - create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $AMT_MGS - create_hier_cell_dfx_par [current_bd_instance .] dfx_par $AMT_MGS $MGS_WIDTH - - -} - - -cr_bd_system \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl index 0fde3835d1..545af88d0c 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl @@ -22,10 +22,12 @@ update_ip_catalog set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj -source mgs_meta +source mga_meta.tcl proc cr_bd_system {} { - + + global HLS_CFG_AMT_MGS HLS_CFG_MGS_INDEX HLS_CFG_BANK_IDX_WIDTH HLS_CFG_MGS_WRAP_WIDTH + set design_name system create_bd_design $design_name @@ -120,7 +122,7 @@ proc cr_bd_system {} { } - proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs amtMgsIdx bank1Idx} { + proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs bank1Idx} { #### old system obj is cell and oldCurInstr is path set parentObj [get_bd_cells $parentCell] @@ -158,15 +160,14 @@ proc cr_bd_system {} { ##### Create instance ######################## ############################################## - set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeq:1.0 MagicSeq_0 ] + set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeqTop:1.0 MagicSeq_0 ] set_property -dict [list \ CONFIG.BANK1_INDEX_WIDTH $bank1Idx \ CONFIG.BANK0_CNT_WIDTH $bank1Idx \ - CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgsIdx+1}] \ - CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgsIdx+1}] \ + CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgs+1}] \ + CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgs+1}] \ ] $MagicSeq_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 ] @@ -352,379 +353,379 @@ proc cr_bd_system {} { # ########################### # ###### set Cpu - # 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_INPUT_TYPE {cmos} \ - # CONFIG.PSU_MIO_22_POLARITY {Default} \ - # CONFIG.PSU_MIO_23_POLARITY {Default} \ - # CONFIG.PSU_MIO_26_POLARITY {Default} \ - # CONFIG.PSU_MIO_32_POLARITY {Default} \ - # CONFIG.PSU_MIO_33_POLARITY {Default} \ - # CONFIG.PSU_MIO_35_POLARITY {Default} \ - # CONFIG.PSU_MIO_36_POLARITY {Default} \ - # CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ - # MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ - # CONFIG.PSU__PMU__GPO1__ENABLE {0} \ - # CONFIG.PSU__PMU__GPO2__ENABLE {1} \ - # CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ - # CONFIG.PSU__PMU__GPO2__POLARITY {high} \ - # CONFIG.PSU__PMU__GPO3__ENABLE {0} \ - # 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ - # CONFIG.PSU__USE__M_AXI_GP2 {0} \ - # CONFIG.PSU__USE__S_AXI_GP0 {1} \ - # CONFIG.PSU__USE__S_AXI_GP1 {1} \ - # ] $zynq_ultra_ps_e_0 + 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_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_22_POLARITY {Default} \ + CONFIG.PSU_MIO_23_POLARITY {Default} \ + CONFIG.PSU_MIO_26_POLARITY {Default} \ + CONFIG.PSU_MIO_32_POLARITY {Default} \ + CONFIG.PSU_MIO_33_POLARITY {Default} \ + CONFIG.PSU_MIO_35_POLARITY {Default} \ + CONFIG.PSU_MIO_36_POLARITY {Default} \ + CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ + MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ + CONFIG.PSU__PMU__GPO1__ENABLE {0} \ + CONFIG.PSU__PMU__GPO2__ENABLE {1} \ + CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ + CONFIG.PSU__PMU__GPO2__POLARITY {high} \ + CONFIG.PSU__PMU__GPO3__ENABLE {0} \ + 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ + CONFIG.PSU__USE__M_AXI_GP2 {0} \ + CONFIG.PSU__USE__S_AXI_GP0 {1} \ + CONFIG.PSU__USE__S_AXI_GP1 {1} \ + ] $zynq_ultra_ps_e_0 ###### set main control set axi_interconnect_main_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_main_control ] @@ -759,7 +760,7 @@ proc cr_bd_system {} { create_hier_cell_data_mover [current_bd_instance .] data_mover $HLS_CFG_AMT_MGS - create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $HLS_CFG_AMT_MGS $HLS_CFG_MGS_INDEX $HLS_CFG_BANK_IDX_WIDTH + create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $HLS_CFG_AMT_MGS $HLS_CFG_BANK_IDX_WIDTH create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_s $HLS_CFG_AMT_MGS create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $HLS_CFG_AMT_MGS create_hier_cell_dfx_par [current_bd_instance .] dfx_par $HLS_CFG_AMT_MGS $HLS_CFG_MGS_WRAP_WIDTH diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl index 7dd73984bc..33ec484957 100644 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl +++ b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl @@ -17,4 +17,7 @@ ipx::check_integrity [ipx::current_core] ipx::save_core [ipx::current_core] set_property ip_repo_paths ../magic_streamer_grp_ip [current_project] -update_ip_catalog \ No newline at end of file +update_ip_catalog + +close_project +exit diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index 44993904ca..beb04db12e 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -47,4 +47,5 @@ def write_hls(self, model, is_multigraph=False): if True: self.magic_gen.copyMagicArchIp(self.writer_meta, model) - self.magic_gen.write_mgs(self.writer_meta, model) \ No newline at end of file + self.magic_gen.write_mgs(self.writer_meta, model) + self.magic_gen.gen_vivado_project(self.writer_meta, model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index 45dea3503f..073695596a 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -9,13 +9,18 @@ class VitisUnifiedPartial_MagicArchGen(): - def gen_vivado_project(self, meta: VitisUnifiedWriterMeta, model, board_name = "zcu102"): + @classmethod + def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model): filedir = os.path.dirname(os.path.abspath(__file__)) vivado_project_des_folder_path = f'{model.config.get_output_dir()}/vivado_project' - if not os.path.exists(vivado_project_des_folder_path): - os.makedirs(vivado_project_des_folder_path) + if os.path.exists(vivado_project_des_folder_path): + shutil.rmtree(vivado_project_des_folder_path) + + os.makedirs(vivado_project_des_folder_path) + + board_name = meta.vitis_unified_config.get_board() #### copy project building script vivado_project_src_script_path = os.path.join(filedir, @@ -40,15 +45,15 @@ def gen_vivado_project(self, meta: VitisUnifiedWriterMeta, model, board_name = " for line in fin.readlines(): if "HLS_CFG_AMT_MGS" in line: line = line.replace("VAL", str(len(meta_list))) - if "HLS_CFG_MGS_INDEX" in line: - line = line.replace("VAL", meta_idx_width) if "HLS_CFG_BANK_IDX_WIDTH" in line: line = line.replace("VAL", graph_idx_width) if "HLS_CFG_MGS_WRAP_WIDTH" in line: - line = line.replace("VAL", "{ "+ ", ".join([str(width) for width, *_ in meta_list]) + " }") + width_list = ([str(meta.vitis_unified_config.get_dma_size())]) + width_list.extend([str(width) for width, *_ in meta_list]) + line = line.replace("VAL", "{"+ " ".join(width_list) + "}") fout.write(line) - fin.close() + fin .close() fout.close() From b982b21d1e240625ea0a534b262ddd822328578c Mon Sep 17 00:00:00 2001 From: tanawin Date: Sat, 23 Aug 2025 19:38:27 +0200 Subject: [PATCH 36/70] add connection between block --- .../board_support/zcu102/project_builder.tcl | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl index 545af88d0c..771dd8e7aa 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl @@ -765,6 +765,65 @@ proc cr_bd_system {} { create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $HLS_CFG_AMT_MGS create_hier_cell_dfx_par [current_bd_instance .] dfx_par $HLS_CFG_AMT_MGS $HLS_CFG_MGS_WRAP_WIDTH + + # Create interface connections + connect_bd_intf_net -intf_net S_AXI_DFX_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_DFX_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M00_AXI] + connect_bd_intf_net -intf_net S_AXI_INTR_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_INTR_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M02_AXI] + connect_bd_intf_net -intf_net S_AXI_MGQ_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_MGQ_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M01_AXI] + connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins axi_interconnect_dma_control/M00_AXI] [get_bd_intf_pins data_mover/S_AXI_DMA_CTRL] + + for {set i 0} {$i <= $HLS_CFG_AMT_MGS} {incr i} { + #### data mover connections -----> to master decoupler + connect_bd_intf_net -intf_net data_mover_M${i}_AXI [get_bd_intf_pins data_mover/M${i}_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_${i}] + #### master decoupler ------> to dfx region + connect_bd_intf_net -intf_net dfx_decup_m_s_intf_${i} [get_bd_intf_pins dfx_decup_m/s_intf_${i}] [get_bd_intf_pins dfx_par/S_AXI_${i}] + #### dfx region -------> to slave decoupler + connect_bd_intf_net -intf_net dfx_par_M_AXI_${i} [get_bd_intf_pins dfx_par/M_AXI_${i}] [get_bd_intf_pins dfx_decup_s/rp_intf_${i}] + #### slave decoupler -------> data mover + connect_bd_intf_net -intf_net dfx_decup_s_s_intf_${i} [get_bd_intf_pins dfx_decup_s/s_intf_${i}] [get_bd_intf_pins data_mover/S${i}_AXI] + + } + + + ###### data transfer connections + # connect_bd_intf_net -intf_net data_mover_M0_AXI [get_bd_intf_pins data_mover/M0_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_0] + # connect_bd_intf_net -intf_net data_mover_M1_AXI [get_bd_intf_pins data_mover/M1_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_1] + # connect_bd_intf_net -intf_net data_mover_M2_AXI [get_bd_intf_pins data_mover/M2_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_2] + # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_0 [get_bd_intf_pins dfx_decup_m/s_intf_0] [get_bd_intf_pins dfx_par/S_AXI_0] + # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_1 [get_bd_intf_pins dfx_decup_m/s_intf_1] [get_bd_intf_pins dfx_par/S_AXI_1] + # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_2 [get_bd_intf_pins dfx_decup_m/s_intf_2] [get_bd_intf_pins dfx_par/S_AXI_2] + # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_0 [get_bd_intf_pins dfx_decup_s/s_intf_0] [get_bd_intf_pins data_mover/S0_AXI] + # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_1 [get_bd_intf_pins dfx_decup_s/s_intf_1] [get_bd_intf_pins data_mover/S1_AXI] + # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_2 [get_bd_intf_pins dfx_decup_s/s_intf_2] [get_bd_intf_pins data_mover/S2_AXI] + # connect_bd_intf_net -intf_net dfx_par_M_AXI_0 [get_bd_intf_pins dfx_par/M_AXI_0] [get_bd_intf_pins dfx_decup_s/rp_intf_0] + # connect_bd_intf_net -intf_net dfx_par_M_AXI_1 [get_bd_intf_pins dfx_par/M_AXI_1] [get_bd_intf_pins dfx_decup_s/rp_intf_1] + # connect_bd_intf_net -intf_net dfx_par_M_AXI_2 [get_bd_intf_pins dfx_par/M_AXI_2] [get_bd_intf_pins dfx_decup_s/rp_intf_2] + + connect_bd_intf_net -intf_net data_mover_M_AXI_MM2S [get_bd_intf_pins data_mover/M_AXI_MM2S] [get_bd_intf_pins smartconnect_reader/S00_AXI] + connect_bd_intf_net -intf_net data_mover_M_AXI_S2MM [get_bd_intf_pins data_mover/M_AXI_S2MM] [get_bd_intf_pins smartconnect_writer/S00_AXI] + + connect_bd_intf_net -intf_net magic_seq_ctrl_M_AXI_DFX_LOADER [get_bd_intf_pins magic_seq_ctrl/M_AXI_DFX_LOADER] [get_bd_intf_pins smartconnect_reader/S01_AXI] + connect_bd_intf_net -intf_net magic_seq_ctrl_M_AXI_DMA_CTRL [get_bd_intf_pins magic_seq_ctrl/M_AXI_DMA_CTRL] [get_bd_intf_pins axi_interconnect_dma_control/S00_AXI] + connect_bd_intf_net -intf_net smartconnect_reader_M00_AXI [get_bd_intf_pins smartconnect_reader/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] + connect_bd_intf_net -intf_net smartconnect_writer_M00_AXI [get_bd_intf_pins smartconnect_writer/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC1_FPD] + 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 axi_interconnect_main_control/S00_AXI] + connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM1_FPD [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] [get_bd_intf_pins axi_interconnect_dma_control/S01_AXI] + + # Create port connections + connect_bd_net -net data_mover_finStore [get_bd_pins data_mover/finStore] [get_bd_pins magic_seq_ctrl/mgsFinExec] + connect_bd_net -net magic_seq_ctrl_decup [get_bd_pins magic_seq_ctrl/decup] [get_bd_pins dfx_decup_s/decouple] [get_bd_pins dfx_decup_m/decouple] + connect_bd_net -net magic_seq_ctrl_irq [get_bd_pins magic_seq_ctrl/irq] [get_bd_pins zynq_ultra_ps_e_0/pl_ps_irq0] + connect_bd_net -net magic_seq_ctrl_mgsLoadInit [get_bd_pins magic_seq_ctrl/mgsLoadInit] [get_bd_pins data_mover/loadInit] + connect_bd_net -net magic_seq_ctrl_mgsLoadReset [get_bd_pins magic_seq_ctrl/mgsLoadReset] [get_bd_pins data_mover/loadReset] + connect_bd_net -net magic_seq_ctrl_mgsStoreInit [get_bd_pins magic_seq_ctrl/mgsStoreInit] [get_bd_pins data_mover/storeInit] + connect_bd_net -net magic_seq_ctrl_mgsStoreReset [get_bd_pins magic_seq_ctrl/mgsStoreReset] [get_bd_pins data_mover/storeReset] + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins rst_ps8_0_99M/peripheral_aresetn] [get_bd_pins axi_interconnect_dma_control/ARESETN] [get_bd_pins axi_interconnect_dma_control/M00_ARESETN] [get_bd_pins data_mover/nreset] [get_bd_pins axi_interconnect_dma_control/S00_ARESETN] [get_bd_pins magic_seq_ctrl/nreset] [get_bd_pins axi_interconnect_dma_control/S01_ARESETN] [get_bd_pins axi_interconnect_main_control/ARESETN] [get_bd_pins axi_interconnect_main_control/M00_ARESETN] [get_bd_pins axi_interconnect_main_control/M01_ARESETN] [get_bd_pins axi_interconnect_main_control/M02_ARESETN] [get_bd_pins axi_interconnect_main_control/S00_ARESETN] [get_bd_pins smartconnect_reader/aresetn] [get_bd_pins smartconnect_writer/aresetn] [get_bd_pins dfx_par/nreset] [get_bd_pins dfx_decup_s/nreset] [get_bd_pins dfx_decup_m/nreset] + 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_interconnect_dma_control/ACLK] [get_bd_pins rst_ps8_0_99M/slowest_sync_clk] [get_bd_pins axi_interconnect_dma_control/M00_ACLK] [get_bd_pins data_mover/clk] [get_bd_pins axi_interconnect_dma_control/S00_ACLK] [get_bd_pins magic_seq_ctrl/clk] [get_bd_pins axi_interconnect_dma_control/S01_ACLK] [get_bd_pins zynq_ultra_ps_e_0/maxihpm1_fpd_aclk] [get_bd_pins axi_interconnect_main_control/ACLK] [get_bd_pins axi_interconnect_main_control/M00_ACLK] [get_bd_pins axi_interconnect_main_control/M01_ACLK] [get_bd_pins axi_interconnect_main_control/M02_ACLK] [get_bd_pins axi_interconnect_main_control/S00_ACLK] [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_fpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc0_fpd_aclk] [get_bd_pins smartconnect_reader/aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc1_fpd_aclk] [get_bd_pins smartconnect_writer/aclk] [get_bd_pins dfx_decup_m/clk] [get_bd_pins dfx_par/clk] [get_bd_pins dfx_decup_s/clk] + 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] + + delete_bd_objs [get_bd_addr_segs] [get_bd_addr_segs -excluded] + assign_bd_address + } From 0b3debc55477334da66e42782d0bd0bb1c6ac6b9 Mon Sep 17 00:00:00 2001 From: tanawin Date: Sun, 24 Aug 2025 22:01:40 +0200 Subject: [PATCH 37/70] drafting the automatically magic streamer linker --- .../magic_streamer_mng.py | 103 ++++++++ .../vitis_unified_partial_backend.py | 20 +- hls4ml/model/graph.py | 244 ++++++++++++++++-- .../vitis_unified/hls_kernel_config.cfg | 2 +- .../vitis_unified_partial/myproject_axi.cpp | 4 +- .../vitis_unified_partial_writer/__init__.py | 3 +- .../vitis_unified_partial_writer/meta_gen.py | 6 +- .../vitis_unified_partial_writer/wrap_gen.py | 5 +- .../writer/vitis_unified_writer/__init__.py | 7 +- .../writer/vitis_unified_writer/build_gen.py | 2 + .../writer/vitis_unified_writer/meta_gen.py | 3 + hls4ml/writer/vitis_writer.py | 7 +- 12 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py new file mode 100644 index 0000000000..659a17ec9b --- /dev/null +++ b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py @@ -0,0 +1,103 @@ + + +#### the shared class between subgraph and host graph + +class MgsConMeta: + #### + def __init__(self, io_idx, input_node, mgs_wrap_width, mgs_row_idx_width): + self.io_idx = io_idx + self.input_node = input_node + self.mgs_idx = -1 + self.mgs_wrap_width = mgs_wrap_width + self.mgs_row_idx_width = mgs_row_idx_width + +class MagicStreamerMeta: + def __init__(self, data_width, row_idx_width, mgs_idx): + self.data_width = data_width + self.row_idx_width = row_idx_width + self.mgs_idx = mgs_idx + + +class MagicStreamerManager: + + ### + ### [ (inputIdx, mgsNumber, mgsNumber) ] + ### [] + + def __init__(self, multiModel): + + self.magicStreamer_meta_list = [] ##### (data_width, row_idx_width, mgs_idx) + self.input_connection_result_list = [[] for _ in range(len(multiModel.graphs))] + + + def get_MgsConMeta_from_graph(self, graph, input_node,io_idx, is_input): + + ####### get its tensor variable + tensor_var = graph.get_input_variables()[io_idx] if is_input else graph.get_output_variables()[io_idx] + ####### fix this two variable + mgs_bit_width = 32 + mgs_row_width = 1024 + mgs_con_meta = MgsConMeta(io_idx, input_node, mgs_bit_width, mgs_row_width) + return mgs_con_meta + + def complete_the_connection(self, mgsCon: MgsConMeta, multiModel): + ###[ [ (inputNode, srcNode, srcNodeOutputIdx), .....], [ ..], [ ..] ] + node_links = multiModel.input_node_links + + inspect_input_node = mgsCon.input_node + + for input_node, src_node, src_node_output_idx in node_links: + if input_node == inspect_input_node: + #### find where is so + + + def select_mgs_number_for_port(self, inspect_connection: MgsConMeta, free_list: list[MagicStreamerMeta]): + + matched_dw_mgs = list(filter(lambda x: x.data_width == inspect_connection.mgs_wrap_width, free_list)) + sorted_mgs = sorted(matched_dw_mgs, key=lambda x: x.row_idx_width, reverse=True) + #### get the MagicStreamerMeta that have the maximum size + if len(sorted_mgs) == 0: + return None + else: + return sorted_mgs[0] + + + def build_all_meta_data(self, multiModel): + + next_mgs_number = 0 + ready_to_used_mgs = [] ### list of mgs number + using_mgs_list = [] ### list of mgs number + + + #### loop to all subgraph + for gid, subGraph in enumerate(multiModel.graphs): + + ######## we inspect the output + connection_out_meta_list = [ self.get_MgsConMeta_from_graph(subGraph, subGraph.graph[io_name], io_idx, False) + for io_idx, io_name in enumerate(subGraph.outputs)] + connection_out_meta_sorted_rs = sorted(connection_out_meta_list, key=lambda x: x.mgs_row_idx_width, reverse=True) + + ##### try to allocate the magic streamer that matched the most match + for connection in connection_out_meta_sorted_rs: + ##### check the available magic streamer for each connection + selected_mgs = self.select_mgs_number_for_port(connection, ready_to_used_mgs) + if selected_mgs is None: + ##### not found create the magic streamer + using_mgs_list.append(MagicStreamerMeta(connection.mgs_wrap_width, connection.mgs_row_idx_width, next_mgs_number)) + else: + ##### found get the increase size of row Idx if it is need + idx_in_ready_list = ready_to_used_mgs.index(selected_mgs) + ready_to_used_mgs.pop(idx_in_ready_list) #### remove it from ready list + using_mgs_list.append(selected_mgs) #### append it into used list + + ######## we inspect the input + connection_in_meta_list = [self.get_MgsConMeta_from_graph(subGraph, subGraph.graph[io_name], io_idx, True) + for io_idx, io_name in enumerate(subGraph.inputs)] + for connection in connection_in_meta_list: + + + + + + ########## finalize the magic streamer metadata + self.magic_streamer_meta_list = sorted(ready_to_used_mgs, key=lambda x: x.mgs_idx) \ No newline at end of file diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index 6c2ae59579..5b4685896b 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -7,9 +7,10 @@ from hls4ml.backends import VitisUnifiedBackend, VivadoBackend from hls4ml.model.flow import register_flow from hls4ml.report import parse_vivado_report - from hls4ml.writer.vitis_unified_partial_writer.meta_gen import VitisUnifiedPartial_MetaGen as mg +from magic_streamer_mng import MagicStreamerManager + class VitisUnifiedPartialBackend(VitisUnifiedBackend): @@ -110,17 +111,30 @@ def create_initial_config( config['MultiGraphConfig']['amtGraph'] = init_amt_graph # it should be set by the multigraph system config['MultiGraphConfig']['graphIdx'] = -1 # -1 means unset yet or it is multigraph stitcher print(f"mgs initial is set to {init_mgs_meta}") - config['MultiGraphConfig']['MgsMeta'] = init_mgs_meta if init_mgs_meta is not None else [] #### it should be only used for stitcher - config['MultiGraphConfig']['IOInterimType'] = {} config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type + config['MagicStreamerMng'] = None + return config + def multigraph_augment_config(self, multi_model): + + #### create magic streamer manager + mgs_mng = MagicStreamerManager(multi_model) + + ########## fill to every posible graph to make it work + multi_model.config.config["MagicStreamerMng"] = mgs_mng + for subGraph in multi_model.graphs: + subGraph.config.config["MagicStreamerMng"] = mgs_mng + + + + def _register_flows(self): vitis_ip = 'vitis:ip' writer_passes = ['make_stamp', 'vitisunifiedpartial:write_hls'] diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index e3c293dd46..ff75f44af0 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -8,6 +8,7 @@ import threading import uuid from collections import OrderedDict +from operator import indexOf import numpy as np import numpy.ctypeslib as npc @@ -1036,7 +1037,7 @@ def save(self, file_path): class MultiModelGraph: - def __init__(self, graphs: list[ModelGraph]): + def __init__(self, graphs: list[ModelGraph], input_node_links = None): """ Create a stitched model from pre-optimized subgraphs. """ @@ -1044,53 +1045,228 @@ def __init__(self, graphs: list[ModelGraph]): self._initialize_config(self.graphs[0]) self._bind_modelgraph_methods() self._initialize_io_attributes(self.graphs) + self.input_node_links = input_node_links + + + + ##### node link is the meta data that used to store how the new generated input node when the graph was chopped connect with the source data node + ##### [graph0, graph1, graph2, ...] + ##### [[(newInputNodeX, srcOutputNodeY, inofOutputFromNodeY), (x2,y2,ys2), (x3,y3,ys3), .....], []] + + + @staticmethod + def check_io_idx_from_node(node_slices, inspectNode, isAnalyzeInput: bool): + + """ + check the Input of the inspectNode (incase isAnalyzeInput=True) that is come from outside current graph + check the Output of the inspectNode (incase isAnalyzeInput=False) that is come from outside current graph + return idx of the io array to indicate which io should be rerouted + """ + + requiredReroute = [] + + io_of_inspect_node = inspectNode.inputs if isAnalyzeInput else inspectNode.outputs + + for idx, ioName in enumerate(io_of_inspect_node): + shouldReroute = True + for curNode in node_slices: + #### the same node must be skipped + if curNode.name == inspectNode.name: + continue + io_of_scanning_node = curNode.outputs if isAnalyzeInput else curNode.inputs + if ioName in io_of_scanning_node: + shouldReroute = False + break + if shouldReroute: + requiredReroute.append(idx) + # if isAnalyzeInput: + # print("reroute IN put = ", idx, " ", ioName) + # print(" nodeName", inspectNode.name) + # print(" inputs", inspectNode.inputs) + # print(" outputs", inspectNode.outputs) + # print("-----------------") + return requiredReroute + + @staticmethod + def get_src_node_from_output_name(base_model: ModelGraph, output_name: str): + for layer_name, node in base_model.graph.items(): + if output_name in node.outputs: + return node, node.outputs.indexOf(output_name) + + + + @staticmethod + def group_for_creating_new_io(meta, isAnalyzeInput: bool): + + """ + some io that we gather from each node from the graph may have the same input source + if that so we should group it together + meta is list of (ioIdx, ofNode) + return {io_name: [(ioIdx, ofNode), ....]} + """ + rerouted_result = dict() + + for idx, node in meta: + ioName = node.inputs[idx] if isAnalyzeInput else node.outputs[idx] + if ioName not in rerouted_result: + rerouted_result[ioName] = [] + rerouted_result[ioName].append((idx, node)) + + return rerouted_result + + @staticmethod + def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, input_raw, output_raw): + + ######### we focus on copy 'MultiGraphConfig' + if 'MultiGraphConfig' in baseConfig: + newConfig['MultiGraphConfig'] = copy.deepcopy(baseConfig.get('MultiGraphConfig', {})) + ######## create the structure + newConfig.setdefault('MultiGraphConfig', {}) + newConfig['MultiGraphConfig'].setdefault('amtGraph', -2) + newConfig['MultiGraphConfig'].setdefault('graphIdx', -2) + newConfig['MultiGraphConfig'].setdefault('MgsMeta', []) + + newConfig['MultiGraphConfig'].setdefault('IOInterimType', {}) + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input', -2) + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', -2) + + ######## try to copy from the base model, if it it exist @classmethod - def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str]): + def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str], free_axi_interim: bool = False): """ Create a MultiModelGraph by splitting a base ModelGraph at specified layer names, each initiating a subgraph. """ + print("from multi model graph") cls._validate_split_points(base_model, split_before_layers) - all_nodes = list(base_model.graph.values()) - layer_names = [node.name for node in all_nodes] + all_nodes = list(base_model.graph.values()) + layer_names = [node.name for node in all_nodes] split_indices = sorted(layer_names.index(s) for s in split_before_layers) - bounds = [0] + split_indices + [len(all_nodes)] + bounds = [0] + split_indices + [len(all_nodes)] node_slices: list[list] = [all_nodes[bounds[i] : bounds[i + 1]] for i in range(len(bounds) - 1)] base_input_layer = base_model.graph[base_model.inputs[0]] input_layer_kind = base_input_layer.attributes['class_name'] next_index = max(n.index for n in all_nodes) + input_node_links = [ [] for _ in range(len(node_slices))] + subgraphs: list['ModelGraph'] = [] for idx, slice_ in enumerate(node_slices): + + #### clone and modify the config cfg_copy = copy.copy(base_model.config) cfg_copy.config = copy.copy(base_model.config.config) + cls.add_config_for_multi_model(base_model.config.config, + cfg_copy.config, + len(node_slices), idx, + free_axi_interim and (idx != 0), + free_axi_interim and (idx != (len(node_slices)-1))) + cfg_copy.config['ProjectName'] = f'{base_model.config.get_project_name()}_graph{idx + 1}' cfg_copy.config['OutputDir'] = os.path.join(base_model.config.get_output_dir(), f'graph{idx + 1}') - subgraph = ModelGraph(cfg_copy, inputs=[], outputs=[]) - graph_dict: OrderedDict[str, Layer] = OrderedDict() + subgraph = base_model.__class__(cfg_copy, inputs=[], outputs=[]) + graph_dict = OrderedDict() + + pooled_input_layer = [] + print("-------------- idx = ", idx, " -----------------------------") + ################################################################ + ##### check the current slice node and create new input node ### + ################################################################ if idx > 0: - next_index += 1 - input_layer = cls._create_input_node(subgraph, slice_[0], input_layer_kind, next_index) - graph_dict[input_layer.name] = input_layer - slice_[0].inputs = input_layer.outputs + requiredReroute = [] + + ###### get input for each slice + for checkingNode in slice_: + nodeInputChangeList = cls.check_io_idx_from_node(slice_, checkingNode, True) + #### node input change list = [changeIdx: int, ....] + #### add to requiredReroute + for changeIdx in nodeInputChangeList: + requiredReroute.append((changeIdx, checkingNode)) + + ###### grouping it, incase the io have been reused many time + ######### rerouteGrp { "ioName" : [(inputIdx, Node), ....]} + + + #rerouteGrp = cls.group_for_creating_new_io(requiredReroute, True) + + + ###### create reroute for for each new input + + named_new_input_layer = dict() + #### inputIdx is index in input of target Node + for inputIdx, targetNode in requiredReroute: + ioName = targetNode.outputs[inputIdx] + ###### nodeUpdateList[0][1] is the sample Node (Layer) that must be inject to the system + input_layer = cls._create_input_node(subgraph, targetNode, #### list of (inputIdx, Node) + input_layer_kind, next_index, + next_node_portName = ioName, + namedNewInputLayer = named_new_input_layer) + pooled_input_layer.append(input_layer) + graph_dict[input_layer.name] = input_layer + targetNode.inputs[inputIdx] = input_layer.outputs[0] + + #### update link meta data + src_node, src_node_out_idx = cls.get_src_node_from_output_name(base_model, targetNode.inputs[inputIdx]) + input_node_links[idx].append((input_layer, src_node, src_node_out_idx)) + + + # print("added name is ", input_layer.name ) + # print("output from input layer", input_layer.outputs) + # print("input from input layer", input_layer.inputs) + + next_index += 1 + + ####### the input node should have 1 input node right so + else: input_layer = base_input_layer + pooled_input_layer.append(input_layer) + input_node_links[idx].append((input_layer, None, None)) + + ############################## + ##### config new graph ####### + ############################## for node in slice_: - node.model = subgraph # fix for layer.model.get_layer_output_variable() + graph_dict[node.name] = node + node.model = subgraph # fix for layer.model.get_layer_output_variable() for out_name in node.outputs: subgraph.output_vars[out_name] = base_model.output_vars[out_name] - graph_dict[node.name] = node + subgraph.graph = graph_dict - subgraph.graph = graph_dict - subgraph.inputs = input_layer.outputs if idx > 0 else base_model.inputs - subgraph.outputs = slice_[-1].outputs if idx < len(node_slices) - 1 else base_model.outputs - subgraph._applied_flows = base_model._applied_flows + ###### config input + print("idx is ", idx) + if idx > 0: + subgraph.inputs = [curInputNode.outputs[0] for curInputNode in pooled_input_layer] + else: + subgraph.inputs = base_model.inputs + + ###### config output + pooled_outputs = [] + print("checking output") + for layer in slice_: + outputIdxs = cls.check_io_idx_from_node(slice_, layer, False) + print(f"layer name {layer.name} : {outputIdxs}") + for outIdx in outputIdxs: + pooled_outputs.append(layer.outputs[outIdx]) + + subgraph.outputs = pooled_outputs + # subgraph.inputs = input_layer.outputs if idx > 0 else base_model.inputs + # subgraph.outputs = slice_[-1].outputs if idx < len(node_slices) - 1 else base_model.outputs + + print("input ---->") + print(subgraph.inputs) + print("output ---->") + print(subgraph.outputs) + + + + subgraph._applied_flows = base_model._applied_flows # NOTE might need to examine other subgraph-related flows (i.e., fifo_optimizer) subgraph.apply_flow('vivado:specific_types') subgraph.apply_flow('vitis:apply_templates') @@ -1101,7 +1277,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] subgraphs.append(subgraph) - return cls(subgraphs) + return cls(subgraphs, input_node_links) @staticmethod def _validate_split_points(model: ModelGraph, split_names: list[str]): @@ -1116,21 +1292,36 @@ def _validate_split_points(model: ModelGraph, split_names: list[str]): raise ValueError(f"Split layer '{name}' not found in the model.") if len(node.inputs) > 1: raise ValueError(f"Cannot split at layer '{name}' (multiple inputs detected).") - if model.graph[node.inputs[0]].class_name == 'Reshape' or node.class_name == 'Reshape': + + hostName = None + for key, value in model.graph.items(): + if value.outputs[0] == node.inputs[0]: + hostName = key + + if model.graph[hostName].class_name == 'Reshape' or node.class_name == 'Reshape': raise ValueError(f"Cannot split at '{name}': Reshape layer found in this or previous layer.") @staticmethod - def _create_input_node(model, next_node, kind, index): + def _create_input_node(model, next_node, kind, index, next_node_portName = None, namedNewInputLayer = None): layer_name = f'{next_node.name}_input' + + if (namedNewInputLayer is not None): + if layer_name in namedNewInputLayer: + newLayerName = layer_name + "_" + str(namedNewInputLayer[layer_name]) + namedNewInputLayer[layer_name] = namedNewInputLayer[layer_name] + 1 + layer_name = newLayerName + else: + namedNewInputLayer[layer_name] = 0 + attrs = { 'name': layer_name, 'class_name': kind, 'data_format': 'channels_last', - 'input_shape': next_node.get_input_variable().shape, + 'input_shape': next_node.get_input_variable(next_node_portName).shape, } model.index = index node = model.make_node(kind, layer_name, attrs, [layer_name], [layer_name], initialize=True) - model.output_vars[layer_name].type.precision = next_node.get_input_variable().type.precision + model.output_vars[layer_name].type.precision = next_node.get_input_variable(next_node_portName).type.precision return node def _initialize_config(self, first_graph): @@ -1143,6 +1334,10 @@ def _initialize_config(self, first_graph): self._update_project_config(first_graph) self.backend = first_graph.config.backend + ####### after Multigraph split already some config may have been augment after + self.backend.writer.multigraph_augment_config(self) + + def _bind_modelgraph_methods(self): # Bind necessary ModelGraph methods to this instance self._compile = ModelGraph._compile.__get__(self, MultiModelGraph) @@ -1296,11 +1491,12 @@ def write(self): self.nn_config = self.parse_nn_config() self.config.config['Stamp'] = self._make_stamp() # Bypass VitisWriter and invoke write_hls directly from VivadoWriter - super(self.backend.writer.__class__, self.backend.writer).write_hls(self, is_multigraph=True) + #super(self.backend.writer.__class__, self.backend.writer).write_hls(self, is_multigraph=True) + self.backend.writer.write_hls(self, is_multigraph=True) def compile(self): self.write() - self._compile() + #self._compile() def predict(self, x, sim='csim'): if sim == 'csim': diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg index 5b44cca2d5..c7cda021b1 100644 --- a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -17,7 +17,7 @@ tb.file={OUTDIR}/tb_data tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-std=c++0x tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-DRTL_SIM package.ip.version=1.0.0 -package.output.format=xo +package.output.format={OUTPUT_KERNEL_TYPE} syn.compile.name_max_length=80 syn.schedule.enable_dsp_full_reg=0 package.output.syn=1 \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp index 0031e383b0..5def3d4fce 100644 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp +++ b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp @@ -37,7 +37,7 @@ void enqueue_layerStream2layer(hls::stream& src_mgs_stream, template -void dequeue_layer2atom(hls::stream& des_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ +void dequeue_layer2atom(hls::stream& des_dma_stream, hls::stream& raw_stream, bool isLastIndicate){ dma_data_packet dma_tmp; dma_tmp.last = 0; for(unsigned i = 0; i < SIZE/OUTPUT_LAYER_ARR::size; ++i){ @@ -54,7 +54,7 @@ void dequeue_layer2atom(hls::stream& des_dma_stream, hls::strea } template -void dequeue_layer2layer(hls::stream& des_mgs_stream, hls::stream& raw_stream, bool& isLastIndicate){ +void dequeue_layer2layer(hls::stream& des_mgs_stream, hls::stream& raw_stream, bool isLastIndicate){ OUTPUT_LAYER_STREAM output_layer_stream_tmp; output_layer_stream_tmp.last = 0; diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index beb04db12e..8c01a5fb6c 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -34,6 +34,7 @@ def __init__(self): self.magic_gen = VitisUnifiedPartial_MagicArchGen + def generate_config(self, model): from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig self.writer_meta.vitis_unified_config = VitisUnifiedPartialConfig( @@ -45,7 +46,7 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model, is_multigraph) - if True: + if False: self.magic_gen.copyMagicArchIp(self.writer_meta, model) self.magic_gen.write_mgs(self.writer_meta, model) self.magic_gen.gen_vivado_project(self.writer_meta, model) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py index 639f6dbe67..1884af5c6d 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py @@ -23,6 +23,10 @@ def get_io_port_name(self, tensorVar, isInput: bool, idx: int): def get_top_wrap_func_name(self, model): return f"{model.config.get_project_name()}_axis" + @classmethod + def get_output_kernel_type(cls): + return "ip_catalog" + @classmethod def get_input_size_arr_name(self, model): return "N_IN_" + model.config.get_project_name() @@ -46,7 +50,7 @@ def get_is_last_var(self, idx): @classmethod def get_all_last_logic(self, amt): isLastList = [self.get_is_last_var(idx) for idx in range(amt)] - return " & ".join(isLastList) + return " && ".join(isLastList) ################################################## ## generation function call ############### diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py index 7f0c4c2348..44d5064544 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -43,7 +43,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.cpp'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_axi.cpp', 'w') + fout = open(f'{model.config.get_output_dir()}/firmware/{mg.get_wrapper_file_name(model)}.cpp', 'w') for line in fin.readlines(): @@ -83,6 +83,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): line += mg.get_enqueue_func_stream2rstream(inp, inp_idx) else: line += mg.get_enqueue_func_atom2stream(inp, inp_idx) + line += "\n" elif "// hls-fpga-machine-learning insert call" in line: poolList = [] @@ -112,7 +113,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.h'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_axi.h', 'w') + fout = open(f'{model.config.get_output_dir()}/firmware/{mg.get_wrapper_file_name(model)}.h', 'w') for line in fin.readlines(): diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 005e79e287..9744f36d1b 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -67,10 +67,15 @@ def make_export_path(self, model): def write_hls(self, model, is_multigraph=False): + + if is_multigraph: + super().write_hls(model, is_multigraph = True) + return + self.generate_config(model) - super().write_hls(model) + super().write_hls(model, is_multigraph = False) self.wg.write_wrapper(self.writer_meta, model, self.mg) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 0adbecb66c..530b3ae792 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -53,6 +53,8 @@ def write_hls_kernel_cfg(self, meta, model, mg): line = line.replace("{FILE_NAME_AXIS}", mg.get_wrapper_file_name(model)) if "{FILE_NAME_BASE}" in line: line = line.replace("{FILE_NAME_BASE}", mg.get_main_file_name(model)) + if "{OUTPUT_KERNEL_TYPE}" in line: + line = line.replace("{OUTPUT_KERNEL_TYPE}", mg.get_output_kernel_type()) fout.write(line) diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index 6915c0c16a..d45893abde 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -92,3 +92,6 @@ def get_top_wrap_func_name(self, model): def rename_type(self, tensorVar, layerIdx: int, isInput: bool): return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" + @classmethod + def get_output_kernel_type(cls): + return "xo" \ No newline at end of file diff --git a/hls4ml/writer/vitis_writer.py b/hls4ml/writer/vitis_writer.py index 46c0ba3044..c5038124b1 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) From d4220c489d907ee328c2eeb32093baf6829befb2 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 12:38:44 +0200 Subject: [PATCH 38/70] add new refactor magic streamer controller --- .../magic_streamer_mng.py | 176 +++++++++++------- hls4ml/model/graph.py | 22 ++- 2 files changed, 122 insertions(+), 76 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py index 659a17ec9b..413bf4d7c4 100644 --- a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py +++ b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py @@ -1,103 +1,139 @@ - - -#### the shared class between subgraph and host graph - class MgsConMeta: #### - def __init__(self, io_idx, input_node, mgs_wrap_width, mgs_row_idx_width): - self.io_idx = io_idx - self.input_node = input_node - self.mgs_idx = -1 - self.mgs_wrap_width = mgs_wrap_width - self.mgs_row_idx_width = mgs_row_idx_width - -class MagicStreamerMeta: + def __init__(self, io_idx, tensor): + self.io_idx = io_idx + self.mgs_idx = -1 + self.mgs_wrap_width = 32 + self.mgs_row_idx_width = 10 + + +class MagicBufferMeta: def __init__(self, data_width, row_idx_width, mgs_idx): self.data_width = data_width self.row_idx_width = row_idx_width self.mgs_idx = mgs_idx + def upgrade_mgs_to_support(self, mgs_con_meta): + if self.row_idx_width < mgs_con_meta.mgs_row_idx_width: + self.row_idx_width = mgs_con_meta.mgs_row_idx_width + -class MagicStreamerManager: + def is_data_width_match(self, check_width): + return self.data_width == check_width - ### - ### [ (inputIdx, mgsNumber, mgsNumber) ] - ### [] + #### the shared class between subgraph and host graph - def __init__(self, multiModel): +class MgsConGraph: + #### in suppose to be pool of connection for each sub graph - self.magicStreamer_meta_list = [] ##### (data_width, row_idx_width, mgs_idx) - self.input_connection_result_list = [[] for _ in range(len(multiModel.graphs))] + def __init__(self, gid, input_node_links, amt_graph, mgs_model): ### gid = graph id + self.gid = gid + self.input_cons = [] #### the index of the list supposed to be the index of the input port as well + self.output_cons = [] + self.input_node_links = input_node_links + self.amt_graph = amt_graph + self.mgs_model = mgs_model + def start_convert_graph(self, graph): + #### do the output first because we need to not free the src first (src des cannot be the same buffer) + out_var = graph.get_output_variables() + for out_idx, out in enumerate(out_var): + mgs_con_meta = MgsConMeta(out_idx, out) + self.add_output_con(mgs_con_meta) - def get_MgsConMeta_from_graph(self, graph, input_node,io_idx, is_input): + #### do the input + in_var = graph.get_input_variables() + for in_idx, inp in enumerate(in_var): + mgs_con_meta = MgsConMeta(in_idx, inp) + self.add_input_con(mgs_con_meta) - ####### get its tensor variable - tensor_var = graph.get_input_variables()[io_idx] if is_input else graph.get_output_variables()[io_idx] - ####### fix this two variable - mgs_bit_width = 32 - mgs_row_width = 1024 - mgs_con_meta = MgsConMeta(io_idx, input_node, mgs_bit_width, mgs_row_width) - return mgs_con_meta + def is_last_graph(self): + return (self.gid + 1) == self.amt_graph - def complete_the_connection(self, mgsCon: MgsConMeta, multiModel): - ###[ [ (inputNode, srcNode, srcNodeOutputIdx), .....], [ ..], [ ..] ] - node_links = multiModel.input_node_links + def add_input_con(self, mgs_con_meta): - inspect_input_node = mgsCon.input_node + src_gid, src_out_idx = self.input_node_links[self.gid][mgs_con_meta.io_idx] - for input_node, src_node, src_node_output_idx in node_links: - if input_node == inspect_input_node: - #### find where is so + #### it load from dma + if src_gid == -1: + src_mgs_idx = -1 ##### it means dma + else: + src_mgs_con_meta = self.mgs_model.get_mgs_idx(src_gid, src_out_idx) + mgs_con_meta.mgs_idx = src_mgs_con_meta + self.mgs_model.move_buffer_to_free_list(src_mgs_con_meta) + ### expand the mgs if it is need + self.input_cons.append(mgs_con_meta) - def select_mgs_number_for_port(self, inspect_connection: MgsConMeta, free_list: list[MagicStreamerMeta]): + def add_output_con(self, mgs_con_meta): + + if self.is_last_graph(): + self.output_cons.append(mgs_con_meta) + return + + ###### we check the + stream_buffer = self.mgs_model.get_existing_possible_mgs_buffer(mgs_con_meta) + + if stream_buffer is None: + stream_buffer = self.mgs_model.allocate_mgs_buffer(mgs_con_meta) + + self.mgs_model.move_buffer_to_using_list(stream_buffer.mgs_idx) + mgs_con_meta.mgs_idx = stream_buffer.mgs_idx - matched_dw_mgs = list(filter(lambda x: x.data_width == inspect_connection.mgs_wrap_width, free_list)) - sorted_mgs = sorted(matched_dw_mgs, key=lambda x: x.row_idx_width, reverse=True) - #### get the MagicStreamerMeta that have the maximum size - if len(sorted_mgs) == 0: - return None - else: - return sorted_mgs[0] + self.output_cons.append(mgs_con_meta) - def build_all_meta_data(self, multiModel): +class MgsModel: + def __init__(self, amt_graph, mgs_mng): + self.amt_graph = amt_graph + self.con_graphs = [] + self.mgs_buffer_meta = [] #### index of the system supposed to be magic streamer and its port id - next_mgs_number = 0 - ready_to_used_mgs = [] ### list of mgs number - using_mgs_list = [] ### list of mgs number + self.mgs_buffer_holding = [] + self.mgs_buffer_empty = [] + def add_mgs_con_graph(self, mgs_con_graph): + self.con_graphs.append(mgs_con_graph) - #### loop to all subgraph - for gid, subGraph in enumerate(multiModel.graphs): + def get_mgs_idx(self, gid, outputIdx): + if gid < 0: + return -1 + mgs_con_meta = self.con_graphs[gid].output_cons[outputIdx] + return mgs_con_meta.mgs_idx - ######## we inspect the output - connection_out_meta_list = [ self.get_MgsConMeta_from_graph(subGraph, subGraph.graph[io_name], io_idx, False) - for io_idx, io_name in enumerate(subGraph.outputs)] - connection_out_meta_sorted_rs = sorted(connection_out_meta_list, key=lambda x: x.mgs_row_idx_width, reverse=True) + ############################################## + ############ magic streamer buffer ########### + ############################################## - ##### try to allocate the magic streamer that matched the most match - for connection in connection_out_meta_sorted_rs: - ##### check the available magic streamer for each connection - selected_mgs = self.select_mgs_number_for_port(connection, ready_to_used_mgs) - if selected_mgs is None: - ##### not found create the magic streamer - using_mgs_list.append(MagicStreamerMeta(connection.mgs_wrap_width, connection.mgs_row_idx_width, next_mgs_number)) - else: - ##### found get the increase size of row Idx if it is need - idx_in_ready_list = ready_to_used_mgs.index(selected_mgs) - ready_to_used_mgs.pop(idx_in_ready_list) #### remove it from ready list - using_mgs_list.append(selected_mgs) #### append it into used list + def upgrade_mgs_to_support(self, mgs_con_meta, mgsIdx): + if mgsIdx >= len(self.mgs_buffer_meta) or mgsIdx < 0: + raise Exception("upgrade magic streamer with Idx {mgsIdx} is out of bound.") + self.mgs_buffer_meta[mgsIdx].checkSpecAndUpgrade(mgs_con_meta) - ######## we inspect the input - connection_in_meta_list = [self.get_MgsConMeta_from_graph(subGraph, subGraph.graph[io_name], io_idx, True) - for io_idx, io_name in enumerate(subGraph.inputs)] - for connection in connection_in_meta_list: + def allocate_mgs_buffer(self, mgs_con_meta): + newStreamBuffer = MagicBufferMeta(mgs_con_meta.mgs_wrap_width, mgs_con_meta.mgs_row_idx_width, len(self.mgs_buffer_meta)) + mgs_idx = len(self.mgs_buffer_meta) + self.mgs_buffer_meta.append(newStreamBuffer) + return mgs_idx + def get_existing_possible_mgs_buffer(self, mgs_con_meta): + ##### filter the match buffer from exis + matched_buffer = list(filter( + lambda mgs: mgs.is_data_width_match(mgs_con_meta.mgs_wrap_width), + self.mgs_buffer_meta )) + highest_possible_buffer = sorted(matched_buffer, key=lambda x: x.row_idx_width, reverse=True) + return None if len(highest_possible_buffer) == 0 else highest_possible_buffer[0] + def move_buffer_to_using_list(self, mgs_idx): + ###### delete from free list first + self.mgs_buffer_empty = list(filter(lambda x: x.mgs_idx != mgs_idx, self.mgs_buffer_empty)) + ###### add to holding list + self.mgs_buffer_holding.append(self.mgs_buffer_meta[mgs_idx]) - ########## finalize the magic streamer metadata - self.magic_streamer_meta_list = sorted(ready_to_used_mgs, key=lambda x: x.mgs_idx) \ No newline at end of file + def move_buffer_to_free_list(self, mgs_idx): + ###### delete from holding list first + self.mgs_buffer_holding = list(filter(lambda x: x.mgs_idx != mgs_idx, self.mgs_buffer_holding)) + ###### add to free list + self.mgs_buffer_empty.append(self.mgs_buffer_meta[mgs_idx]) \ No newline at end of file diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index ff75f44af0..352421e635 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1050,8 +1050,10 @@ def __init__(self, graphs: list[ModelGraph], input_node_links = None): ##### node link is the meta data that used to store how the new generated input node when the graph was chopped connect with the source data node - ##### [graph0, graph1, graph2, ...] - ##### [[(newInputNodeX, srcOutputNodeY, inofOutputFromNodeY), (x2,y2,ys2), (x3,y3,ys3), .....], []] + + ##### |-------------graph 0 ------------| + ##### [ [(src_graph_idx, output_idx), ....], ] + @staticmethod @@ -1093,6 +1095,14 @@ def get_src_node_from_output_name(base_model: ModelGraph, output_name: str): if output_name in node.outputs: return node, node.outputs.indexOf(output_name) + @staticmethod + def get_src_subGraph_and_output_idx(subGraphs, output_name): + + for gid, subGraph in enumerate(subGraphs): + for layer_name, node in subGraph.graph.items(): + if output_name in node.outputs: + return gid, node.outputs.indexOf(output_name) + @staticmethod @@ -1198,7 +1208,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] named_new_input_layer = dict() #### inputIdx is index in input of target Node - for inputIdx, targetNode in requiredReroute: + for inputIdx, targetNode in requiredReroute: ### note that tagetNode may be same within requiredRerote ioName = targetNode.outputs[inputIdx] ###### nodeUpdateList[0][1] is the sample Node (Layer) that must be inject to the system input_layer = cls._create_input_node(subgraph, targetNode, #### list of (inputIdx, Node) @@ -1210,8 +1220,8 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] targetNode.inputs[inputIdx] = input_layer.outputs[0] #### update link meta data - src_node, src_node_out_idx = cls.get_src_node_from_output_name(base_model, targetNode.inputs[inputIdx]) - input_node_links[idx].append((input_layer, src_node, src_node_out_idx)) + src_gid, src_graph_out_idx = cls.get_src_subGraph_and_output_idx(subgraphs, targetNode.outputs[inputIdx]) + input_node_links[idx].append((src_gid, src_graph_out_idx)) # print("added name is ", input_layer.name ) @@ -1225,7 +1235,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] else: input_layer = base_input_layer pooled_input_layer.append(input_layer) - input_node_links[idx].append((input_layer, None, None)) + input_node_links[idx].append((-1, -1)) ############################## From e81078a59d59941cfb09cbf26c9e18f0b797229f Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 12:56:57 +0200 Subject: [PATCH 39/70] add start converter for class MgsModel --- .../magic_streamer_mng.py | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py index 413bf4d7c4..fac482fffa 100644 --- a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py +++ b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py @@ -84,27 +84,43 @@ def add_output_con(self, mgs_con_meta): self.output_cons.append(mgs_con_meta) class MgsModel: - def __init__(self, amt_graph, mgs_mng): - self.amt_graph = amt_graph + def __init__(self, multigraph): + self.multigraph = multigraph self.con_graphs = [] self.mgs_buffer_meta = [] #### index of the system supposed to be magic streamer and its port id self.mgs_buffer_holding = [] self.mgs_buffer_empty = [] + ############################################## + ############ start get the data ########### + ############################################## + + + def start_convert_model(self): + for gid, sub_graph in enumerate(self.multigraph.graphs): + #### initialize the MgsConGraph + input_node_link = self.multigraph.input_node_links + amt_graph = len(self.multigraph.graphs) + mgs_con_graph = MgsConGraph(gid, input_node_link, amt_graph, self) + mgs_con_graph.start_convert_graph(sub_graph) + #### start fill the metadata + self.add_mgs_con_graph(mgs_con_graph) + def add_mgs_con_graph(self, mgs_con_graph): self.con_graphs.append(mgs_con_graph) + ############################################## + ############ magic streamer buffer ########### + ############################################## + + ##### used by the vitis uniifed partial backend writer def get_mgs_idx(self, gid, outputIdx): if gid < 0: return -1 mgs_con_meta = self.con_graphs[gid].output_cons[outputIdx] return mgs_con_meta.mgs_idx - ############################################## - ############ magic streamer buffer ########### - ############################################## - def upgrade_mgs_to_support(self, mgs_con_meta, mgsIdx): if mgsIdx >= len(self.mgs_buffer_meta) or mgsIdx < 0: raise Exception("upgrade magic streamer with Idx {mgsIdx} is out of bound.") From 05cc84900e359b6b9753dc8051b95e2cbcd08a50 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 16:00:36 +0200 Subject: [PATCH 40/70] fix mgs model syntax bug --- .../magic_streamer_mng.py | 52 +++++++++++++++---- .../vitis_unified_partial_backend.py | 9 ++-- hls4ml/backends/vivado/vivado_backend.py | 7 +++ hls4ml/model/graph.py | 40 +++++++++----- 4 files changed, 83 insertions(+), 25 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py index fac482fffa..64249744a9 100644 --- a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py +++ b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py @@ -61,7 +61,6 @@ def add_input_con(self, mgs_con_meta): src_mgs_con_meta = self.mgs_model.get_mgs_idx(src_gid, src_out_idx) mgs_con_meta.mgs_idx = src_mgs_con_meta self.mgs_model.move_buffer_to_free_list(src_mgs_con_meta) - ### expand the mgs if it is need self.input_cons.append(mgs_con_meta) @@ -72,13 +71,16 @@ def add_output_con(self, mgs_con_meta): return ###### we check the - stream_buffer = self.mgs_model.get_existing_possible_mgs_buffer(mgs_con_meta) + stream_buffer_idx = self.mgs_model.get_existing_possible_mgs_buffer(mgs_con_meta) - if stream_buffer is None: - stream_buffer = self.mgs_model.allocate_mgs_buffer(mgs_con_meta) + if stream_buffer_idx is None: + stream_buffer_idx = self.mgs_model.allocate_mgs_buffer(mgs_con_meta) - self.mgs_model.move_buffer_to_using_list(stream_buffer.mgs_idx) - mgs_con_meta.mgs_idx = stream_buffer.mgs_idx + ##### upgrade the magic stream buffer to match size of it is lower + self.mgs_model.upgrade_mgs_to_support(mgs_con_meta, stream_buffer_idx) + + self.mgs_model.move_buffer_to_using_list(stream_buffer_idx) + mgs_con_meta.mgs_idx = stream_buffer_idx self.output_cons.append(mgs_con_meta) @@ -110,11 +112,43 @@ def start_convert_model(self): def add_mgs_con_graph(self, mgs_con_graph): self.con_graphs.append(mgs_con_graph) + + ### for outsider used + def get_mgs_idx_src(self, gid, inputIdx): + if gid not in range(0, self.multigraph.amt_graph): + raise Exception( + "get_mgs_idx_src: gid {gid} is out of bound. The amount of graph is {amt_graph}".format( + gid=gid, amt_graph=self.multigraph.amt_graph + ) + ) + if inputIdx not in range(0, len(self.con_graphs[gid].input_cons)): + raise Exception( + "get_mgs_idx_src: inputIdx {inputIdx} is out of bound. The amount of input is {input_num}".format( + inputIdx=inputIdx, input_num=len(self.con_graphs[gid].input_cons) + ) + ) + return self.con_graphs[gid].input_cons[inputIdx].mgs_idx + ### for outsider usd + def get_mgs_idx_dst(self, gid, outputIdx): + if gid not in range(0, self.multigraph.amt_graph): + raise Exception( + "get_mgs_idx_dst: gid {gid} is out of bound. The amount of graph is {amt_graph}".format( + gid=gid, amt_graph=self.multigraph.amt_graph + ) + ) + if outputIdx not in range(0, len(self.con_graphs[gid].output_cons)): + raise Exception( + "get_mgs_idx_dst: outputIdx {outputIdx} is out of bound. The amount of output is {output_num}".format( + outputIdx=outputIdx, output_num=len(self.con_graphs[gid].output_cons) + ) + ) + return self.con_graphs[gid].output_cons[outputIdx].mgs_idx + ############################################## ############ magic streamer buffer ########### ############################################## - ##### used by the vitis uniifed partial backend writer + ##### used by the vitis uniifed partial backend writer and MgsConGraph def get_mgs_idx(self, gid, outputIdx): if gid < 0: return -1 @@ -124,7 +158,7 @@ def get_mgs_idx(self, gid, outputIdx): def upgrade_mgs_to_support(self, mgs_con_meta, mgsIdx): if mgsIdx >= len(self.mgs_buffer_meta) or mgsIdx < 0: raise Exception("upgrade magic streamer with Idx {mgsIdx} is out of bound.") - self.mgs_buffer_meta[mgsIdx].checkSpecAndUpgrade(mgs_con_meta) + self.mgs_buffer_meta[mgsIdx].upgrade_mgs_to_support(mgs_con_meta) def allocate_mgs_buffer(self, mgs_con_meta): newStreamBuffer = MagicBufferMeta(mgs_con_meta.mgs_wrap_width, mgs_con_meta.mgs_row_idx_width, len(self.mgs_buffer_meta)) @@ -140,7 +174,7 @@ def get_existing_possible_mgs_buffer(self, mgs_con_meta): highest_possible_buffer = sorted(matched_buffer, key=lambda x: x.row_idx_width, reverse=True) - return None if len(highest_possible_buffer) == 0 else highest_possible_buffer[0] + return None if len(highest_possible_buffer) == 0 else highest_possible_buffer[0].mgs_idx def move_buffer_to_using_list(self, mgs_idx): ###### delete from free list first diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index 5b4685896b..30c3dbc566 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -9,7 +9,7 @@ from hls4ml.report import parse_vivado_report from hls4ml.writer.vitis_unified_partial_writer.meta_gen import VitisUnifiedPartial_MetaGen as mg -from magic_streamer_mng import MagicStreamerManager +from .magic_streamer_mng import MgsModel class VitisUnifiedPartialBackend(VitisUnifiedBackend): @@ -122,11 +122,12 @@ def create_initial_config( - def multigraph_augment_config(self, multi_model): + def augment_multigraph_config(self, multi_model): #### create magic streamer manager - mgs_mng = MagicStreamerManager(multi_model) - + mgs_mng = MgsModel(multi_model) + #### start retrieve the metadata + mgs_mng.start_convert_model() ########## fill to every posible graph to make it work multi_model.config.config["MagicStreamerMng"] = mgs_mng for subGraph in multi_model.graphs: diff --git a/hls4ml/backends/vivado/vivado_backend.py b/hls4ml/backends/vivado/vivado_backend.py index d5309c377f..5928d24218 100644 --- a/hls4ml/backends/vivado/vivado_backend.py +++ b/hls4ml/backends/vivado/vivado_backend.py @@ -288,6 +288,13 @@ def create_initial_config( return config + def augment_multigraph_config(self, multi_model_config): + """Augment the configuration of a multi-graph model.""" + """ + no return value + """ + pass + def build( self, model, diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index 352421e635..c110ac8726 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1042,10 +1042,11 @@ def __init__(self, graphs: list[ModelGraph], input_node_links = None): Create a stitched model from pre-optimized subgraphs. """ self.graphs = graphs + self.input_node_links = input_node_links self._initialize_config(self.graphs[0]) self._bind_modelgraph_methods() self._initialize_io_attributes(self.graphs) - self.input_node_links = input_node_links + @@ -1099,9 +1100,10 @@ def get_src_node_from_output_name(base_model: ModelGraph, output_name: str): def get_src_subGraph_and_output_idx(subGraphs, output_name): for gid, subGraph in enumerate(subGraphs): - for layer_name, node in subGraph.graph.items(): - if output_name in node.outputs: - return gid, node.outputs.indexOf(output_name) + if output_name in subGraph.outputs: + return gid, subGraph.outputs.index(output_name) + + return -1, -1 @@ -1125,20 +1127,28 @@ def group_for_creating_new_io(meta, isAnalyzeInput: bool): return rerouted_result @staticmethod - def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, input_raw, output_raw): + def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, input_raw: bool, output_raw: bool): ######### we focus on copy 'MultiGraphConfig' if 'MultiGraphConfig' in baseConfig: newConfig['MultiGraphConfig'] = copy.deepcopy(baseConfig.get('MultiGraphConfig', {})) ######## create the structure newConfig.setdefault('MultiGraphConfig', {}) - newConfig['MultiGraphConfig'].setdefault('amtGraph', -2) - newConfig['MultiGraphConfig'].setdefault('graphIdx', -2) + newConfig['MultiGraphConfig'].setdefault('amtGraph', amount_graph) + newConfig['MultiGraphConfig'].setdefault('graphIdx', graph_idx) newConfig['MultiGraphConfig'].setdefault('MgsMeta', []) newConfig['MultiGraphConfig'].setdefault('IOInterimType', {}) - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input', -2) - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', -2) + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input' , "io_free_stream" if input_raw else 'io_stream') + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', "io_free_stream" if output_raw else 'io_stream') + + @staticmethod + def print_input_node_link_debug(input_node_links): + print("------ input_node_links ----------") + for gid, input_metas in enumerate(input_node_links): + print(f" ----- @ graph idx {gid}") + for idx, (src_gid, src_output_idx) in enumerate(input_metas): + print(f" input {idx}: get data from graph {src_gid} output {src_output_idx}") ######## try to copy from the base model, if it it exist @@ -1209,7 +1219,9 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] named_new_input_layer = dict() #### inputIdx is index in input of target Node for inputIdx, targetNode in requiredReroute: ### note that tagetNode may be same within requiredRerote - ioName = targetNode.outputs[inputIdx] + if idx == 1: + print("debug here") + ioName = targetNode.inputs[inputIdx] ###### nodeUpdateList[0][1] is the sample Node (Layer) that must be inject to the system input_layer = cls._create_input_node(subgraph, targetNode, #### list of (inputIdx, Node) input_layer_kind, next_index, @@ -1220,7 +1232,9 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] targetNode.inputs[inputIdx] = input_layer.outputs[0] #### update link meta data - src_gid, src_graph_out_idx = cls.get_src_subGraph_and_output_idx(subgraphs, targetNode.outputs[inputIdx]) + if idx == 1: + print("debug here") + src_gid, src_graph_out_idx = cls.get_src_subGraph_and_output_idx(subgraphs, ioName) input_node_links[idx].append((src_gid, src_graph_out_idx)) @@ -1287,6 +1301,8 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] subgraphs.append(subgraph) + cls.print_input_node_link_debug(input_node_links) + return cls(subgraphs, input_node_links) @staticmethod @@ -1345,7 +1361,7 @@ def _initialize_config(self, first_graph): self.backend = first_graph.config.backend ####### after Multigraph split already some config may have been augment after - self.backend.writer.multigraph_augment_config(self) + self.backend.augment_multigraph_config(self) def _bind_modelgraph_methods(self): From fe9fe8bcf92930287fbdcd0bd779f61a4332f1e8 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 17:13:42 +0200 Subject: [PATCH 41/70] fix syntax generation for vitisUnified partialbackend --- .../vitis_unified_partial_backend.py | 12 ++++-------- hls4ml/backends/vivado/vivado_backend.py | 2 +- hls4ml/model/graph.py | 18 +++++++++++++----- .../vitis_unified_partial_writer/meta_gen.py | 2 +- .../vitis_unified_partial_writer/wrap_gen.py | 4 ++-- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index 30c3dbc566..1a225754af 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -18,6 +18,7 @@ def __init__(self): super(VivadoBackend, self).__init__(name='VitisUnifiedPartial') self._register_layer_attributes() self._register_flows() + self.mgs_model = None def build( @@ -122,19 +123,14 @@ def create_initial_config( - def augment_multigraph_config(self, multi_model): + def augment_multigraph_writer(self, multi_model): #### create magic streamer manager mgs_mng = MgsModel(multi_model) #### start retrieve the metadata mgs_mng.start_convert_model() - ########## fill to every posible graph to make it work - multi_model.config.config["MagicStreamerMng"] = mgs_mng - for subGraph in multi_model.graphs: - subGraph.config.config["MagicStreamerMng"] = mgs_mng - - - + #### assign mgs_mng writer in manager + self.writer.mgs_mng = mgs_mng def _register_flows(self): vitis_ip = 'vitis:ip' diff --git a/hls4ml/backends/vivado/vivado_backend.py b/hls4ml/backends/vivado/vivado_backend.py index 5928d24218..f54c03d63a 100644 --- a/hls4ml/backends/vivado/vivado_backend.py +++ b/hls4ml/backends/vivado/vivado_backend.py @@ -288,7 +288,7 @@ def create_initial_config( return config - def augment_multigraph_config(self, multi_model_config): + def augment_multigraph_writer(self, multi_model_config): """Augment the configuration of a multi-graph model.""" """ no return value diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index c110ac8726..5ba312b22d 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1139,8 +1139,16 @@ def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, i newConfig['MultiGraphConfig'].setdefault('MgsMeta', []) newConfig['MultiGraphConfig'].setdefault('IOInterimType', {}) - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input' , "io_free_stream" if input_raw else 'io_stream') - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', "io_free_stream" if output_raw else 'io_stream') + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input' , None ) + newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', None ) + + newConfig['MultiGraphConfig']['IOInterimType']['Input'] = "io_free_stream" if input_raw else 'io_stream' + newConfig['MultiGraphConfig']['IOInterimType']['Output'] = "io_free_stream" if output_raw else 'io_stream' + + + + + print(newConfig) @staticmethod def print_input_node_link_debug(input_node_links): @@ -1361,7 +1369,7 @@ def _initialize_config(self, first_graph): self.backend = first_graph.config.backend ####### after Multigraph split already some config may have been augment after - self.backend.augment_multigraph_config(self) + self.backend.augment_multigraph_writer(self) def _bind_modelgraph_methods(self): @@ -1688,7 +1696,7 @@ def _replace_logos(self): print(f'Error copying hls4ml logo to {g.config.get_output_dir()} project: {e}') -def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str]): +def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str], free_axi_interim = False): """ Create a MultiModelGraph by splitting a base ModelGraph before the specified layer names. @@ -1700,4 +1708,4 @@ def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str]): Returns: multi_model_graph (MultiModelGraph): the partitioned multi model graph """ - return MultiModelGraph.from_model_graph(model, split_before_layers) + return MultiModelGraph.from_model_graph(model, split_before_layers, free_axi_interim) diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py index 1884af5c6d..07c166d460 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py @@ -93,7 +93,7 @@ def get_dequeue_func_rstream2atom(self, tensorVar, idx: int, lastcheck: str,out_ @classmethod def get_dequeue_func_rstream2stream(self, tensorVar, idx: int, lastcheck: str): - result = "dequeue_layer2layer><{OUTPUT_LAYER_STREAM}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK})".format( + result = "dequeue_layer2layer<{OUTPUT_LAYER_STREAM}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK});".format( OUTPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), OUTPUT_LAYER_ARR = tensorVar.type.name, SIZE = str(tensorVar.size()), diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py index 44d5064544..5ba0e9c50e 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py @@ -18,14 +18,14 @@ def gen_io_str(self, mg,indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): for inp_idx, inp in enumerate(inps): inp_type = mg.get_dma_type_name() if (meta.vitis_unified_config.is_free_interim_input()) and \ - (meta.vitis_unified_config.getGraphIdx() != 0 ): + (meta.vitis_unified_config.get_graph_idx() != 0 ): inp_type = mg.get_axi_wrapper_type(inp) inputStreamList.append(f"{indent} hls::stream<{inp_type}>& {mg.get_io_port_name(inp, True, inp_idx)}") for out_idx, out in enumerate(outs): out_type = mg.get_dma_type_name() if (meta.vitis_unified_config.is_free_interim_output()) and \ - (meta.vitis_unified_config.getGraphIdx() != (meta.vitis_unified_config.getGraphAmtGraph()-1) ): + (meta.vitis_unified_config.get_graph_idx() != (meta.vitis_unified_config.get_amt_graph()-1) ): out_type = mg.get_axi_wrapper_type(out) outputStreamList.append(f"{indent} hls::stream<{out_type}>& {mg.get_io_port_name(out, False, out_idx)}") From 7b1b12b5b2e5334c57ede4db65026e622e9bb368 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 17:52:38 +0200 Subject: [PATCH 42/70] send magic streamer manager to writer --- .../vitis_unified_partial_backend.py | 2 +- hls4ml/model/graph.py | 2 +- hls4ml/writer/vitis_unified_partial_writer/__init__.py | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py index 1a225754af..cc0dccf92f 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py @@ -130,7 +130,7 @@ def augment_multigraph_writer(self, multi_model): #### start retrieve the metadata mgs_mng.start_convert_model() #### assign mgs_mng writer in manager - self.writer.mgs_mng = mgs_mng + self.writer.set_mgs_mng(mgs_mng) def _register_flows(self): vitis_ip = 'vitis:ip' diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index 5ba312b22d..da53f476e8 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1148,7 +1148,7 @@ def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, i - print(newConfig) + # print(newConfig) @staticmethod def print_input_node_link_debug(input_node_links): diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index 8c01a5fb6c..b7d8069dbe 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -35,6 +35,14 @@ def __init__(self): self.magic_gen = VitisUnifiedPartial_MagicArchGen + ################################################# + ######### magic streamer controller variable #### + ################################################# + self.mgs_mng = None + + def set_mgs_mng(self, mgs_mng): + self.mgs_mng = mgs_mng + def generate_config(self, model): from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig self.writer_meta.vitis_unified_config = VitisUnifiedPartialConfig( @@ -46,7 +54,7 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model, is_multigraph) - if False: + if is_multigraph: self.magic_gen.copyMagicArchIp(self.writer_meta, model) self.magic_gen.write_mgs(self.writer_meta, model) self.magic_gen.gen_vivado_project(self.writer_meta, model) \ No newline at end of file From b2f2238663ca25c08334e91d3575bda40a86cd8a Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 21:20:59 +0200 Subject: [PATCH 43/70] specify io signal meta-data to tcl file for each configuration --- .../magic_streamer_mng.py | 36 +++++++-- .../vitis_unified_partial_config.py | 12 ++- hls4ml/model/graph.py | 6 +- .../board_support/mga_meta.tcl | 24 +++--- .../vitis_unified_partial_writer/__init__.py | 5 +- .../vitis_unified_partial_writer/mgs_gen.py | 74 +++++++++++++++---- .../writer/vitis_unified_writer/__init__.py | 3 +- 7 files changed, 119 insertions(+), 41 deletions(-) diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py index 64249744a9..18ada1ad4a 100644 --- a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py +++ b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py @@ -94,11 +94,6 @@ def __init__(self, multigraph): self.mgs_buffer_holding = [] self.mgs_buffer_empty = [] - ############################################## - ############ start get the data ########### - ############################################## - - def start_convert_model(self): for gid, sub_graph in enumerate(self.multigraph.graphs): #### initialize the MgsConGraph @@ -109,9 +104,38 @@ def start_convert_model(self): #### start fill the metadata self.add_mgs_con_graph(mgs_con_graph) + print("finish_convert") + def add_mgs_con_graph(self, mgs_con_graph): self.con_graphs.append(mgs_con_graph) + ############################################## + ############ start get the data ########### + ############################################## + + def get_io_idx_for_all_mgs_buffer_with_dma(self, gid, is_input): + related_con_graph = self.con_graphs[gid] + io_con_meta_list = related_con_graph.input_cons if is_input else related_con_graph.output_cons + + result_list = [None for _ in range(len(self.mgs_buffer_meta))] + + dma_port = [] + + for io_idx, io_con_meta in enumerate(io_con_meta_list): + mgs_idx = io_con_meta.mgs_idx + if mgs_idx == -1: + dma_port.append(io_idx) + continue + result_list[mgs_idx] = io_idx + + ##### calculate with dma + if len(dma_port) > 1: + print("[warning] the system detect io port that should be used by dma is more than one") + result_list_with_dma = [None if len(dma_port) == 0 else dma_port[0]] + result_list_with_dma.extend(result_list) + + + return result_list_with_dma ### for outsider used def get_mgs_idx_src(self, gid, inputIdx): @@ -170,7 +194,7 @@ def get_existing_possible_mgs_buffer(self, mgs_con_meta): ##### filter the match buffer from exis matched_buffer = list(filter( lambda mgs: mgs.is_data_width_match(mgs_con_meta.mgs_wrap_width), - self.mgs_buffer_meta )) + self.mgs_buffer_empty )) highest_possible_buffer = sorted(matched_buffer, key=lambda x: x.row_idx_width, reverse=True) diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py index 3929c95976..4a31baf468 100644 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py +++ b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py @@ -9,7 +9,7 @@ class VitisUnifiedPartialConfig(VitisUnifiedConfig): - def __init__(self, config, model_inputs, model_outputs): + def __init__(self, config, model_inputs, model_outputs, mgs_mng): super().__init__(config, model_inputs, model_outputs) @@ -23,6 +23,8 @@ def __init__(self, config, model_inputs, model_outputs): self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('MgsMeta', None) + self.mgs_mng = mgs_mng + def get_dma_size(self): return 32 @@ -40,6 +42,10 @@ def get_graph_idx(self): return self.graph_idx def get_mgs_meta_list(self): - ### it is supposed to return [(dataWidth, IndexWidth, ...), ... ] - return self.mgs_meta + ### it is supposed to return list of MagicBufferMeta + return self.mgs_mng.mgs_buffer_meta + + ### get magic streamer + def get_mgs_mng(self): + return self.mgs_mng diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index da53f476e8..0c570c7b86 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1134,9 +1134,9 @@ def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, i newConfig['MultiGraphConfig'] = copy.deepcopy(baseConfig.get('MultiGraphConfig', {})) ######## create the structure newConfig.setdefault('MultiGraphConfig', {}) - newConfig['MultiGraphConfig'].setdefault('amtGraph', amount_graph) - newConfig['MultiGraphConfig'].setdefault('graphIdx', graph_idx) - newConfig['MultiGraphConfig'].setdefault('MgsMeta', []) + newConfig['MultiGraphConfig']['amtGraph'] = amount_graph + newConfig['MultiGraphConfig']['graphIdx'] = graph_idx + newConfig['MultiGraphConfig']['MgsMeta' ] = [] newConfig['MultiGraphConfig'].setdefault('IOInterimType', {}) newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input' , None ) diff --git a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl index c9ac26186a..680b5e5caa 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl @@ -5,12 +5,18 @@ set HLS_CFG_BANK_IDX_WIDTH VAL variable HLS_CFG_MGS_WRAP_WIDTH set HLS_CFG_MGS_WRAP_WIDTH VAL - - - - - - - - - +# HLS CFG MGS WRAP WIDTH the Val dma is include + +##### connection meta +variable HLS_CFG_MGS_M +set HLS_CFG_MGS_M VAL +variable HLS_CFG_MGS_S +set HLS_CFG_MGS_S VAL + +# kernel name setting +#### src repo path +variable HLS_CFG_HLS_SRC +set HLS_CFG_HLS_SRC VAL +#### top name +variable HLS_CFG_HLS_TOP_NAME +set HLS_CFG_HLS_TOP_NAME VAL diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py index b7d8069dbe..ebf981fa74 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_partial_writer/__init__.py @@ -46,7 +46,8 @@ def set_mgs_mng(self, mgs_mng): def generate_config(self, model): from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig self.writer_meta.vitis_unified_config = VitisUnifiedPartialConfig( - model.config, model.get_input_variables(), model.get_output_variables() + model.config, model.get_input_variables(), model.get_output_variables(), self.mgs_mng + ) @@ -57,4 +58,4 @@ def write_hls(self, model, is_multigraph=False): if is_multigraph: self.magic_gen.copyMagicArchIp(self.writer_meta, model) self.magic_gen.write_mgs(self.writer_meta, model) - self.magic_gen.gen_vivado_project(self.writer_meta, model) \ No newline at end of file + self.magic_gen.gen_vivado_project(self.writer_meta, model, self.mg) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index 073695596a..9712e8eaf1 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -7,10 +7,24 @@ from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta +#### This class is allowed for multigraph only class VitisUnifiedPartial_MagicArchGen(): + ########### allow for @classmethod - def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model): + def convert_idx_to_io_name(cls, list_of_io_idx, multi_graph, gid, is_input, default_name: str): + sub_graph = multi_graph.graphs[gid] + io_name_list = sub_graph.inputs if is_input else sub_graph.outputs + result_name_list = [] + for io_idx in list_of_io_idx: + if io_idx is None: + result_name_list.append(default_name) + else: + result_name_list.append(io_name_list[io_idx]) + return result_name_list + + @classmethod + def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) vivado_project_des_folder_path = f'{model.config.get_output_dir()}/vivado_project' @@ -36,21 +50,49 @@ def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model): fin = open(vivado_project_src_meta_arg_path, 'r') fout = open(des_projectscript_meta_arg_path, 'w') - meta_list = meta.vitis_unified_config.get_mgs_meta_list() + mgs_buffer_meta_list = meta.vitis_unified_config.get_mgs_meta_list() amt_subGraph = meta.vitis_unified_config.get_amt_graph() - meta_idx_width = str(max(0, int(math.ceil(math.log2(len(meta_list)))))) graph_idx_width = str(max(0, int(math.ceil(math.log2(amt_subGraph))))) for line in fin.readlines(): if "HLS_CFG_AMT_MGS" in line: - line = line.replace("VAL", str(len(meta_list))) + line = line.replace("VAL", str(len(mgs_buffer_meta_list))) if "HLS_CFG_BANK_IDX_WIDTH" in line: line = line.replace("VAL", graph_idx_width) if "HLS_CFG_MGS_WRAP_WIDTH" in line: width_list = ([str(meta.vitis_unified_config.get_dma_size())]) - width_list.extend([str(width) for width, *_ in meta_list]) + width_list.extend([str(magic_buffer_meta.data_width) for magic_buffer_meta in mgs_buffer_meta_list]) line = line.replace("VAL", "{"+ " ".join(width_list) + "}") + if "HLS_CFG_MGS_M" in line: + all_input_connect = [ ] #### each element is for each subgraph + for gid in range(meta.vitis_unified_config.get_amt_graph()): + mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma(gid, True) + input_connect_names = cls.convert_idx_to_io_name(mgs_buffer_con_idx, model, gid, True, "DUMMY") + input_connect_str = "{" + " ".join(input_connect_names) + "}" + all_input_connect.append(input_connect_str) + + line = line.replace("VAL", "{" + " ".join(all_input_connect) + "}") + + if "HLS_CFG_MGS_S" in line: + all_output_connect = [] #### each element is for each subgraph + for gid in range(meta.vitis_unified_config.get_amt_graph()): + mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma(gid, False) + output_connect_names = cls.convert_idx_to_io_name(mgs_buffer_con_idx, model, gid, False, "DUMMY") + output_connect_str = "{" + " ".join(output_connect_names) + "}" + all_output_connect.append(output_connect_str) + + line = line.replace("VAL", "{" + " ".join(all_output_connect) + "}") + + + if "HLS_CFG_HLS_SRC" in line: + kernel_paths = [sub_graph.config.get_output_dir() + "/unifiedWorkspace" for sub_graph in model.graphs] + line = line.replace("VAL", "{" + " ".join(kernel_paths) + "}") + if "HLS_CFG_HLS_TOP_NAME" in line: + kernel_topNames = [ mg.get_top_wrap_func_name(sub_graph) for sub_graph in model.graphs] + line = line.replace("VAL", "{" + " ".join(kernel_topNames) + "}") + + fout.write(line) fin .close() @@ -90,7 +132,7 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): fout = open(f'{model.config.get_output_dir()}/ips/magic_streamer_grp_src/streamGrp.v', 'w') - metaList = meta.vitis_unified_config.get_mgs_meta_list() + mgs_buffer_meta_list = meta.vitis_unified_config.get_mgs_meta_list() #### v------ mgs0 v--------- mgs1 #### [(data width, indexWidth, ....), (data width, indexWidth, ....)] @@ -99,16 +141,16 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): if "// hls4ml-streamGrp-gen-parameter" in line: parameterList = [] - for idx, (data_width, index_width, *_) in enumerate(metaList): - parameterList.append(f"parameter DATA_WIDTH_{idx+1} = {data_width}") - parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx+1} = {index_width}") + for idx, magic_buffer_meta in enumerate(mgs_buffer_meta_list): + parameterList.append(f"parameter DATA_WIDTH_{idx+1} = {magic_buffer_meta.data_width}") + parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx+1} = {magic_buffer_meta.row_idx_width}") parameterStr = ",\n".join(parameterList) newline += parameterStr + "\n" elif "// hls4ml-streamGrp-gen-io" in line: ioList = [] - for idx in range(1, len(metaList) + 1): + for idx in range(1, len(mgs_buffer_meta_list) + 1): ioList.append(f"//io for MGS{str(idx)}") ioList.append(f"input wire [DATA_WIDTH_{str(idx)} -1:0] S{str(idx)}_AXI_TDATA" ) ioList.append(f"input wire S{str(idx)}_AXI_TVALID") @@ -126,11 +168,11 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): ioList.append("//--------- Pool commanding ------------") ioList.append("///// for load [Reset/Init] of dma will be ignore") ioList.append("///// for store [Reset/Init] of dma will be ignore") - ioList.append(f"input wire[{len(metaList)}: 0] storeReset") - ioList.append(f"input wire[{len(metaList)}: 0] loadReset") - ioList.append(f"input wire[{len(metaList)}: 0] storeInit") - ioList.append(f"input wire[{len(metaList)}: 0] loadInit") - ioList.append(f"output wire[{len(metaList)}: 0] finStore") + ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] storeReset") + ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] loadReset") + ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] storeInit") + ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] loadInit") + ioList.append(f"output wire[{len(mgs_buffer_meta_list)}: 0] finStore") ioList.append(f"input wire finStoreProxyDma") newline += ",\n".join(ioList) + ",\n" @@ -142,7 +184,7 @@ def write_mgs(self, meta: VitisUnifiedWriterMeta, model): elif "// hls4ml-streamGrp-gen-create-module" in line: - for idx in range(1, len(metaList)+1): + for idx in range(1, len(mgs_buffer_meta_list)+1): newline += f"//create module for MGS{str(idx)}\n" newline += f"MagicStreammerCore #(\n" newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 9744f36d1b..aac590b381 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -72,9 +72,8 @@ def write_hls(self, model, is_multigraph=False): super().write_hls(model, is_multigraph = True) return + ##### generate kernel and its driver self.generate_config(model) - - super().write_hls(model, is_multigraph = False) self.wg.write_wrapper(self.writer_meta, model, self.mg) From 654724a3bc3aebd6fdd145616211355cbe32ec36 Mon Sep 17 00:00:00 2001 From: tanawin Date: Mon, 25 Aug 2025 22:29:54 +0200 Subject: [PATCH 44/70] add build for stitcher --- hls4ml/model/graph.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index 0c570c7b86..03727cbdad 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1499,6 +1499,8 @@ def build_wrapper(idx, g, **kwargs): self.graph_reports = build_results + self.backend.build(self, compose_streamers = True) + if stitch_design or sim_stitched_design or export_stitched_design: failed_graphs = [name for name, report in build_results.items() if report is None] if failed_graphs: From 95148d8ad6c2f8c4c145e416da5cb3c4f98b1a64 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 01:32:41 +0200 Subject: [PATCH 45/70] update vivado project stitcher script --- .../board_support/mga_meta.tcl | 6 +- .../board_support/zcu102/project_builder.tcl | 237 +++++++++++++++++- .../vitis_unified_partial_writer/mgs_gen.py | 35 +-- 3 files changed, 258 insertions(+), 20 deletions(-) diff --git a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl index 680b5e5caa..baffb6f132 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl @@ -8,10 +8,12 @@ set HLS_CFG_MGS_WRAP_WIDTH VAL # HLS CFG MGS WRAP WIDTH the Val dma is include ##### connection meta -variable HLS_CFG_MGS_M -set HLS_CFG_MGS_M VAL +######### input variable HLS_CFG_MGS_S set HLS_CFG_MGS_S VAL +variable HLS_CFG_MGS_M +######### output +set HLS_CFG_MGS_M VAL # kernel name setting #### src repo path diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl index 771dd8e7aa..bb3bf6bc1d 100644 --- a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl +++ b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl @@ -11,22 +11,36 @@ set script_file "project_builder.tcl" # Create project create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xczu9eg-ffvb1156-2-e +source mga_meta.tcl + # Set the directory path for the new project set proj_dir [get_property directory [current_project]] # Set project properties set obj [current_project] -set_property ip_repo_paths ../ips $obj +# set_property ip_repo_paths ../ips $obj +# update_ip_catalog + +# foreach ip_dir $HLS_CFG_HLS_SRC { +# update_ip_catalog -add $ip_dir -repo_path $ip_dir +# } +# update_ip_catalog + +set HLS_CFG_HLS_ALL_IP {} +foreach dir $HLS_CFG_HLS_SRC { + lappend HLS_CFG_HLS_ALL_IP $dir +} +lappend HLS_CFG_HLS_ALL_IP ../ips +set_property ip_repo_paths $HLS_CFG_HLS_ALL_IP $obj update_ip_catalog set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj -source mga_meta.tcl proc cr_bd_system {} { - global HLS_CFG_AMT_MGS HLS_CFG_MGS_INDEX HLS_CFG_BANK_IDX_WIDTH HLS_CFG_MGS_WRAP_WIDTH + global HLS_CFG_AMT_MGS HLS_CFG_MGS_INDEX HLS_CFG_BANK_IDX_WIDTH HLS_CFG_MGS_WRAP_WIDTH HLS_CFG_MGS_S HLS_CFG_MGS_M HLS_CFG_HLS_TOP_NAME set design_name system create_bd_design $design_name @@ -338,6 +352,173 @@ proc cr_bd_system {} { #### return to old instance current_bd_instance $oldCurInst + } + + proc convert_hier_cell_dfx_to_bd {} { + + + set oldCurInst [current_bd_instance .] + + ### create block design container + validate_bd_design + startgroup + set curdesign [current_bd_design] + create_bd_design -cell [get_bd_cells /dfx_par] dfx_par + current_bd_design $curdesign + set new_cell [create_bd_cell -type container -reference dfx_par dfx_par_temp] + replace_bd_cell [get_bd_cells /dfx_par] $new_cell + delete_bd_objs [get_bd_cells /dfx_par] + set_property name dfx_par $new_cell + endgroup + ### set property for dfx_par to be dfx region + set_property CONFIG.ENABLE_DFX {true} [get_bd_cells dfx_par] + validate_bd_design + + current_bd_instance $oldCurInst + validate_bd_design + save_bd_design + + current_bd_design [get_bd_designs system] + + + } + + proc build_reconfig_module {} { + + ############################################### + ################# create reconfig module ###### + ############################################### + current_bd_design [get_bd_designs system] + + set curdesign [current_bd_design] + + create_bd_design -boundary_from_container [get_bd_cells /dfx_par] dfx_par_1 + + current_bd_design $curdesign + set_property -dict [list CONFIG.LIST_SYNTH_BD {dfx_par.bd:dfx_par_1.bd} CONFIG.LIST_SIM_BD {dfx_par.bd:dfx_par_1.bd}] [get_bd_cells /dfx_par] + + current_bd_design $curdesign + current_bd_design [get_bd_designs dfx_par_1] + + + + ################################################ + ################### add cell ################### + ################################################ + + startgroup + create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_graph1_axis:1.0 myproject_graph1_axis_0 + endgroup + + ################################################ + ################### do connection ############## + ################################################ + + connect_bd_intf_net [get_bd_intf_ports S_AXI_0] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_in0_input_1] + connect_bd_intf_net [get_bd_intf_ports M_AXI_0] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_out0_layer13_cpy2] + connect_bd_intf_net [get_bd_intf_ports M_AXI_1] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_out1_layer15_out] + connect_bd_net [get_bd_ports clk] [get_bd_pins myproject_graph1_axis_0/ap_clk] + connect_bd_net [get_bd_ports nreset] [get_bd_pins myproject_graph1_axis_0/ap_rst_n] + + validate_bd_design + + save_bd_design + + current_bd_design [get_bd_designs system] + + + + } + + proc build_reconfig_module2 { gid top_func_name input_list output_list dataWidths } { + + current_bd_design [get_bd_designs system] + + set curdesign [current_bd_design] + + create_bd_design -boundary_from_container [get_bd_cells /dfx_par] dfx_par_${gid} + + ################################################ + #### switch back to system to set the config ### + ################################################ + current_bd_design $curdesign + #set_property -dict [list CONFIG.LIST_SYNTH_BD {dfx_par.bd:dfx_par_${gid}.bd} CONFIG.LIST_SIM_BD {dfx_par.bd:dfx_par_${gid}.bd}] [get_bd_cells /dfx_par] + + ################################################ + #### switch back to the reconfig module ######## + ################################################ + + current_bd_design $curdesign + current_bd_design [get_bd_designs dfx_par_${gid}] + ################################################ + #### create cell ######## + ################################################ + + startgroup + create_bd_cell -type ip -vlnv xilinx.com:hls:${top_func_name}:1.0 ${top_func_name}_0 + endgroup + + ################################################ + #### do connection input ####################### + ################################################ + + for {set mgs_buffer_idx 0} {$mgs_buffer_idx < [llength $input_list]} {incr mgs_buffer_idx} { + set kernel_port_name [lindex $input_list $mgs_buffer_idx] + + + switch -- $kernel_port_name { + "DUMMY" { + ####### create dummy stream slave + set DummyStreamSlave_${mgs_buffer_idx} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${mgs_buffer_idx} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $mgs_buffer_idx] [get_bd_cells DummyStreamSlave_${mgs_buffer_idx}] + + connect_bd_intf_net -intf_net DummyStreamSlave_${mgs_buffer_idx} [get_bd_intf_pins S_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins DummyStreamSlave_${mgs_buffer_idx}/S_AXI] + connect_bd_net -net clk_internal [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${mgs_buffer_idx}/clk] + connect_bd_net -net nreset_internal [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${mgs_buffer_idx}/reset] + + } + default { + connect_bd_intf_net -intf_net ${kernel_port_name} [get_bd_intf_pins S_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins ${top_func_name}_0/${kernel_port_name}] + } + } + } + + ################################################ + #### do connection output ###################### + ################################################ + + for {set mgs_buffer_idx 0} {$mgs_buffer_idx < [llength $output_list]} {incr mgs_buffer_idx} { + set kernel_port_name [lindex $output_list $mgs_buffer_idx] + + + switch -- $kernel_port_name { + "DUMMY" { + ####### create dummy stream slave + set DummyStreamMaster_${mgs_buffer_idx} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${mgs_buffer_idx} ] + set_property CONFIG.DATA_WIDTH [lindex $dataWidths $mgs_buffer_idx] [get_bd_cells DummyStreamMaster_${mgs_buffer_idx}] + + connect_bd_intf_net -intf_net DummyStreamMaster_${mgs_buffer_idx} [get_bd_intf_pins M_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins DummyStreamMaster_${mgs_buffer_idx}/M_AXI] + connect_bd_net -net clk_internal [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${mgs_buffer_idx}/clk] + connect_bd_net -net nreset_internal [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${mgs_buffer_idx}/reset] + + } + default { + connect_bd_intf_net -intf_net ${kernel_port_name} [get_bd_intf_pins M_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins ${top_func_name}_0/${kernel_port_name}] + } + } + } + + connect_bd_net [get_bd_ports clk] [get_bd_pins ${top_func_name}_0/ap_clk] + connect_bd_net [get_bd_ports nreset] [get_bd_pins ${top_func_name}_0/ap_rst_n] + + + validate_bd_design + save_bd_design + current_bd_design [get_bd_designs system] + + + + } # set parentObj "" @@ -824,6 +1005,56 @@ proc cr_bd_system {} { delete_bd_objs [get_bd_addr_segs] [get_bd_addr_segs -excluded] assign_bd_address + convert_hier_cell_dfx_to_bd + #build_reconfig_module + + set n [llength $HLS_CFG_HLS_TOP_NAME] + + # Loop over each outer list index + for {set i 0} {$i < $n} {incr i} { + # Get sublists at index 0 of each inner list + set input_meta [lindex $HLS_CFG_MGS_S $i] + set output_meta [lindex $HLS_CFG_MGS_M $i] + set top_name [lindex $HLS_CFG_HLS_TOP_NAME $i] + + + build_reconfig_module2 $i $top_name $input_meta $output_meta $HLS_CFG_MGS_WRAP_WIDTH + + } + + current_bd_design [get_bd_designs system] + validate_bd_design + save_bd_design + + + #################################### + ### do dfx config ################## + #################################### + + + # # initialize the list with the main dfx_par.bd + set dfx_grp_list {"dfx_par.bd"} + + # append dynamic groups + for {set i 0} {$i < $n} {incr i} { + lappend dfx_grp_list "dfx_par_$i.bd" + } + + # join the list with colon ":" for the property string + set dfx_str [join $dfx_grp_list ":"] + + # set the properties + set_property -dict [list \ + CONFIG.LIST_SIM_BD "$dfx_str" \ + CONFIG.LIST_SYNTH_BD "$dfx_str" \ + ] [get_bd_cells dfx_par] + + current_bd_design [get_bd_designs system] + validate_bd_design + save_bd_design + + + } diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py index 9712e8eaf1..db9e28e1bf 100644 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py @@ -12,15 +12,17 @@ class VitisUnifiedPartial_MagicArchGen(): ########### allow for @classmethod - def convert_idx_to_io_name(cls, list_of_io_idx, multi_graph, gid, is_input, default_name: str): + def convert_idx_to_io_name(cls, meta, mg, list_of_io_idx, multi_graph, gid, is_input, default_name: str): + inp_axis_t, out_axis_t, inps, outs = meta.vitis_unified_config.get_corrected_types() sub_graph = multi_graph.graphs[gid] - io_name_list = sub_graph.inputs if is_input else sub_graph.outputs + io_tensor = sub_graph.get_input_variables() if is_input else sub_graph.get_output_variables() result_name_list = [] for io_idx in list_of_io_idx: if io_idx is None: result_name_list.append(default_name) else: - result_name_list.append(io_name_list[io_idx]) + io_name = mg.get_io_port_name(io_tensor[io_idx], is_input, io_idx) + result_name_list.append(io_name) return result_name_list @classmethod @@ -65,25 +67,28 @@ def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model, mg): width_list.extend([str(magic_buffer_meta.data_width) for magic_buffer_meta in mgs_buffer_meta_list]) line = line.replace("VAL", "{"+ " ".join(width_list) + "}") if "HLS_CFG_MGS_M" in line: - all_input_connect = [ ] #### each element is for each subgraph - for gid in range(meta.vitis_unified_config.get_amt_graph()): - mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma(gid, True) - input_connect_names = cls.convert_idx_to_io_name(mgs_buffer_con_idx, model, gid, True, "DUMMY") - input_connect_str = "{" + " ".join(input_connect_names) + "}" - all_input_connect.append(input_connect_str) - - line = line.replace("VAL", "{" + " ".join(all_input_connect) + "}") - - if "HLS_CFG_MGS_S" in line: + #### output side all_output_connect = [] #### each element is for each subgraph for gid in range(meta.vitis_unified_config.get_amt_graph()): - mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma(gid, False) - output_connect_names = cls.convert_idx_to_io_name(mgs_buffer_con_idx, model, gid, False, "DUMMY") + mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma( + gid, False) + output_connect_names = cls.convert_idx_to_io_name(meta, mg, mgs_buffer_con_idx, model, gid, False, "DUMMY") output_connect_str = "{" + " ".join(output_connect_names) + "}" all_output_connect.append(output_connect_str) line = line.replace("VAL", "{" + " ".join(all_output_connect) + "}") + if "HLS_CFG_MGS_S" in line: + #### input side + all_input_connect = [] #### each element is for each subgraph + for gid in range(meta.vitis_unified_config.get_amt_graph()): + mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma( + gid, True) + input_connect_names = cls.convert_idx_to_io_name(meta, mg, mgs_buffer_con_idx, model, gid, True, "DUMMY") + input_connect_str = "{" + " ".join(input_connect_names) + "}" + all_input_connect.append(input_connect_str) + + line = line.replace("VAL", "{" + " ".join(all_input_connect) + "}") if "HLS_CFG_HLS_SRC" in line: kernel_paths = [sub_graph.config.get_output_dir() + "/unifiedWorkspace" for sub_graph in model.graphs] From 3de044468ee70e62fab0bb86de389e1f27ed39ae Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 13:53:36 +0200 Subject: [PATCH 46/70] delete vitis Unified partial after merge the co-reactor --- hls4ml/backends/__init__.py | 20 +- .../vitis_unified/supported_boards.json | 14 -- .../vitis_unified_partial/__init__.py | 0 .../magic_streamer_mng.py | 213 ----------------- .../vitis_unified_partial_backend.py | 139 ----------- .../vitis_unified_partial_config.py | 51 ---- hls4ml/writer/__init__.py | 2 - .../vitis_unified_partial_writer/__init__.py | 61 ----- .../driver_gen.py | 26 -- .../vitis_unified_partial_writer/meta.py | 2 - .../vitis_unified_partial_writer/meta_gen.py | 106 --------- .../vitis_unified_partial_writer/mgs_gen.py | 223 ------------------ .../test_bridge_gen.py | 37 --- .../test_cosim_gen.py | 25 -- .../vitis_unified_partial_writer/wrap_gen.py | 152 ------------ 15 files changed, 8 insertions(+), 1063 deletions(-) delete mode 100644 hls4ml/backends/vitis_unified/supported_boards.json delete mode 100644 hls4ml/backends/vitis_unified_partial/__init__.py delete mode 100644 hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py delete mode 100644 hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py delete mode 100644 hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/__init__.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/driver_gen.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/meta.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/meta_gen.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py delete mode 100644 hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 800d3935c0..2a53a50aca 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -14,15 +14,11 @@ from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig -from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_backend import VitisUnifiedPartialBackend -from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig - -register_backend('Vivado', VivadoBackend) -register_backend('VivadoAccelerator', VivadoAcceleratorBackend) -register_backend('Vitis', VitisBackend) -register_backend('VitisUnified', VitisUnifiedBackend) -register_backend('VitisUnifiedPartial', VitisUnifiedPartialBackend) -register_backend('Quartus', QuartusBackend) -register_backend('Catapult', CatapultBackend) -register_backend('SymbolicExpression', SymbolicExpressionBackend) -register_backend('oneAPI', OneAPIBackend) +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) +register_backend('oneAPI' , OneAPIBackend) diff --git a/hls4ml/backends/vitis_unified/supported_boards.json b/hls4ml/backends/vitis_unified/supported_boards.json deleted file mode 100644 index 4a54ea2924..0000000000 --- a/hls4ml/backends/vitis_unified/supported_boards.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pynq-z2": { - "part": "xc7z020clg400-1", - "tcl_scripts": {"axi_lite": "axi_lite_design.tcl", "axi_stream": "axi_stream_design.tcl"}, - "python_drivers": {"axi_stream": "axi_stream_driver.py"}, - "c_drivers": {} - }, - "zcu102": { - "part": "xczu9eg-ffvb1156-2-e", - "tcl_scripts": { "axi_stream": "axi_stream_design.tcl"}, - "python_drivers": {"axi_stream": "axi_stream_driver.py"}, - "c_drivers": {} - } -} diff --git a/hls4ml/backends/vitis_unified_partial/__init__.py b/hls4ml/backends/vitis_unified_partial/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py b/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py deleted file mode 100644 index 18ada1ad4a..0000000000 --- a/hls4ml/backends/vitis_unified_partial/magic_streamer_mng.py +++ /dev/null @@ -1,213 +0,0 @@ -class MgsConMeta: - #### - def __init__(self, io_idx, tensor): - self.io_idx = io_idx - self.mgs_idx = -1 - self.mgs_wrap_width = 32 - self.mgs_row_idx_width = 10 - - -class MagicBufferMeta: - def __init__(self, data_width, row_idx_width, mgs_idx): - self.data_width = data_width - self.row_idx_width = row_idx_width - self.mgs_idx = mgs_idx - - def upgrade_mgs_to_support(self, mgs_con_meta): - if self.row_idx_width < mgs_con_meta.mgs_row_idx_width: - self.row_idx_width = mgs_con_meta.mgs_row_idx_width - - - def is_data_width_match(self, check_width): - return self.data_width == check_width - - #### the shared class between subgraph and host graph - -class MgsConGraph: - #### in suppose to be pool of connection for each sub graph - - def __init__(self, gid, input_node_links, amt_graph, mgs_model): ### gid = graph id - self.gid = gid - self.input_cons = [] #### the index of the list supposed to be the index of the input port as well - self.output_cons = [] - self.input_node_links = input_node_links - self.amt_graph = amt_graph - self.mgs_model = mgs_model - - def start_convert_graph(self, graph): - #### do the output first because we need to not free the src first (src des cannot be the same buffer) - out_var = graph.get_output_variables() - for out_idx, out in enumerate(out_var): - mgs_con_meta = MgsConMeta(out_idx, out) - self.add_output_con(mgs_con_meta) - - #### do the input - in_var = graph.get_input_variables() - for in_idx, inp in enumerate(in_var): - mgs_con_meta = MgsConMeta(in_idx, inp) - self.add_input_con(mgs_con_meta) - - def is_last_graph(self): - return (self.gid + 1) == self.amt_graph - - def add_input_con(self, mgs_con_meta): - - src_gid, src_out_idx = self.input_node_links[self.gid][mgs_con_meta.io_idx] - - #### it load from dma - if src_gid == -1: - src_mgs_idx = -1 ##### it means dma - else: - src_mgs_con_meta = self.mgs_model.get_mgs_idx(src_gid, src_out_idx) - mgs_con_meta.mgs_idx = src_mgs_con_meta - self.mgs_model.move_buffer_to_free_list(src_mgs_con_meta) - - self.input_cons.append(mgs_con_meta) - - def add_output_con(self, mgs_con_meta): - - if self.is_last_graph(): - self.output_cons.append(mgs_con_meta) - return - - ###### we check the - stream_buffer_idx = self.mgs_model.get_existing_possible_mgs_buffer(mgs_con_meta) - - if stream_buffer_idx is None: - stream_buffer_idx = self.mgs_model.allocate_mgs_buffer(mgs_con_meta) - - ##### upgrade the magic stream buffer to match size of it is lower - self.mgs_model.upgrade_mgs_to_support(mgs_con_meta, stream_buffer_idx) - - self.mgs_model.move_buffer_to_using_list(stream_buffer_idx) - mgs_con_meta.mgs_idx = stream_buffer_idx - - - self.output_cons.append(mgs_con_meta) - -class MgsModel: - def __init__(self, multigraph): - self.multigraph = multigraph - self.con_graphs = [] - self.mgs_buffer_meta = [] #### index of the system supposed to be magic streamer and its port id - - self.mgs_buffer_holding = [] - self.mgs_buffer_empty = [] - - def start_convert_model(self): - for gid, sub_graph in enumerate(self.multigraph.graphs): - #### initialize the MgsConGraph - input_node_link = self.multigraph.input_node_links - amt_graph = len(self.multigraph.graphs) - mgs_con_graph = MgsConGraph(gid, input_node_link, amt_graph, self) - mgs_con_graph.start_convert_graph(sub_graph) - #### start fill the metadata - self.add_mgs_con_graph(mgs_con_graph) - - print("finish_convert") - - def add_mgs_con_graph(self, mgs_con_graph): - self.con_graphs.append(mgs_con_graph) - - ############################################## - ############ start get the data ########### - ############################################## - - def get_io_idx_for_all_mgs_buffer_with_dma(self, gid, is_input): - related_con_graph = self.con_graphs[gid] - io_con_meta_list = related_con_graph.input_cons if is_input else related_con_graph.output_cons - - result_list = [None for _ in range(len(self.mgs_buffer_meta))] - - dma_port = [] - - for io_idx, io_con_meta in enumerate(io_con_meta_list): - mgs_idx = io_con_meta.mgs_idx - if mgs_idx == -1: - dma_port.append(io_idx) - continue - result_list[mgs_idx] = io_idx - - ##### calculate with dma - if len(dma_port) > 1: - print("[warning] the system detect io port that should be used by dma is more than one") - result_list_with_dma = [None if len(dma_port) == 0 else dma_port[0]] - result_list_with_dma.extend(result_list) - - - return result_list_with_dma - - ### for outsider used - def get_mgs_idx_src(self, gid, inputIdx): - if gid not in range(0, self.multigraph.amt_graph): - raise Exception( - "get_mgs_idx_src: gid {gid} is out of bound. The amount of graph is {amt_graph}".format( - gid=gid, amt_graph=self.multigraph.amt_graph - ) - ) - if inputIdx not in range(0, len(self.con_graphs[gid].input_cons)): - raise Exception( - "get_mgs_idx_src: inputIdx {inputIdx} is out of bound. The amount of input is {input_num}".format( - inputIdx=inputIdx, input_num=len(self.con_graphs[gid].input_cons) - ) - ) - return self.con_graphs[gid].input_cons[inputIdx].mgs_idx - ### for outsider usd - def get_mgs_idx_dst(self, gid, outputIdx): - if gid not in range(0, self.multigraph.amt_graph): - raise Exception( - "get_mgs_idx_dst: gid {gid} is out of bound. The amount of graph is {amt_graph}".format( - gid=gid, amt_graph=self.multigraph.amt_graph - ) - ) - if outputIdx not in range(0, len(self.con_graphs[gid].output_cons)): - raise Exception( - "get_mgs_idx_dst: outputIdx {outputIdx} is out of bound. The amount of output is {output_num}".format( - outputIdx=outputIdx, output_num=len(self.con_graphs[gid].output_cons) - ) - ) - return self.con_graphs[gid].output_cons[outputIdx].mgs_idx - - ############################################## - ############ magic streamer buffer ########### - ############################################## - - ##### used by the vitis uniifed partial backend writer and MgsConGraph - def get_mgs_idx(self, gid, outputIdx): - if gid < 0: - return -1 - mgs_con_meta = self.con_graphs[gid].output_cons[outputIdx] - return mgs_con_meta.mgs_idx - - def upgrade_mgs_to_support(self, mgs_con_meta, mgsIdx): - if mgsIdx >= len(self.mgs_buffer_meta) or mgsIdx < 0: - raise Exception("upgrade magic streamer with Idx {mgsIdx} is out of bound.") - self.mgs_buffer_meta[mgsIdx].upgrade_mgs_to_support(mgs_con_meta) - - def allocate_mgs_buffer(self, mgs_con_meta): - newStreamBuffer = MagicBufferMeta(mgs_con_meta.mgs_wrap_width, mgs_con_meta.mgs_row_idx_width, len(self.mgs_buffer_meta)) - mgs_idx = len(self.mgs_buffer_meta) - self.mgs_buffer_meta.append(newStreamBuffer) - return mgs_idx - - def get_existing_possible_mgs_buffer(self, mgs_con_meta): - ##### filter the match buffer from exis - matched_buffer = list(filter( - lambda mgs: mgs.is_data_width_match(mgs_con_meta.mgs_wrap_width), - self.mgs_buffer_empty )) - - highest_possible_buffer = sorted(matched_buffer, key=lambda x: x.row_idx_width, reverse=True) - - return None if len(highest_possible_buffer) == 0 else highest_possible_buffer[0].mgs_idx - - def move_buffer_to_using_list(self, mgs_idx): - ###### delete from free list first - self.mgs_buffer_empty = list(filter(lambda x: x.mgs_idx != mgs_idx, self.mgs_buffer_empty)) - ###### add to holding list - self.mgs_buffer_holding.append(self.mgs_buffer_meta[mgs_idx]) - - def move_buffer_to_free_list(self, mgs_idx): - ###### delete from holding list first - self.mgs_buffer_holding = list(filter(lambda x: x.mgs_idx != mgs_idx, self.mgs_buffer_holding)) - ###### add to free list - self.mgs_buffer_empty.append(self.mgs_buffer_meta[mgs_idx]) \ No newline at end of file diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py deleted file mode 100644 index cc0dccf92f..0000000000 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_backend.py +++ /dev/null @@ -1,139 +0,0 @@ -import os -import sys -import subprocess -from shutil import copy2 - - -from hls4ml.backends import VitisUnifiedBackend, VivadoBackend -from hls4ml.model.flow import register_flow -from hls4ml.report import parse_vivado_report -from hls4ml.writer.vitis_unified_partial_writer.meta_gen import VitisUnifiedPartial_MetaGen as mg - -from .magic_streamer_mng import MgsModel - - -class VitisUnifiedPartialBackend(VitisUnifiedBackend): - - def __init__(self): - super(VivadoBackend, self).__init__(name='VitisUnifiedPartial') - self._register_layer_attributes() - self._register_flows() - self.mgs_model = None - - - def build( - self, - model, - reset=False, - csim=False, - synth=False, - cosim=False, - validation=False, - export=False, - vsynth=False, - fifo_opt=False, - bitfile=False, - log_to_stdout=True, - compose_streamers=False - ): - - ##### do magic streamer generation - if compose_streamers: - #### generate magic sequencer wrapper - magic_stream_grp_ip_prj = f'{model.config.get_output_dir()}/ips/magic_streamer_grp_prj' - self.run_term_command(model, - "magic_streamer_ip_generation", - "vivado -mode gui -source composer.tcl", log_to_stdout, - magic_stream_grp_ip_prj - ) - #### generate vivado project - magic_arch_prj = f"{model.config.get_output_dir()}/vivado_project" - self.run_term_command(model, - "magic_streamer_arch_generation", - "vivado -mode gui -source project_builder.tcl", log_to_stdout, - magic_arch_prj) - - # super().build( - # model, - # reset, - # csim, - # synth, - # cosim, - # validation, - # export, - # vsynth, - # fifo_opt, - # bitfile, - # log_to_stdout - # ) - - def create_initial_config( - self, - board='pynq-z2', - part=None, - clock_period=5, - clock_uncertainty='12.5%', - io_type='io_parallel', - interface='axi_stream', - driver='python', - input_type='float', - output_type='float', - gmemBuf_in_size=12, - gmemBuf_out_size=12, - xpfmPath='/tools/Xilinx/Vitis/2023.2/base_platforms/' - 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', - input_interim_type='io_stream', #### it should be io_stream or io_free_stream/ io_stream - output_interim_type='io_stream', - init_mgs_meta=None, - init_amt_graph=3, - **_ - ): - - if init_mgs_meta is None: - init_mgs_meta = list() - if init_mgs_meta is None: - init_mgs_meta = [] - config = super().create_initial_config( - board=board, - part=part, - clock_period=clock_period, - clock_uncertainty=clock_uncertainty, - io_type=io_type, - interface=interface, - driver=driver, - input_type=input_type, - output_type=output_type, - gmemBuf_in_size=1, - gmemBuf_out_size=1, - xpfmPath=xpfmPath - ) - - config['MultiGraphConfig'] = {} - config['MultiGraphConfig']['amtGraph'] = init_amt_graph # it should be set by the multigraph system - config['MultiGraphConfig']['graphIdx'] = -1 # -1 means unset yet or it is multigraph stitcher - print(f"mgs initial is set to {init_mgs_meta}") - - config['MultiGraphConfig']['IOInterimType'] = {} - config['MultiGraphConfig']['IOInterimType']['Input'] = input_interim_type - config['MultiGraphConfig']['IOInterimType']['Output'] = output_interim_type - - config['MagicStreamerMng'] = None - - return config - - - - def augment_multigraph_writer(self, multi_model): - - #### create magic streamer manager - mgs_mng = MgsModel(multi_model) - #### start retrieve the metadata - mgs_mng.start_convert_model() - #### assign mgs_mng writer in manager - self.writer.set_mgs_mng(mgs_mng) - - def _register_flows(self): - vitis_ip = 'vitis:ip' - writer_passes = ['make_stamp', 'vitisunifiedpartial:write_hls'] - self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name) - self._default_flow = vitis_ip \ No newline at end of file diff --git a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py b/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py deleted file mode 100644 index 4a31baf468..0000000000 --- a/hls4ml/backends/vitis_unified_partial/vitis_unified_partial_config.py +++ /dev/null @@ -1,51 +0,0 @@ -import json -import os - -import numpy as np - -from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig - - -class VitisUnifiedPartialConfig(VitisUnifiedConfig): - - - def __init__(self, config, model_inputs, model_outputs, mgs_mng): - - super().__init__(config, model_inputs, model_outputs) - - self.free_interim_input = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get( - "Input") == "io_free_stream" - self.free_interim_output = self.config.get('MultiGraphConfig', {}).get('IOInterimType', {}).get( - "Output") == "io_free_stream" - - self.amt_graph = self.config.get('MultiGraphConfig', {}).get('amtGraph', -1) - self.graph_idx = self.config.get('MultiGraphConfig', {}).get('graphIdx', -1) - - self.mgs_meta = self.config.get('MultiGraphConfig', {}).get('MgsMeta', None) - - self.mgs_mng = mgs_mng - - - def get_dma_size(self): - return 32 - - def is_free_interim_input(self): - return self.free_interim_input - - def is_free_interim_output(self): - return self.free_interim_output - - def get_amt_graph(self): - return self.amt_graph - - def get_graph_idx(self): - return self.graph_idx - - def get_mgs_meta_list(self): - ### it is supposed to return list of MagicBufferMeta - return self.mgs_mng.mgs_buffer_meta - - ### get magic streamer - def get_mgs_mng(self): - return self.mgs_mng - diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 903867afa8..48897ce1a7 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -4,7 +4,6 @@ from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter from hls4ml.writer.vitis_writer import VitisWriter from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter -from hls4ml.writer.vitis_unified_partial_writer import VitisUnifiedPartialWriter from hls4ml.writer.vivado_accelerator_writer import VivadoAcceleratorWriter from hls4ml.writer.vivado_writer import VivadoWriter from hls4ml.writer.writers import Writer, get_writer, register_writer # noqa: F401 @@ -13,7 +12,6 @@ register_writer('VivadoAccelerator', VivadoAcceleratorWriter) register_writer('Vitis', VitisWriter) register_writer('VitisUnified', VitisUnifiedWriter) -register_writer('VitisUnifiedPartial', VitisUnifiedPartialWriter) register_writer('Quartus', QuartusWriter) register_writer('oneAPI', OneAPIWriter) register_writer('Catapult', CatapultWriter) diff --git a/hls4ml/writer/vitis_unified_partial_writer/__init__.py b/hls4ml/writer/vitis_unified_partial_writer/__init__.py deleted file mode 100644 index ebf981fa74..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ - -from hls4ml.writer.vitis_unified_writer import VitisUnifiedWriter - - -class VitisUnifiedPartialWriter(VitisUnifiedWriter): - - def __init__(self): - super().__init__() - - #from .build_gen import VitisUnifiedPartial_BuildGen - from .driver_gen import VitisUnifiedPartial_DriverGen - from .meta_gen import VitisUnifiedPartial_MetaGen - from .test_bridge_gen import VitisUnifiedPartial_BridgeGen - from .test_cosim_gen import VitisUnifiedPartial_TestGen - from .wrap_gen import VitisUnifiedPartial_WrapperGen - - from .mgs_gen import VitisUnifiedPartial_MagicArchGen - - - - ################################################# - ######### override the vitisUnified Writer ###### - ################################################# - - self.dg = VitisUnifiedPartial_DriverGen - self.mg = VitisUnifiedPartial_MetaGen - self.tbg = VitisUnifiedPartial_BridgeGen - self.tcg = VitisUnifiedPartial_TestGen - self.wg = VitisUnifiedPartial_WrapperGen - - ################################################# - ######### override the vitisUnified Writer ###### - ################################################# - - self.magic_gen = VitisUnifiedPartial_MagicArchGen - - - ################################################# - ######### magic streamer controller variable #### - ################################################# - self.mgs_mng = None - - def set_mgs_mng(self, mgs_mng): - self.mgs_mng = mgs_mng - - def generate_config(self, model): - from hls4ml.backends.vitis_unified_partial.vitis_unified_partial_config import VitisUnifiedPartialConfig - self.writer_meta.vitis_unified_config = VitisUnifiedPartialConfig( - model.config, model.get_input_variables(), model.get_output_variables(), self.mgs_mng - - ) - - - def write_hls(self, model, is_multigraph=False): - - super().write_hls(model, is_multigraph) - - if is_multigraph: - self.magic_gen.copyMagicArchIp(self.writer_meta, model) - self.magic_gen.write_mgs(self.writer_meta, model) - self.magic_gen.gen_vivado_project(self.writer_meta, model, self.mg) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py b/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py deleted file mode 100644 index e520e5e076..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/driver_gen.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -import stat -from pathlib import Path - - -from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta -from hls4ml.writer.vitis_unified_writer.driver_gen import VitisUnified_DriverGen - -class VitisUnifiedPartial_DriverGen(VitisUnified_DriverGen): - - - @classmethod - def write_driver(self, meta: VitisUnifiedWriterMeta, model, mg): - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/driver/pynq/pynq_driver.py'), 'r') - fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') - - - for line in fin.readlines(): - newline = line - ##### TODO - fout.write(newline) - - - fin.close() - fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta.py b/hls4ml/writer/vitis_unified_partial_writer/meta.py deleted file mode 100644 index 7bed812196..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/meta.py +++ /dev/null @@ -1,2 +0,0 @@ - -### meta is using from vitis unified writer \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py b/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py deleted file mode 100644 index 07c166d460..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/meta_gen.py +++ /dev/null @@ -1,106 +0,0 @@ -from hls4ml.writer.vitis_unified_writer.meta_gen import VitisUnified_MetaGen - -class VitisUnifiedPartial_MetaGen(VitisUnified_MetaGen): - - ################################################## - ## file and directory ############################ - ################################################## - - @classmethod - def get_wrapper_file_name(self, model): - return f"{model.config.get_project_name()}_axi" - - ################################################## - ## naming function and variable ############### - ################################################## - - @classmethod - def get_io_port_name(self, tensorVar, isInput: bool, idx: int): - ioDirect = "in" if isInput else "out" - return f"streamIo_{ioDirect}{str(idx)}_{tensorVar.name}" - - @classmethod - def get_top_wrap_func_name(self, model): - return f"{model.config.get_project_name()}_axis" - - @classmethod - def get_output_kernel_type(cls): - return "ip_catalog" - - @classmethod - def get_input_size_arr_name(self, model): - return "N_IN_" + model.config.get_project_name() - - @classmethod - def get_output_size_arr_name(self, model): - return "N_OUT_" + model.config.get_project_name() - - @classmethod - def get_axi_wrapper_type(self, tensorVar): - return f"{tensorVar.type.name}_packet" - - @classmethod - def get_axi_wrapper_dec(self, tensorVar): - return f"typedef hls::axis<{tensorVar.type.name}, 0,0,0, AXIS_ENABLE_LAST> {self.get_axi_wrapper_type(tensorVar)};" - - @classmethod - def get_is_last_var(self, idx): - return f"isLast_{str(idx)}" - - @classmethod - def get_all_last_logic(self, amt): - isLastList = [self.get_is_last_var(idx) for idx in range(amt)] - return " && ".join(isLastList) - - ################################################## - ## generation function call ############### - ################################################## - - @classmethod - def get_enqueue_func_atom2stream(self, tensorVar, idx: int): - result = "enqueue_atom2layer<{INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( - INPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size()), - SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), - RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), - IS_LAST = self.get_is_last_var(idx), - ) - return result - - @classmethod ## rStream == raw stream (no tlast) - def get_enqueue_func_stream2rstream(self, tensorVar, idx: int): - result = "enqueue_layerStream2layer<{INPUT_LAYER_STREAM}, {INPUT_LAYER_ARR}, {SIZE}>({SRC_STREAM}, {RAW_STREAM}, {IS_LAST});".format( - INPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), - INPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size()), - SRC_STREAM = self.get_io_port_name(tensorVar, True, idx), - RAW_STREAM = self.get_local_stream_name(tensorVar, True, idx), - IS_LAST = self.get_is_last_var(idx), - ) - return result - - @classmethod - def get_dequeue_func_rstream2atom(self, tensorVar, idx: int, lastcheck: str,out_dma_type: str = "float"): - result = "dequeue_layer2atom<{ATOMIC_TYPE}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK});".format( - ATOMIC_TYPE = out_dma_type, - OUTPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size()), - DES_STREAM = self.get_io_port_name(tensorVar, False, idx), - RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), - IS_LAST_CHECK = lastcheck - ) - return result - - @classmethod - def get_dequeue_func_rstream2stream(self, tensorVar, idx: int, lastcheck: str): - result = "dequeue_layer2layer<{OUTPUT_LAYER_STREAM}, {OUTPUT_LAYER_ARR}, {SIZE}>({DES_STREAM}, {RAW_STREAM}, {IS_LAST_CHECK});".format( - OUTPUT_LAYER_STREAM = self.get_axi_wrapper_type(tensorVar), - OUTPUT_LAYER_ARR = tensorVar.type.name, - SIZE = str(tensorVar.size()), - DES_STREAM = self.get_io_port_name(tensorVar, False, idx), - RAW_STREAM = self.get_local_stream_name(tensorVar, False, idx), - IS_LAST_CHECK = lastcheck - ) - return result - - diff --git a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py b/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py deleted file mode 100644 index db9e28e1bf..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/mgs_gen.py +++ /dev/null @@ -1,223 +0,0 @@ -import os -import shutil -import stat -from pathlib import Path -import math - - -from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta - -#### This class is allowed for multigraph only -class VitisUnifiedPartial_MagicArchGen(): - - ########### allow for - @classmethod - def convert_idx_to_io_name(cls, meta, mg, list_of_io_idx, multi_graph, gid, is_input, default_name: str): - inp_axis_t, out_axis_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - sub_graph = multi_graph.graphs[gid] - io_tensor = sub_graph.get_input_variables() if is_input else sub_graph.get_output_variables() - result_name_list = [] - for io_idx in list_of_io_idx: - if io_idx is None: - result_name_list.append(default_name) - else: - io_name = mg.get_io_port_name(io_tensor[io_idx], is_input, io_idx) - result_name_list.append(io_name) - return result_name_list - - @classmethod - def gen_vivado_project(cls, meta: VitisUnifiedWriterMeta, model, mg): - filedir = os.path.dirname(os.path.abspath(__file__)) - - vivado_project_des_folder_path = f'{model.config.get_output_dir()}/vivado_project' - - if os.path.exists(vivado_project_des_folder_path): - shutil.rmtree(vivado_project_des_folder_path) - - os.makedirs(vivado_project_des_folder_path) - - board_name = meta.vitis_unified_config.get_board() - - #### copy project building script - vivado_project_src_script_path = os.path.join(filedir, - f'../../templates/vitis_unified_partial/board_support/{board_name}/project_builder.tcl') - des_project_script_path = f'{vivado_project_des_folder_path}/project_builder.tcl' - shutil.copyfile(vivado_project_src_script_path, des_project_script_path) - - #### copy mgs argument - vivado_project_src_meta_arg_path = os.path.join(filedir, - f'../../templates/vitis_unified_partial/board_support/mga_meta.tcl') - des_projectscript_meta_arg_path = f'{vivado_project_des_folder_path}/mga_meta.tcl' - - fin = open(vivado_project_src_meta_arg_path, 'r') - fout = open(des_projectscript_meta_arg_path, 'w') - - mgs_buffer_meta_list = meta.vitis_unified_config.get_mgs_meta_list() - amt_subGraph = meta.vitis_unified_config.get_amt_graph() - - graph_idx_width = str(max(0, int(math.ceil(math.log2(amt_subGraph))))) - - for line in fin.readlines(): - if "HLS_CFG_AMT_MGS" in line: - line = line.replace("VAL", str(len(mgs_buffer_meta_list))) - if "HLS_CFG_BANK_IDX_WIDTH" in line: - line = line.replace("VAL", graph_idx_width) - if "HLS_CFG_MGS_WRAP_WIDTH" in line: - width_list = ([str(meta.vitis_unified_config.get_dma_size())]) - width_list.extend([str(magic_buffer_meta.data_width) for magic_buffer_meta in mgs_buffer_meta_list]) - line = line.replace("VAL", "{"+ " ".join(width_list) + "}") - if "HLS_CFG_MGS_M" in line: - #### output side - all_output_connect = [] #### each element is for each subgraph - for gid in range(meta.vitis_unified_config.get_amt_graph()): - mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma( - gid, False) - output_connect_names = cls.convert_idx_to_io_name(meta, mg, mgs_buffer_con_idx, model, gid, False, "DUMMY") - output_connect_str = "{" + " ".join(output_connect_names) + "}" - all_output_connect.append(output_connect_str) - - line = line.replace("VAL", "{" + " ".join(all_output_connect) + "}") - - if "HLS_CFG_MGS_S" in line: - #### input side - all_input_connect = [] #### each element is for each subgraph - for gid in range(meta.vitis_unified_config.get_amt_graph()): - mgs_buffer_con_idx = meta.vitis_unified_config.get_mgs_mng().get_io_idx_for_all_mgs_buffer_with_dma( - gid, True) - input_connect_names = cls.convert_idx_to_io_name(meta, mg, mgs_buffer_con_idx, model, gid, True, "DUMMY") - input_connect_str = "{" + " ".join(input_connect_names) + "}" - all_input_connect.append(input_connect_str) - - line = line.replace("VAL", "{" + " ".join(all_input_connect) + "}") - - if "HLS_CFG_HLS_SRC" in line: - kernel_paths = [sub_graph.config.get_output_dir() + "/unifiedWorkspace" for sub_graph in model.graphs] - line = line.replace("VAL", "{" + " ".join(kernel_paths) + "}") - if "HLS_CFG_HLS_TOP_NAME" in line: - kernel_topNames = [ mg.get_top_wrap_func_name(sub_graph) for sub_graph in model.graphs] - line = line.replace("VAL", "{" + " ".join(kernel_topNames) + "}") - - - fout.write(line) - - fin .close() - fout.close() - - - - - - - @classmethod - def copyMagicArchIp(self, meta: VitisUnifiedWriterMeta, model): - - filedir = os.path.dirname(os.path.abspath(__file__)) - magic_arch_src_folder_path = os.path.join(filedir, '../../templates/vitis_unified_partial/ips') - magic_arch_des_folder_path = f'{model.config.get_output_dir()}/ips' - - if os.path.exists(magic_arch_des_folder_path): - shutil.rmtree(magic_arch_des_folder_path) - shutil.copytree(magic_arch_src_folder_path, magic_arch_des_folder_path, dirs_exist_ok=True) - - ##### delete the magic streamer grp generated ip first - magic_stream_grp_ip_path = f'{model.config.get_output_dir()}/ips/magic_streamer_grp_ip' - - if os.path.exists(magic_stream_grp_ip_path): - shutil.rmtree(magic_stream_grp_ip_path) - os.makedirs(magic_stream_grp_ip_path) - - - - - @classmethod - def write_mgs(self, meta: VitisUnifiedWriterMeta, model): - - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v'), 'r') - - fout = open(f'{model.config.get_output_dir()}/ips/magic_streamer_grp_src/streamGrp.v', 'w') - - mgs_buffer_meta_list = meta.vitis_unified_config.get_mgs_meta_list() - #### v------ mgs0 v--------- mgs1 - #### [(data width, indexWidth, ....), (data width, indexWidth, ....)] - - for line in fin.readlines(): - newline = line - - if "// hls4ml-streamGrp-gen-parameter" in line: - parameterList = [] - for idx, magic_buffer_meta in enumerate(mgs_buffer_meta_list): - parameterList.append(f"parameter DATA_WIDTH_{idx+1} = {magic_buffer_meta.data_width}") - parameterList.append(f"parameter STORAGE_IDX_WIDTH_{idx+1} = {magic_buffer_meta.row_idx_width}") - - parameterStr = ",\n".join(parameterList) - newline += parameterStr + "\n" - - elif "// hls4ml-streamGrp-gen-io" in line: - ioList = [] - for idx in range(1, len(mgs_buffer_meta_list) + 1): - ioList.append(f"//io for MGS{str(idx)}") - ioList.append(f"input wire [DATA_WIDTH_{str(idx)} -1:0] S{str(idx)}_AXI_TDATA" ) - ioList.append(f"input wire S{str(idx)}_AXI_TVALID") - ioList.append(f"output wire S{str(idx)}_AXI_TREADY") - ioList.append(f"input wire S{str(idx)}_AXI_TLAST" ) - ioList.append(f"output wire [DATA_WIDTH_{str(idx)}-1:0] M{str(idx)}_AXI_TDATA" ) - ioList.append(f"output wire M{str(idx)}_AXI_TVALID") - ioList.append(f"input wire M{str(idx)}_AXI_TREADY") - ioList.append(f"output wire M{str(idx)}_AXI_TLAST" ) - ioList.append("//----------debugging -------------") - ioList.append(f"output wire [4-1:0] dbg_state_{str(idx)}") - ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_store_bytes_{str(idx)}") - ioList.append(f"output wire [(STORAGE_IDX_WIDTH_{idx}+1)-1:0] dbg_amt_load_bytes_{str(idx)}") - - ioList.append("//--------- Pool commanding ------------") - ioList.append("///// for load [Reset/Init] of dma will be ignore") - ioList.append("///// for store [Reset/Init] of dma will be ignore") - ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] storeReset") - ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] loadReset") - ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] storeInit") - ioList.append(f"input wire[{len(mgs_buffer_meta_list)}: 0] loadInit") - ioList.append(f"output wire[{len(mgs_buffer_meta_list)}: 0] finStore") - ioList.append(f"input wire finStoreProxyDma") - - newline += ",\n".join(ioList) + ",\n" - - elif "// hls4ml-streamGrp-gen-logic-assign" in line: - newline += "assign finStore[0] = finStoreProxyDma;\n" - - - elif "// hls4ml-streamGrp-gen-create-module" in line: - - - for idx in range(1, len(mgs_buffer_meta_list)+1): - newline += f"//create module for MGS{str(idx)}\n" - newline += f"MagicStreammerCore #(\n" - newline += f" .DATA_WIDTH(DATA_WIDTH_{idx}),\n" - newline += f" .STORAGE_IDX_WIDTH(STORAGE_IDX_WIDTH_{idx})\n" - newline += f")\n" - newline += f"MGS{str(idx)} (\n" - newline += f" .S_AXI_TDATA(S{str(idx)}_AXI_TDATA),\n" - newline += f" .S_AXI_TVALID(S{str(idx)}_AXI_TVALID),\n" - newline += f" .S_AXI_TREADY(S{str(idx)}_AXI_TREADY),\n" - newline += f" .S_AXI_TLAST(S{str(idx)}_AXI_TLAST),\n" - newline += f" .M_AXI_TDATA(M{str(idx)}_AXI_TDATA),\n" - newline += f" .M_AXI_TVALID(M{str(idx)}_AXI_TVALID),\n" - newline += f" .M_AXI_TREADY(M{str(idx)}_AXI_TREADY),\n" - newline += f" .M_AXI_TLAST(M{str(idx)}_AXI_TLAST),\n" - newline += f"//------ command --------\n" - newline += f" .storeReset (storeReset[{str(idx)}]),\n" - newline += f" .loadReset (loadReset [{str(idx)}]),\n" - newline += f" .storeInit (storeInit [{str(idx)}]),\n" - newline += f" .loadInit (loadInit [{str(idx)}]),\n" - newline += f" .finStore (finStore [{str(idx)}]),\n" - newline += f"//------ debugging ------\n" - newline += f" .dbg_state(dbg_state_{str(idx)}),\n" - newline += f" .dbg_amt_store_bytes(dbg_amt_store_bytes_{str(idx)}),\n" - newline += f" .dbg_amt_load_bytes(dbg_amt_load_bytes_{str(idx)}),\n" - newline += f" .clk(clk),\n" - newline += f" .reset(nreset)\n" - newline += f");\n" - - - - fout.write(newline) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py deleted file mode 100644 index d083f7ac45..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/test_bridge_gen.py +++ /dev/null @@ -1,37 +0,0 @@ -import os - -from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta -from hls4ml.writer.vitis_unified_writer.test_bridge_gen import VitisUnified_BridgeGen - -class VitisUnifiedPartial_BridgeGen(VitisUnified_BridgeGen): - - @classmethod - def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): - - filedir = os.path.dirname(os.path.abspath(__file__)) - #### we will use the same bridge template file as VitisUnified_BridgeGen - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_bridge.cpp')) - fout = open(f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp", 'w') - - indent = ' ' - - - for line in fin.readlines(): - - #### TODO we will do the code next time - newline = line - - if 'MYPROJECT' in line: - newline = line.replace('MYPROJECT', format(model.config.get_project_name().upper())) - - elif 'myproject' in line: - newline = line.replace('myproject', format(model.config.get_project_name())) - - elif 'PROJECT_FILE_NAME' in line: - newline = line.replace('PROJECT_FILE_NAME', format(mg.get_wrapper_file_name(model))) - - fout.write(newline) - - - fin.close() - fout.close() \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py deleted file mode 100644 index 959ed9ce44..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/test_cosim_gen.py +++ /dev/null @@ -1,25 +0,0 @@ -import os - -from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta -from hls4ml.writer.vitis_unified_writer.test_cosim_gen import VitisUnified_TestGen - - -class VitisUnifiedPartial_TestGen(VitisUnified_TestGen): - - @classmethod - def write_wrapper_test(self, meta, model, mg): - inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - - - filedir = os.path.dirname(os.path.abspath(__file__)) - #### we use the same file as vitis unified - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') - - - fout.write("//// generated by Vitis Unified Backend\n") - - for line in f.readlines(): - newline = line - #### TODO we will do it next - fout.write(newline) \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py deleted file mode 100644 index 5ba0e9c50e..0000000000 --- a/hls4ml/writer/vitis_unified_partial_writer/wrap_gen.py +++ /dev/null @@ -1,152 +0,0 @@ -import os -from pathlib import Path -import stat -from shutil import copyfile - -from hls4ml.writer.vitis_unified_writer.meta import VitisUnifiedWriterMeta -from hls4ml.writer.vitis_unified_writer.wrap_gen import VitisUnified_WrapperGen -from .meta_gen import VitisUnifiedPartial_MetaGen as mg - -class VitisUnifiedPartial_WrapperGen(VitisUnified_WrapperGen): - - @classmethod - def gen_io_str(self, mg,indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): - inputStreamList = [] - outputStreamList = [] - - - for inp_idx, inp in enumerate(inps): - inp_type = mg.get_dma_type_name() - if (meta.vitis_unified_config.is_free_interim_input()) and \ - (meta.vitis_unified_config.get_graph_idx() != 0 ): - inp_type = mg.get_axi_wrapper_type(inp) - inputStreamList.append(f"{indent} hls::stream<{inp_type}>& {mg.get_io_port_name(inp, True, inp_idx)}") - - for out_idx, out in enumerate(outs): - out_type = mg.get_dma_type_name() - if (meta.vitis_unified_config.is_free_interim_output()) and \ - (meta.vitis_unified_config.get_graph_idx() != (meta.vitis_unified_config.get_amt_graph()-1) ): - out_type = mg.get_axi_wrapper_type(out) - outputStreamList.append(f"{indent} hls::stream<{out_type}>& {mg.get_io_port_name(out, False, out_idx)}") - - return ", \n".join(inputStreamList) + ",\n" + ", \n".join(outputStreamList) - - @classmethod - def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): - - inp_axis_t, out_axis_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - indent = ' ' - - ####################################### - ###### start write myproject_axi.cpp ## - ####################################### - - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.cpp'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/{mg.get_wrapper_file_name(model)}.cpp', 'w') - - - for line in fin.readlines(): - - # if "MY_PROJECT_AXI_INC" in line: - # line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) - if "MY_PROJECT_TOP_FUNC" in line: - line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) - elif "WRAPPER_FILE_NAME" in line: - line = line.replace("WRAPPER_FILE_NAME", mg.get_wrapper_file_name(model)) - elif "// hls-fpga-machine-learning insert multi-io" in line: - line = self.gen_io_str(mg, indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" - elif "// hls-fpga-machine-learning insert interface" in line: - for inp_idx, inp in enumerate(inps): - line += f"{indent} #pragma HLS INTERFACE axis port={mg.get_io_port_name(inp, True, inp_idx)}\n" - for out_idx, out in enumerate(outs): - line += f"{indent} #pragma HLS INTERFACE axis port={mg.get_io_port_name(out, False, out_idx)}\n" - elif "// hls-fpga-machine-learning insert local vars" in line: - #### declare stream variable - for inp_idx, inp in enumerate(inps): - line += f"{indent} static hls::stream<{inp.type.name}> {mg.get_local_stream_name(inp, True, inp_idx)};\n" - for out_idx, out in enumerate(outs): - line += f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" - #### declare stream size - for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth={inp.pragma[1]}\n" - for out_idx, out in enumerate(outs): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth={out.pragma[1]}\n" - - elif "// hls-fpga-machine-learning insert isLast vars" in line: - for inp_idx in range(len(inps)): - line += f"bool {mg.get_is_last_var(inp_idx)} = false;\n" - - elif "// hls-fpga-machine-learning insert enqueue" in line: - for inp_idx, inp in enumerate(inps): - if meta.vitis_unified_config.is_free_interim_input(): - line += mg.get_enqueue_func_stream2rstream(inp, inp_idx) - else: - line += mg.get_enqueue_func_atom2stream(inp, inp_idx) - line += "\n" - - elif "// hls-fpga-machine-learning insert call" in line: - poolList = [] - for inp_idx, inp in enumerate(inps): - poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") - for out_idx, out in enumerate(outs): - poolList.append(f"{mg.get_local_stream_name(out, False, out_idx)}") - joinedIo = ", \n".join(poolList) - line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" - - elif "// hls-fpga-machine-learning insert dequeue" in line: - for out_idx, out in enumerate(outs): - if meta.vitis_unified_config.is_free_interim_output(): - line += mg.get_dequeue_func_rstream2stream(out, out_idx, - mg.get_all_last_logic(len(inps))) + "\n" - else: - line += mg.get_dequeue_func_rstream2atom(out, out_idx, mg.get_all_last_logic(len(inps)), - out_axis_t) + "\n" - - fout.write(line) - fin.close() - fout.close() - - ####################################### - ###### start write myproject_axi.h ## - ####################################### - - filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified_partial/myproject_axi.h'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/{mg.get_wrapper_file_name(model)}.h', 'w') - - for line in fin.readlines(): - - newline = line - if "FILENAME" in line: - newline = line.replace("FILENAME", mg.get_wrapper_file_name(model).upper()) - if "MY_PROJECT_TOP_FUNC" in line: - newline = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) - elif "MY_PROJECT_AXI_INC" in line: - newline = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) - elif "// hls-fpga-machine-learning insert definitions" in line: - ##### make input - newline = '' - inputSizeStr = "{ " + ", ".join([str(inp.size()) for inp in inps]) + " }" - newline += f'constexpr unsigned {mg.get_input_size_arr_name(model)} [{len(inps)}] = {inputSizeStr};\n' - - ##### make output - outputSizeStr = "{ " + ", ".join([str(out.size()) for out in outs]) + " }" - newline += f'constexpr unsigned {mg.get_output_size_arr_name(model)} [{len(outs)}] = {outputSizeStr};\n' - newline += f'typedef hls::axis<{inp_axis_t}, 0, 0, 0, AXIS_ENABLE_LAST> dma_data_packet;\n' - #### incase the io is interim input - if meta.vitis_unified_config.is_free_interim_input(): - for inp in inps: - newline += mg.get_axi_wrapper_dec(inp) + "\n" - #### incase the io is interim output - if meta.vitis_unified_config.is_free_interim_output(): - for out in outs: - newline += mg.get_axi_wrapper_dec(out) + "\n" - elif "// vitis-unified-wrapper-io" in line: - newline = self.gen_io_str(mg, indent, inp_axis_t, out_axis_t, inps, outs, meta) + "\n" - fout.write(newline) - - - fin.close() - fout.close() - From 3e1314c817676af510bf2c9a239452c1e8c93f84 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 13:55:35 +0200 Subject: [PATCH 47/70] delete vitis Unified partial template --- .../board_support/mga_meta.tcl | 24 - .../board_support/zcu102/project_builder.tcl | 1061 ----------- .../vitis_unified_partial/build_lib.sh | 30 - .../build_lib_multigraph.sh | 69 - .../driver/pynq/pynq_driver.py | 69 - .../ips/magic_dummy_master/component.xml | 331 ---- .../src/dummyStreamMaster.v | 23 - .../xgui/DummyStreamMaster_v1_0.tcl | 39 - .../ips/magic_dummy_slave/component.xml | 344 ---- .../magic_dummy_slave/src/dummyStreamSlave.v | 21 - .../xgui/DummyStreamSlave_v1_0.tcl | 54 - .../ips/magic_icap/component.xml | 333 ---- .../ips/magic_icap/src/icapWrapper.v | 61 - .../ips/magic_icap/xgui/icapWrap_v1_0.tcl | 10 - .../ips/magic_seq/component.xml | 1600 ----------------- .../ips/magic_seq/src/m_axi_read.v | 48 - .../ips/magic_seq/src/m_axi_write.v | 205 --- .../ips/magic_seq/src/magicSeq.v | 634 ------- .../ips/magic_seq/src/magicSeqCore.v | 644 ------- .../ips/magic_seq/src/s_axi_read.v | 162 -- .../ips/magic_seq/src/s_axi_write.v | 240 --- .../ips/magic_seq/src/slot.v | 89 - .../ips/magic_seq/src/slotTable.v | 150 -- .../ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl | 294 --- .../ips/magic_seq/xgui/MagicSeq_v1_0.tcl | 309 ---- .../ips/magic_streamer/component.xml | 559 ------ .../ips/magic_streamer/src/magicStreamer.v | 161 -- .../xgui/MagicStreammerCore_v1_0.tcl | 54 - .../ips/magic_streamer_grp_prj/composer.tcl | 23 - .../ips/magic_streamer_grp_src/streamGrp.v | 18 - .../vitis_unified_partial/myproject_axi.cpp | 88 - .../vitis_unified_partial/myproject_axi.h | 19 - .../myproject_bridge.cpp | 71 - .../vitis_unified_partial/myproject_test.cpp | 96 - .../workspace/projectName/vitis-comp.json | 9 - 35 files changed, 7942 deletions(-) delete mode 100644 hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/build_lib.sh delete mode 100644 hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh delete mode 100644 hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeqCore.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/s_axi_read.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/s_axi_write.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/slot.v delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/slotTable.v delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeqTop_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_seq/xgui/MagicSeq_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_streamer/component.xml delete mode 100755 hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl delete mode 100644 hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v delete mode 100644 hls4ml/templates/vitis_unified_partial/myproject_axi.cpp delete mode 100644 hls4ml/templates/vitis_unified_partial/myproject_axi.h delete mode 100644 hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp delete mode 100644 hls4ml/templates/vitis_unified_partial/myproject_test.cpp delete mode 100644 hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json diff --git a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl b/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl deleted file mode 100644 index baffb6f132..0000000000 --- a/hls4ml/templates/vitis_unified_partial/board_support/mga_meta.tcl +++ /dev/null @@ -1,24 +0,0 @@ -variable HLS_CFG_AMT_MGS -set HLS_CFG_AMT_MGS VAL -variable HLS_CFG_BANK_IDX_WIDTH -set HLS_CFG_BANK_IDX_WIDTH VAL -variable HLS_CFG_MGS_WRAP_WIDTH -set HLS_CFG_MGS_WRAP_WIDTH VAL - -# HLS CFG MGS WRAP WIDTH the Val dma is include - -##### connection meta -######### input -variable HLS_CFG_MGS_S -set HLS_CFG_MGS_S VAL -variable HLS_CFG_MGS_M -######### output -set HLS_CFG_MGS_M VAL - -# kernel name setting -#### src repo path -variable HLS_CFG_HLS_SRC -set HLS_CFG_HLS_SRC VAL -#### top name -variable HLS_CFG_HLS_TOP_NAME -set HLS_CFG_HLS_TOP_NAME VAL diff --git a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl b/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl deleted file mode 100644 index bb3bf6bc1d..0000000000 --- a/hls4ml/templates/vitis_unified_partial/board_support/zcu102/project_builder.tcl +++ /dev/null @@ -1,1061 +0,0 @@ -# Set the reference directory for source file relative paths (by default the value is script directory path) -set origin_dir "." - - -# Set the project name -set _xil_proj_name_ "dfx4ml" - -variable script_file -set script_file "project_builder.tcl" - -# Create project -create_project ${_xil_proj_name_} ./${_xil_proj_name_} -part xczu9eg-ffvb1156-2-e - -source mga_meta.tcl - -# Set the directory path for the new project -set proj_dir [get_property directory [current_project]] - -# Set project properties -set obj [current_project] - -# set_property ip_repo_paths ../ips $obj -# update_ip_catalog - -# foreach ip_dir $HLS_CFG_HLS_SRC { -# update_ip_catalog -add $ip_dir -repo_path $ip_dir -# } -# update_ip_catalog - -set HLS_CFG_HLS_ALL_IP {} -foreach dir $HLS_CFG_HLS_SRC { - lappend HLS_CFG_HLS_ALL_IP $dir -} -lappend HLS_CFG_HLS_ALL_IP ../ips -set_property ip_repo_paths $HLS_CFG_HLS_ALL_IP $obj -update_ip_catalog - -set_property -name "board_part" -value "xilinx.com:zcu102:part0:3.4" -objects $obj - - -proc cr_bd_system {} { - - global HLS_CFG_AMT_MGS HLS_CFG_MGS_INDEX HLS_CFG_BANK_IDX_WIDTH HLS_CFG_MGS_WRAP_WIDTH HLS_CFG_MGS_S HLS_CFG_MGS_M HLS_CFG_HLS_TOP_NAME - - set design_name system - create_bd_design $design_name - - proc create_hier_cell_data_mover {parentCell nameHier amtMgs} { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - ############################################## - ##### Create pins ############################ - ############################################## - - ###### dma interface pin create - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DMA_CTRL - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM - - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M0_AXI - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S0_AXI - - ###### mgs interface pin create - for {set i 1} {$i <= $amtMgs} {incr i} { - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M${i}_AXI - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S${i}_AXI - } - - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - create_bd_pin -dir I -from ${amtMgs} -to 0 storeReset - create_bd_pin -dir I -from ${amtMgs} -to 0 loadReset - create_bd_pin -dir I -from ${amtMgs} -to 0 storeInit - create_bd_pin -dir I -from ${amtMgs} -to 0 loadInit - create_bd_pin -dir O -from ${amtMgs} -to 0 finStore - - ############################################## - ##### Create instance ######################## - ############################################## - - ### create axi dma - 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 magic streamer group - set streamGrp_0 [ create_bd_cell -type ip -vlnv user.org:user:streamGrp:1.0 streamGrp_0 ] - - ############################################## - ##### Create connection ###################### - ############################################## - - - # Create interface connections - - #### only for dma - connect_bd_intf_net -intf_net axi_dma_0_M_AXIS_MM2S [get_bd_intf_pins M0_AXI ] [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] - connect_bd_intf_net -intf_net dfx_decoupler_4_s_intf_0 [get_bd_intf_pins S0_AXI ] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] - - connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins M_AXI_MM2S ] [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] - connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins M_AXI_S2MM ] [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] - - - #### only for mgs - - for {set i 1} {$i <= $amtMgs} {incr i} { - connect_bd_intf_net -intf_net streamGrp_0_M${i}_AXI [get_bd_intf_pins M${i}_AXI] [get_bd_intf_pins streamGrp_0/M${i}_AXI] - connect_bd_intf_net -intf_net streamGrp_0_S${i}_AXI [get_bd_intf_pins S${i}_AXI] [get_bd_intf_pins streamGrp_0/S${i}_AXI] - } - - - connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins S_AXI_DMA_CTRL] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] - - - #### Create port connections - connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins loadInit] [get_bd_pins streamGrp_0/loadInit] - connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins loadReset] [get_bd_pins streamGrp_0/loadReset] - connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins storeInit] [get_bd_pins streamGrp_0/storeInit] - connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins storeReset] [get_bd_pins streamGrp_0/storeReset] - connect_bd_net -net axi_dma_0_s2mm_introut [get_bd_pins axi_dma_0/s2mm_introut] [get_bd_pins streamGrp_0/finStoreProxyDma] - connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins streamGrp_0/nreset] [get_bd_pins axi_dma_0/axi_resetn] - connect_bd_net -net streamGrp_0_finStore [get_bd_pins streamGrp_0/finStore] [get_bd_pins finStore] - connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins streamGrp_0/clk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] - - #### return to old instance - current_bd_instance $oldCurInst - - - } - - proc create_hier_cell_magic_seqCtrl {parentCell nameHier amtMgs bank1Idx} { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - ############################################## - ##### Create pins ############################ - ############################################## - - ####### dfx controller - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_DFX_CTRL - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DFX_LOADER - ####### magic sequencer - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DMA_CTRL - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_MGQ_CTRL - ####### interrupt controler - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_INTR_CTRL - - - # Create pins - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreReset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadReset - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsStoreInit - create_bd_pin -dir O -from ${amtMgs} -to 0 mgsLoadInit - create_bd_pin -dir I -from ${amtMgs} -to 0 mgsFinExec - create_bd_pin -dir O irq - create_bd_pin -dir O decup - - ############################################## - ##### Create instance ######################## - ############################################## - - set MagicSeq_0 [ create_bd_cell -type ip -vlnv user.org:user:MagicSeqTop:1.0 MagicSeq_0 ] - set_property -dict [list \ - CONFIG.BANK1_INDEX_WIDTH $bank1Idx \ - CONFIG.BANK0_CNT_WIDTH $bank1Idx \ - CONFIG.BANK1_LD_MSK_WIDTH [expr {$amtMgs+1}] \ - CONFIG.BANK1_ST_MSK_WIDTH [expr {$amtMgs+1}] \ - ] $MagicSeq_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: xlconstant_0 (magic seq) ) _1(dfx_controller), and set properties - set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ] - set_property CONFIG.CONST_VAL {0} $xlconstant_0 - set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ] - - - # Create instance: dfx_controller_0, and set properties - set dfx_controller_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_controller:1.0 dfx_controller_0 ] - - # build RM section dynamically - # Build RM list - set rm_list {} - set num_rms [expr {2**$bank1Idx}] - for {set i 0} {$i < [expr {2**$bank1Idx}]} {incr i} { - lappend rm_list "RM_$i {ID $i NAME RM_$i BS {0 {ID 0 ADDR 0 SIZE 0 CLEAR 0}} RESET_REQUIRED low}" - } - - # Convert to proper string - set rm_block [join $rm_list " "] - - set_property -dict [list \ - CONFIG.ALL_PARAMS [format {HAS_AXI_LITE_IF 1 \ - RESET_ACTIVE_LEVEL 0 \ - CP_FIFO_DEPTH 32 \ - CP_FIFO_TYPE lutram \ - CDC_STAGES 6 \ - VS { \ - VS_0 {ID 0 NAME VS_0 \ - RM { %s } \ - POR_RM RM_0 NUM_HW_TRIGGERS %d} \ - } \ - CP_FAMILY ultrascale_plus DIRTY 0} \ - $rm_block $num_rms] \ - CONFIG.GUI_VS_NUM_HW_TRIGGERS $num_rms \ - CONFIG.GUI_VS_NUM_RMS_ALLOCATED [expr {2**$bank1Idx}] \ - ] $dfx_controller_0 - - - # Create instance: icapWrap_0, and set properties - set icapWrap_0 [ create_bd_cell -type ip -vlnv user.org:user:icapWrap:1.0 icapWrap_0 ] - - ############################################## - ##### Create connection ###################### - ############################################## - - - # Create interface connections - - ##### connect DFX controller - connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins S_AXI_DFX_CTRL ] [get_bd_intf_pins dfx_controller_0/s_axi_reg] - connect_bd_intf_net -intf_net Conn2 [get_bd_intf_pins M_AXI_DFX_LOADER ] [get_bd_intf_pins dfx_controller_0/M_AXI_MEM] - connect_bd_intf_net -intf_net dfx_controller_0_ICAP [get_bd_intf_pins dfx_controller_0/ICAP] [get_bd_intf_pins icapWrap_0/ICAP] - ##### connect to magic sequencer - connect_bd_intf_net -intf_net MagicSeq_0_M_AXI [get_bd_intf_pins M_AXI_DMA_CTRL] [get_bd_intf_pins MagicSeq_0/M_AXI] - connect_bd_intf_net -intf_net axi_interconnect_1_M02_AXI [get_bd_intf_pins S_AXI_MGQ_CTRL] [get_bd_intf_pins MagicSeq_0/S_AXI] - ##### connect to interrupt controller - connect_bd_intf_net -intf_net axi_interconnect_1_M00_AXI [get_bd_intf_pins S_AXI_INTR_CTRL] [get_bd_intf_pins axi_intc_0/s_axi] - - - - # Create port connections - - ##### magic sequencer control - connect_bd_net -net MagicSeq_0_hw_intr [get_bd_pins MagicSeq_0/hw_intr] [get_bd_pins axi_intc_0/intr ] - connect_bd_net -net MagicSeq_0_slaveMgsLoadInit [get_bd_pins mgsLoadInit ] [get_bd_pins MagicSeq_0/slaveMgsLoadInit] - connect_bd_net -net MagicSeq_0_slaveMgsLoadReset [get_bd_pins mgsLoadReset ] [get_bd_pins MagicSeq_0/slaveMgsLoadReset] - connect_bd_net -net MagicSeq_0_slaveMgsStoreInit [get_bd_pins mgsStoreInit ] [get_bd_pins MagicSeq_0/slaveMgsStoreInit] - connect_bd_net -net MagicSeq_0_slaveMgsStoreReset [get_bd_pins mgsStoreReset ] [get_bd_pins MagicSeq_0/slaveMgsStoreReset] - connect_bd_net -net streamGrp_0_finStore [get_bd_pins mgsFinExec ] [get_bd_pins MagicSeq_0/mgsFinExec] - ##### interrupt controller connections - connect_bd_net -net axi_intc_0_irq [get_bd_pins irq] [get_bd_pins axi_intc_0/irq] - ##### magic sequencer dfx controller connections - connect_bd_net -net MagicSeq_0_slaveReprog [get_bd_pins MagicSeq_0/slaveReprog] [get_bd_pins dfx_controller_0/vsm_VS_0_hw_triggers] - connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_reset [get_bd_pins MagicSeq_0/nslaveReset] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_reset] - ##### dfx controller control connections - connect_bd_net -net dfx_controller_0_vsm_VS_0_rm_decouple [get_bd_pins decup] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_decouple] - ##### connect constant values - connect_bd_net -net xlconstant_0_dout [get_bd_pins xlconstant_0/dout] [get_bd_pins MagicSeq_0/hw_intr_clear] [get_bd_pins MagicSeq_0/hw_ctrl_start] - connect_bd_net -net xlconstant_1_dout [get_bd_pins xlconstant_1/dout] [get_bd_pins dfx_controller_0/vsm_VS_0_rm_shutdown_ack] - ##### reset - connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins nreset] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins MagicSeq_0/reset] [get_bd_pins dfx_controller_0/icap_reset] [get_bd_pins dfx_controller_0/reset] - connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins clk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins MagicSeq_0/clk] [get_bd_pins dfx_controller_0/icap_clk] [get_bd_pins dfx_controller_0/clk] [get_bd_pins icapWrap_0/CLK] - - #### return to old instance - current_bd_instance $oldCurInst - - - } - - proc create_hier_cell_dfx_decup { parentCell nameHier amtMgs } { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - # Create pins - create_bd_pin -dir I decouple - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - - for {set i 0} {$i <= $amtMgs} {incr i} { - ### s connect to PR - ### rp connect to mgs - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 s_intf_${i} - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 rp_intf_${i} - - set dfx_decoupler_inst [ create_bd_cell -type ip -vlnv xilinx.com:ip:dfx_decoupler:1.0 dfx_decoupler_${i} ] - set_property CONFIG.ALL_PARAMS {INTF {intf_0 {ID 0 VLNV xilinx.com:interface:axis_rtl:1.0}} ALWAYS_HAVE_AXI_CLK 1 HAS_SIGNAL_STATUS 0} [get_bd_cells dfx_decoupler_${i}] - - connect_bd_intf_net -intf_net dfx_decoupler_${i}_s [get_bd_intf_pins s_intf_${i} ] [get_bd_intf_pins dfx_decoupler_${i}/s_intf_0] - connect_bd_intf_net -intf_net dfx_decoupler_${i}_rp [get_bd_intf_pins rp_intf_${i}] [get_bd_intf_pins dfx_decoupler_${i}/rp_intf_0] - - connect_bd_net -net decupNet [get_bd_pins decouple] [get_bd_pins dfx_decoupler_${i}/decouple] - connect_bd_net -net clkNet [get_bd_pins clk ] [get_bd_pins dfx_decoupler_${i}/intf_0_aclk] - connect_bd_net -net nresetNet [get_bd_pins nreset ] [get_bd_pins dfx_decoupler_${i}/intf_0_arstn] - } - - - #### return to old instance - current_bd_instance $oldCurInst - - - - - } - - proc create_hier_cell_dfx_par { parentCell nameHier amtMgs dataWidths } { - - #### old system obj is cell and oldCurInstr is path - set parentObj [get_bd_cells $parentCell] - set oldCurInst [current_bd_instance .] - - set hierObj [create_bd_cell -type hier $nameHier] - current_bd_instance $hierObj - - # Create pins - create_bd_pin -dir I -type clk clk - create_bd_pin -dir I -type rst nreset - - for {set i 0} {$i <= $amtMgs} {incr i} { - ### s connect to PR - ### rp connect to mgs - create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXI_${i} - create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXI_${i} - - set DummyStreamMaster_${i} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${i} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamMaster_${i}] - set DummyStreamSlave_${i} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${i} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $i] [get_bd_cells DummyStreamSlave_${i}] - - - connect_bd_intf_net -intf_net DummyStreamMaster_${i} [get_bd_intf_pins M_AXI_${i} ] [get_bd_intf_pins DummyStreamMaster_${i}/M_AXI] - connect_bd_intf_net -intf_net DummyStreamSlave_${i} [get_bd_intf_pins S_AXI_${i} ] [get_bd_intf_pins DummyStreamSlave_${i}/S_AXI] - - connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${i}/clk] - connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${i}/reset] - connect_bd_net -net clk_DummyStreamMaster_Net [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${i}/clk] - connect_bd_net -net nreset_DummyStreamMaster_Net [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${i}/reset] - } - - - #### return to old instance - current_bd_instance $oldCurInst - - } - - proc convert_hier_cell_dfx_to_bd {} { - - - set oldCurInst [current_bd_instance .] - - ### create block design container - validate_bd_design - startgroup - set curdesign [current_bd_design] - create_bd_design -cell [get_bd_cells /dfx_par] dfx_par - current_bd_design $curdesign - set new_cell [create_bd_cell -type container -reference dfx_par dfx_par_temp] - replace_bd_cell [get_bd_cells /dfx_par] $new_cell - delete_bd_objs [get_bd_cells /dfx_par] - set_property name dfx_par $new_cell - endgroup - ### set property for dfx_par to be dfx region - set_property CONFIG.ENABLE_DFX {true} [get_bd_cells dfx_par] - validate_bd_design - - current_bd_instance $oldCurInst - validate_bd_design - save_bd_design - - current_bd_design [get_bd_designs system] - - - } - - proc build_reconfig_module {} { - - ############################################### - ################# create reconfig module ###### - ############################################### - current_bd_design [get_bd_designs system] - - set curdesign [current_bd_design] - - create_bd_design -boundary_from_container [get_bd_cells /dfx_par] dfx_par_1 - - current_bd_design $curdesign - set_property -dict [list CONFIG.LIST_SYNTH_BD {dfx_par.bd:dfx_par_1.bd} CONFIG.LIST_SIM_BD {dfx_par.bd:dfx_par_1.bd}] [get_bd_cells /dfx_par] - - current_bd_design $curdesign - current_bd_design [get_bd_designs dfx_par_1] - - - - ################################################ - ################### add cell ################### - ################################################ - - startgroup - create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_graph1_axis:1.0 myproject_graph1_axis_0 - endgroup - - ################################################ - ################### do connection ############## - ################################################ - - connect_bd_intf_net [get_bd_intf_ports S_AXI_0] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_in0_input_1] - connect_bd_intf_net [get_bd_intf_ports M_AXI_0] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_out0_layer13_cpy2] - connect_bd_intf_net [get_bd_intf_ports M_AXI_1] [get_bd_intf_pins myproject_graph1_axis_0/streamIo_out1_layer15_out] - connect_bd_net [get_bd_ports clk] [get_bd_pins myproject_graph1_axis_0/ap_clk] - connect_bd_net [get_bd_ports nreset] [get_bd_pins myproject_graph1_axis_0/ap_rst_n] - - validate_bd_design - - save_bd_design - - current_bd_design [get_bd_designs system] - - - - } - - proc build_reconfig_module2 { gid top_func_name input_list output_list dataWidths } { - - current_bd_design [get_bd_designs system] - - set curdesign [current_bd_design] - - create_bd_design -boundary_from_container [get_bd_cells /dfx_par] dfx_par_${gid} - - ################################################ - #### switch back to system to set the config ### - ################################################ - current_bd_design $curdesign - #set_property -dict [list CONFIG.LIST_SYNTH_BD {dfx_par.bd:dfx_par_${gid}.bd} CONFIG.LIST_SIM_BD {dfx_par.bd:dfx_par_${gid}.bd}] [get_bd_cells /dfx_par] - - ################################################ - #### switch back to the reconfig module ######## - ################################################ - - current_bd_design $curdesign - current_bd_design [get_bd_designs dfx_par_${gid}] - ################################################ - #### create cell ######## - ################################################ - - startgroup - create_bd_cell -type ip -vlnv xilinx.com:hls:${top_func_name}:1.0 ${top_func_name}_0 - endgroup - - ################################################ - #### do connection input ####################### - ################################################ - - for {set mgs_buffer_idx 0} {$mgs_buffer_idx < [llength $input_list]} {incr mgs_buffer_idx} { - set kernel_port_name [lindex $input_list $mgs_buffer_idx] - - - switch -- $kernel_port_name { - "DUMMY" { - ####### create dummy stream slave - set DummyStreamSlave_${mgs_buffer_idx} [ create_bd_cell -type ip -vlnv hls4ml_par_gen:user:DummyStreamSlave:1.0 DummyStreamSlave_${mgs_buffer_idx} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $mgs_buffer_idx] [get_bd_cells DummyStreamSlave_${mgs_buffer_idx}] - - connect_bd_intf_net -intf_net DummyStreamSlave_${mgs_buffer_idx} [get_bd_intf_pins S_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins DummyStreamSlave_${mgs_buffer_idx}/S_AXI] - connect_bd_net -net clk_internal [get_bd_pins clk ] [get_bd_pins DummyStreamSlave_${mgs_buffer_idx}/clk] - connect_bd_net -net nreset_internal [get_bd_pins nreset ] [get_bd_pins DummyStreamSlave_${mgs_buffer_idx}/reset] - - } - default { - connect_bd_intf_net -intf_net ${kernel_port_name} [get_bd_intf_pins S_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins ${top_func_name}_0/${kernel_port_name}] - } - } - } - - ################################################ - #### do connection output ###################### - ################################################ - - for {set mgs_buffer_idx 0} {$mgs_buffer_idx < [llength $output_list]} {incr mgs_buffer_idx} { - set kernel_port_name [lindex $output_list $mgs_buffer_idx] - - - switch -- $kernel_port_name { - "DUMMY" { - ####### create dummy stream slave - set DummyStreamMaster_${mgs_buffer_idx} [ create_bd_cell -type ip -vlnv user.org:user:DummyStreamMaster:1.0 DummyStreamMaster_${mgs_buffer_idx} ] - set_property CONFIG.DATA_WIDTH [lindex $dataWidths $mgs_buffer_idx] [get_bd_cells DummyStreamMaster_${mgs_buffer_idx}] - - connect_bd_intf_net -intf_net DummyStreamMaster_${mgs_buffer_idx} [get_bd_intf_pins M_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins DummyStreamMaster_${mgs_buffer_idx}/M_AXI] - connect_bd_net -net clk_internal [get_bd_pins clk ] [get_bd_pins DummyStreamMaster_${mgs_buffer_idx}/clk] - connect_bd_net -net nreset_internal [get_bd_pins nreset ] [get_bd_pins DummyStreamMaster_${mgs_buffer_idx}/reset] - - } - default { - connect_bd_intf_net -intf_net ${kernel_port_name} [get_bd_intf_pins M_AXI_${mgs_buffer_idx} ] [get_bd_intf_pins ${top_func_name}_0/${kernel_port_name}] - } - } - } - - connect_bd_net [get_bd_ports clk] [get_bd_pins ${top_func_name}_0/ap_clk] - connect_bd_net [get_bd_ports nreset] [get_bd_pins ${top_func_name}_0/ap_rst_n] - - - validate_bd_design - save_bd_design - current_bd_design [get_bd_designs system] - - - - - } - - # set parentObj "" - # set parentType [get_property TYPE $parentObj] - - # set oldCurInst [current_bd_instance .] - - # current_bd_instance $parentObj - - - # ########################### - # ###### build the ip ####### - # ########################### - - # ###### set Cpu - 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_INPUT_TYPE {cmos} \ - CONFIG.PSU_MIO_22_POLARITY {Default} \ - CONFIG.PSU_MIO_23_POLARITY {Default} \ - CONFIG.PSU_MIO_26_POLARITY {Default} \ - CONFIG.PSU_MIO_32_POLARITY {Default} \ - CONFIG.PSU_MIO_33_POLARITY {Default} \ - CONFIG.PSU_MIO_35_POLARITY {Default} \ - CONFIG.PSU_MIO_36_POLARITY {Default} \ - CONFIG.PSU_MIO_37_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#GPIO1 MIO#GPIO1 MIO#PMU GPO 2#GPIO1 MIO#GPIO1\ - MIO#GPIO1 MIO#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#gpio1[32]#gpio1[33]#gpo[2]#gpio1[35]#gpio1[36]#gpio1[37]#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__AFI1_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__MAXIGP1__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 {0} \ - CONFIG.PSU__PMU__GPO1__ENABLE {0} \ - CONFIG.PSU__PMU__GPO2__ENABLE {1} \ - CONFIG.PSU__PMU__GPO2__IO {MIO 34} \ - CONFIG.PSU__PMU__GPO2__POLARITY {high} \ - CONFIG.PSU__PMU__GPO3__ENABLE {0} \ - 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__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;1|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__SAXIGP1__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 {1} \ - CONFIG.PSU__USE__M_AXI_GP2 {0} \ - CONFIG.PSU__USE__S_AXI_GP0 {1} \ - CONFIG.PSU__USE__S_AXI_GP1 {1} \ - ] $zynq_ultra_ps_e_0 - - ###### set main control - set axi_interconnect_main_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_main_control ] - set_property CONFIG.NUM_MI {3} $axi_interconnect_main_control - - - ###### set dma control interconnect - set axi_interconnect_dma_control [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_dma_control ] - set_property -dict [list \ - CONFIG.NUM_MI {1} \ - CONFIG.NUM_SI {2} \ - ] $axi_interconnect_dma_control - - - ###### set smart memory reader interconnect - - # Create instance: smartconnect_reader, and set properties - set smartconnect_reader [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_reader] - - # Create instance: smartconnect_writer, and set properties - set smartconnect_writer [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 smartconnect_writer ] - set_property CONFIG.NUM_SI {1} $smartconnect_writer - - # Create instance: reseter - set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] - - - set AMT_MGS 2 - set MGS_IDX 2 - set BANK_IDX_WIDTH 2 - set MGS_WIDTH {32 64 128} - - - create_hier_cell_data_mover [current_bd_instance .] data_mover $HLS_CFG_AMT_MGS - create_hier_cell_magic_seqCtrl [current_bd_instance .] magic_seq_ctrl $HLS_CFG_AMT_MGS $HLS_CFG_BANK_IDX_WIDTH - create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_s $HLS_CFG_AMT_MGS - create_hier_cell_dfx_decup [current_bd_instance .] dfx_decup_m $HLS_CFG_AMT_MGS - create_hier_cell_dfx_par [current_bd_instance .] dfx_par $HLS_CFG_AMT_MGS $HLS_CFG_MGS_WRAP_WIDTH - - - # Create interface connections - connect_bd_intf_net -intf_net S_AXI_DFX_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_DFX_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M00_AXI] - connect_bd_intf_net -intf_net S_AXI_INTR_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_INTR_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M02_AXI] - connect_bd_intf_net -intf_net S_AXI_MGQ_CTRL_1 [get_bd_intf_pins magic_seq_ctrl/S_AXI_MGQ_CTRL] [get_bd_intf_pins axi_interconnect_main_control/M01_AXI] - connect_bd_intf_net -intf_net axi_interconnect_dma_control_M00_AXI [get_bd_intf_pins axi_interconnect_dma_control/M00_AXI] [get_bd_intf_pins data_mover/S_AXI_DMA_CTRL] - - for {set i 0} {$i <= $HLS_CFG_AMT_MGS} {incr i} { - #### data mover connections -----> to master decoupler - connect_bd_intf_net -intf_net data_mover_M${i}_AXI [get_bd_intf_pins data_mover/M${i}_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_${i}] - #### master decoupler ------> to dfx region - connect_bd_intf_net -intf_net dfx_decup_m_s_intf_${i} [get_bd_intf_pins dfx_decup_m/s_intf_${i}] [get_bd_intf_pins dfx_par/S_AXI_${i}] - #### dfx region -------> to slave decoupler - connect_bd_intf_net -intf_net dfx_par_M_AXI_${i} [get_bd_intf_pins dfx_par/M_AXI_${i}] [get_bd_intf_pins dfx_decup_s/rp_intf_${i}] - #### slave decoupler -------> data mover - connect_bd_intf_net -intf_net dfx_decup_s_s_intf_${i} [get_bd_intf_pins dfx_decup_s/s_intf_${i}] [get_bd_intf_pins data_mover/S${i}_AXI] - - } - - - ###### data transfer connections - # connect_bd_intf_net -intf_net data_mover_M0_AXI [get_bd_intf_pins data_mover/M0_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_0] - # connect_bd_intf_net -intf_net data_mover_M1_AXI [get_bd_intf_pins data_mover/M1_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_1] - # connect_bd_intf_net -intf_net data_mover_M2_AXI [get_bd_intf_pins data_mover/M2_AXI] [get_bd_intf_pins dfx_decup_m/rp_intf_2] - # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_0 [get_bd_intf_pins dfx_decup_m/s_intf_0] [get_bd_intf_pins dfx_par/S_AXI_0] - # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_1 [get_bd_intf_pins dfx_decup_m/s_intf_1] [get_bd_intf_pins dfx_par/S_AXI_1] - # connect_bd_intf_net -intf_net dfx_decup_m_s_intf_2 [get_bd_intf_pins dfx_decup_m/s_intf_2] [get_bd_intf_pins dfx_par/S_AXI_2] - # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_0 [get_bd_intf_pins dfx_decup_s/s_intf_0] [get_bd_intf_pins data_mover/S0_AXI] - # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_1 [get_bd_intf_pins dfx_decup_s/s_intf_1] [get_bd_intf_pins data_mover/S1_AXI] - # connect_bd_intf_net -intf_net dfx_decup_s_s_intf_2 [get_bd_intf_pins dfx_decup_s/s_intf_2] [get_bd_intf_pins data_mover/S2_AXI] - # connect_bd_intf_net -intf_net dfx_par_M_AXI_0 [get_bd_intf_pins dfx_par/M_AXI_0] [get_bd_intf_pins dfx_decup_s/rp_intf_0] - # connect_bd_intf_net -intf_net dfx_par_M_AXI_1 [get_bd_intf_pins dfx_par/M_AXI_1] [get_bd_intf_pins dfx_decup_s/rp_intf_1] - # connect_bd_intf_net -intf_net dfx_par_M_AXI_2 [get_bd_intf_pins dfx_par/M_AXI_2] [get_bd_intf_pins dfx_decup_s/rp_intf_2] - - connect_bd_intf_net -intf_net data_mover_M_AXI_MM2S [get_bd_intf_pins data_mover/M_AXI_MM2S] [get_bd_intf_pins smartconnect_reader/S00_AXI] - connect_bd_intf_net -intf_net data_mover_M_AXI_S2MM [get_bd_intf_pins data_mover/M_AXI_S2MM] [get_bd_intf_pins smartconnect_writer/S00_AXI] - - connect_bd_intf_net -intf_net magic_seq_ctrl_M_AXI_DFX_LOADER [get_bd_intf_pins magic_seq_ctrl/M_AXI_DFX_LOADER] [get_bd_intf_pins smartconnect_reader/S01_AXI] - connect_bd_intf_net -intf_net magic_seq_ctrl_M_AXI_DMA_CTRL [get_bd_intf_pins magic_seq_ctrl/M_AXI_DMA_CTRL] [get_bd_intf_pins axi_interconnect_dma_control/S00_AXI] - connect_bd_intf_net -intf_net smartconnect_reader_M00_AXI [get_bd_intf_pins smartconnect_reader/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] - connect_bd_intf_net -intf_net smartconnect_writer_M00_AXI [get_bd_intf_pins smartconnect_writer/M00_AXI] [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC1_FPD] - 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 axi_interconnect_main_control/S00_AXI] - connect_bd_intf_net -intf_net zynq_ultra_ps_e_0_M_AXI_HPM1_FPD [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] [get_bd_intf_pins axi_interconnect_dma_control/S01_AXI] - - # Create port connections - connect_bd_net -net data_mover_finStore [get_bd_pins data_mover/finStore] [get_bd_pins magic_seq_ctrl/mgsFinExec] - connect_bd_net -net magic_seq_ctrl_decup [get_bd_pins magic_seq_ctrl/decup] [get_bd_pins dfx_decup_s/decouple] [get_bd_pins dfx_decup_m/decouple] - connect_bd_net -net magic_seq_ctrl_irq [get_bd_pins magic_seq_ctrl/irq] [get_bd_pins zynq_ultra_ps_e_0/pl_ps_irq0] - connect_bd_net -net magic_seq_ctrl_mgsLoadInit [get_bd_pins magic_seq_ctrl/mgsLoadInit] [get_bd_pins data_mover/loadInit] - connect_bd_net -net magic_seq_ctrl_mgsLoadReset [get_bd_pins magic_seq_ctrl/mgsLoadReset] [get_bd_pins data_mover/loadReset] - connect_bd_net -net magic_seq_ctrl_mgsStoreInit [get_bd_pins magic_seq_ctrl/mgsStoreInit] [get_bd_pins data_mover/storeInit] - connect_bd_net -net magic_seq_ctrl_mgsStoreReset [get_bd_pins magic_seq_ctrl/mgsStoreReset] [get_bd_pins data_mover/storeReset] - connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins rst_ps8_0_99M/peripheral_aresetn] [get_bd_pins axi_interconnect_dma_control/ARESETN] [get_bd_pins axi_interconnect_dma_control/M00_ARESETN] [get_bd_pins data_mover/nreset] [get_bd_pins axi_interconnect_dma_control/S00_ARESETN] [get_bd_pins magic_seq_ctrl/nreset] [get_bd_pins axi_interconnect_dma_control/S01_ARESETN] [get_bd_pins axi_interconnect_main_control/ARESETN] [get_bd_pins axi_interconnect_main_control/M00_ARESETN] [get_bd_pins axi_interconnect_main_control/M01_ARESETN] [get_bd_pins axi_interconnect_main_control/M02_ARESETN] [get_bd_pins axi_interconnect_main_control/S00_ARESETN] [get_bd_pins smartconnect_reader/aresetn] [get_bd_pins smartconnect_writer/aresetn] [get_bd_pins dfx_par/nreset] [get_bd_pins dfx_decup_s/nreset] [get_bd_pins dfx_decup_m/nreset] - 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_interconnect_dma_control/ACLK] [get_bd_pins rst_ps8_0_99M/slowest_sync_clk] [get_bd_pins axi_interconnect_dma_control/M00_ACLK] [get_bd_pins data_mover/clk] [get_bd_pins axi_interconnect_dma_control/S00_ACLK] [get_bd_pins magic_seq_ctrl/clk] [get_bd_pins axi_interconnect_dma_control/S01_ACLK] [get_bd_pins zynq_ultra_ps_e_0/maxihpm1_fpd_aclk] [get_bd_pins axi_interconnect_main_control/ACLK] [get_bd_pins axi_interconnect_main_control/M00_ACLK] [get_bd_pins axi_interconnect_main_control/M01_ACLK] [get_bd_pins axi_interconnect_main_control/M02_ACLK] [get_bd_pins axi_interconnect_main_control/S00_ACLK] [get_bd_pins zynq_ultra_ps_e_0/maxihpm0_fpd_aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc0_fpd_aclk] [get_bd_pins smartconnect_reader/aclk] [get_bd_pins zynq_ultra_ps_e_0/saxihpc1_fpd_aclk] [get_bd_pins smartconnect_writer/aclk] [get_bd_pins dfx_decup_m/clk] [get_bd_pins dfx_par/clk] [get_bd_pins dfx_decup_s/clk] - 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] - - delete_bd_objs [get_bd_addr_segs] [get_bd_addr_segs -excluded] - assign_bd_address - - convert_hier_cell_dfx_to_bd - #build_reconfig_module - - set n [llength $HLS_CFG_HLS_TOP_NAME] - - # Loop over each outer list index - for {set i 0} {$i < $n} {incr i} { - # Get sublists at index 0 of each inner list - set input_meta [lindex $HLS_CFG_MGS_S $i] - set output_meta [lindex $HLS_CFG_MGS_M $i] - set top_name [lindex $HLS_CFG_HLS_TOP_NAME $i] - - - build_reconfig_module2 $i $top_name $input_meta $output_meta $HLS_CFG_MGS_WRAP_WIDTH - - } - - current_bd_design [get_bd_designs system] - validate_bd_design - save_bd_design - - - #################################### - ### do dfx config ################## - #################################### - - - # # initialize the list with the main dfx_par.bd - set dfx_grp_list {"dfx_par.bd"} - - # append dynamic groups - for {set i 0} {$i < $n} {incr i} { - lappend dfx_grp_list "dfx_par_$i.bd" - } - - # join the list with colon ":" for the property string - set dfx_str [join $dfx_grp_list ":"] - - # set the properties - set_property -dict [list \ - CONFIG.LIST_SIM_BD "$dfx_str" \ - CONFIG.LIST_SYNTH_BD "$dfx_str" \ - ] [get_bd_cells dfx_par] - - current_bd_design [get_bd_designs system] - validate_bd_design - save_bd_design - - - -} - - -cr_bd_system \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/build_lib.sh b/hls4ml/templates/vitis_unified_partial/build_lib.sh deleted file mode 100644 index fd7f3c2cdb..0000000000 --- a/hls4ml/templates/vitis_unified_partial/build_lib.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/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=myproject -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/${PROJECT}_dm.cpp -o ${PROJECT}_dm.o -${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o -${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_dm.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so -rm -f *.o \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh b/hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh deleted file mode 100644 index 9dcd85f7d1..0000000000 --- a/hls4ml/templates/vitis_unified_partial/build_lib_multigraph.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/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_partial/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py deleted file mode 100644 index 980883ab7b..0000000000 --- a/hls4ml/templates/vitis_unified_partial/driver/pynq/pynq_driver.py +++ /dev/null @@ -1,69 +0,0 @@ -# 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 -import numpy as np -import os -import subprocess -import re -import time - - -class MyDfxCtrl(DefaultIP): - def __init__(self, description): - super().__init__(description=description) - - self.REG_ADDR_AP_CTRL = 0x00 - - self.INP_PORT_NAMEs = [ - #### hls-driver-input-dbg-name - ] - - self.REG_ADDR_INP_PTRs = [ - #### hls-driver-input-ptr - ] - self.REG_ADDR_INP_SZs = [ - #### hls-driver-input-size - ] - - self.OUT_PORT_NAMEs = [ - #### hls-driver-output-dbg-name - ] - - self.REG_ADDR_OUT_PTRs = [ - #### hls-driver-output-ptr - ] - - self.REG_ADDR_OUT_SZs = [ - #### hls-driver-output-size - ] - - bindto = ['xilinx.com:hls::1.0'] - - ######## TODO interrupt - - - def setSingleBit(self, addr, idx): - self.write(addr, 1 << idx) - - def ctrlStart(self): - self.write(0x00, 0x01) # ap_start = 1 - - def waitUntilDone(self): - while (self.read(0x00) & 0x2) == 0: # Wait for ap_done - time.sleep(0.001) - - def setInput(self, idx, buffer): - - print(f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {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) - self.write(self.REG_ADDR_INP_SZs[idx], buffer.size) - buffer.flush() - - def setOutput(self, idx, buffer): - - print(f"input {self.OUT_PORT_NAMEs[idx]} will be set to addr: {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) - self.write(self.REG_ADDR_OUT_SZs[idx], buffer.size) \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml deleted file mode 100644 index b7d7fd4cdf..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/component.xml +++ /dev/null @@ -1,331 +0,0 @@ - - - user.org - user - DummyStreamMaster - 1.0 - - - M_AXI - - - - - - - TDATA - - - M_AXI_TDATA - - - - - TLAST - - - M_AXI_TLAST - - - - - TVALID - - - M_AXI_TVALID - - - - - TREADY - - - M_AXI_TREADY - - - - - - reset - - - - - - - RST - - - reset - - - - - - clk - - - - - - - CLK - - - clk - - - - - - ASSOCIATED_BUSIF - M_AXI - - - ASSOCIATED_RESET - reset - - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - Verilog - DummyStreamMaster - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - 2ce15dc3 - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - Verilog - DummyStreamMaster - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - 2ce15dc3 - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - 83c2f9ad - - - - - - - M_AXI_TDATA - - out - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_TVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_TREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 1 - - - - - M_AXI_TLAST - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - clk - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - reset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - - - - xilinx_anylanguagesynthesis_view_fileset - - src/dummyStreamMaster.v - verilogSource - CHECKSUM_2ce15dc3 - IMPORTED_FILE - - - - xilinx_anylanguagebehavioralsimulation_view_fileset - - src/dummyStreamMaster.v - verilogSource - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/DummyStreamMaster_v1_0.tcl - tclSource - CHECKSUM_83c2f9ad - XGUI_VERSION_2 - - - - DummyStreamMaster - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - Component_Name - DummyStreamMaster_v1_0 - - - - - - virtex7 - qvirtex7 - versal - kintex7 - kintex7l - qkintex7 - qkintex7l - akintex7 - artix7 - artix7l - aartix7 - qartix7 - zynq - qzynq - azynq - spartan7 - aspartan7 - virtexu - zynquplus - virtexuplus - virtexuplusHBM - virtexuplus58g - kintexuplus - artixuplus - kintexu - - - /UserIP - - DummyStreamMaster - package_project - 3 - 2025-08-19T11:20:58Z - - - 2023.2 - - - - - - - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v deleted file mode 100755 index 5510e387a5..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/src/dummyStreamMaster.v +++ /dev/null @@ -1,23 +0,0 @@ -module DummyStreamMaster # -( - parameter integer DATA_WIDTH = 32, - parameter integer STORAGE_IDX_WIDTH = 10 //// 4 Kb -) -( - // AXIS Master Interface load interface - output wire [DATA_WIDTH-1:0] M_AXI_TDATA, -// output wire [DATA_WIDTH/8-1:0] M_AXI_TKEEP, // <= tkeep added - output wire M_AXI_TVALID, - input wire M_AXI_TREADY, - output wire M_AXI_TLAST, - - input wire clk, - input wire reset -); - -assign M_AXI_TDATA = 0; // Dummy implementation, always output zero -//assign M_AXI_TKEEP = 0; // Dummy implementation, always output zero -assign M_AXI_TVALID = 1'b0; // Dummy implementation, always not valid -assign M_AXI_TLAST = 1'b0; // Dummy implementation, always not last - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl deleted file mode 100644 index b3c93b639b..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_master/xgui/DummyStreamMaster_v1_0.tcl +++ /dev/null @@ -1,39 +0,0 @@ -# Definitional proc to organize widgets for parameters. -proc init_gui { IPINST } { - ipgui::add_param $IPINST -name "Component_Name" - #Adding Page - set Page_0 [ipgui::add_page $IPINST -name "Page 0"] - ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} - - -} - -proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to validate DATA_WIDTH - return true -} - -proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to validate STORAGE_IDX_WIDTH - return true -} - - -proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} -} - -proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} -} - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml deleted file mode 100644 index 07e8fb3fd7..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/component.xml +++ /dev/null @@ -1,344 +0,0 @@ - - - hls4ml_par_gen - user - DummyStreamSlave - 1.0 - - - S_AXI - - - - - - - TDATA - - - S_AXI_TDATA - - - - - TLAST - - - S_AXI_TLAST - - - - - TVALID - - - S_AXI_TVALID - - - - - TREADY - - - S_AXI_TREADY - - - - - - reset - - - - - - - RST - - - reset - - - - - - clk - - - - - - - CLK - - - clk - - - - - - ASSOCIATED_BUSIF - S_AXI - - - ASSOCIATED_RESET - reset - - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - Verilog - DummyStreamSlave - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - 3da6af3d - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - Verilog - DummyStreamSlave - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - 3da6af3d - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - 66396a2b - - - - - - - S_AXI_TDATA - - in - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_TVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_TREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_TLAST - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - clk - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - reset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - SINK_MODE - Sink Mode - 0 - - - - - - xilinx_anylanguagesynthesis_view_fileset - - src/dummyStreamSlave.v - verilogSource - CHECKSUM_3da6af3d - IMPORTED_FILE - - - - xilinx_anylanguagebehavioralsimulation_view_fileset - - src/dummyStreamSlave.v - verilogSource - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/DummyStreamSlave_v1_0.tcl - tclSource - CHECKSUM_66396a2b - XGUI_VERSION_2 - - - - DummyStreamSlave - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - SINK_MODE - Sink Mode - 0 - - - Component_Name - DummyStreamSlave_v1_0 - - - - - - virtex7 - qvirtex7 - versal - kintex7 - kintex7l - qkintex7 - qkintex7l - akintex7 - artix7 - artix7l - aartix7 - qartix7 - zynq - qzynq - azynq - spartan7 - aspartan7 - virtexu - zynquplus - virtexuplus - virtexuplusHBM - virtexuplus58g - kintexuplus - artixuplus - kintexu - - - /UserIP - - DummyStreamSlave - package_project - 2 - 2025-08-19T11:16:24Z - - - 2023.2 - - - - - - - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v deleted file mode 100755 index bac46af092..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/src/dummyStreamSlave.v +++ /dev/null @@ -1,21 +0,0 @@ -module DummyStreamSlave # -( - parameter integer DATA_WIDTH = 32, - parameter integer STORAGE_IDX_WIDTH = 10, //// 4 Kb - parameter [0:0] SINK_MODE = 0 -) -( - // AXIS Slave Interface store in terface - input wire [DATA_WIDTH-1:0] S_AXI_TDATA, -// input wire [DATA_WIDTH/8-1:0] S_AXI_TKEEP, // <= tkeep added - input wire S_AXI_TVALID, - output wire S_AXI_TREADY, - input wire S_AXI_TLAST, - - input wire clk, - input wire reset -); - -assign S_AXI_TREADY = SINK_MODE; // Dummy implementation, always not ready - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl deleted file mode 100644 index 6354d04f3c..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_dummy_slave/xgui/DummyStreamSlave_v1_0.tcl +++ /dev/null @@ -1,54 +0,0 @@ -# Definitional proc to organize widgets for parameters. -proc init_gui { IPINST } { - ipgui::add_param $IPINST -name "Component_Name" - #Adding Page - set Page_0 [ipgui::add_page $IPINST -name "Page 0"] - ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "SINK_MODE" -parent ${Page_0} - - -} - -proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to validate DATA_WIDTH - return true -} - -proc update_PARAM_VALUE.SINK_MODE { PARAM_VALUE.SINK_MODE } { - # Procedure called to update SINK_MODE when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.SINK_MODE { PARAM_VALUE.SINK_MODE } { - # Procedure called to validate SINK_MODE - return true -} - -proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to validate STORAGE_IDX_WIDTH - return true -} - - -proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} -} - -proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} -} - -proc update_MODELPARAM_VALUE.SINK_MODE { MODELPARAM_VALUE.SINK_MODE PARAM_VALUE.SINK_MODE } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.SINK_MODE}] ${MODELPARAM_VALUE.SINK_MODE} -} - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml deleted file mode 100644 index 029c716ca7..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/component.xml +++ /dev/null @@ -1,333 +0,0 @@ - - - user.org - user - icapWrap - 1.0 - - - ICAP - - - - - - - csib - - - CSIB - - - - - rdwrb - - - RDWRB - - - - - i - - - I - - - - - o - - - O - - - - - avail - - - AVAIL - - - - - prdone - - - PRDONE - - - - - prerror - - - PRERROR - - - - - - CLK - - - - - - - CLK - - - CLK - - - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - Verilog - icapWrap - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - 074c58b5 - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - Verilog - icapWrap - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - 074c58b5 - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - f92e9879 - - - - - - - CLK - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - AVAIL - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - O - - out - - 31 - 0 - - - - std_logic_vector - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - PRDONE - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - PRERROR - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - CSIB - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - I - - in - - 31 - 0 - - - - std_logic_vector - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - RDWRB - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - - xilinx_anylanguagesynthesis_view_fileset - - src/icapWrapper.v - verilogSource - CHECKSUM_074c58b5 - IMPORTED_FILE - - - - xilinx_anylanguagebehavioralsimulation_view_fileset - - src/icapWrapper.v - verilogSource - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/icapWrap_v1_0.tcl - tclSource - CHECKSUM_f92e9879 - XGUI_VERSION_2 - - - - icapWrap_v1_0 - - - Component_Name - icapWrap_v1_0 - - - - - - virtex7 - qvirtex7 - versal - kintex7 - kintex7l - qkintex7 - qkintex7l - akintex7 - artix7 - artix7l - aartix7 - qartix7 - zynq - qzynq - azynq - spartan7 - aspartan7 - virtexu - zynquplus - virtexuplus - virtexuplusHBM - virtexuplus58g - kintexuplus - artixuplus - kintexu - - - /UserIP - - icapWrap_v1_0 - package_project - 2 - 2025-08-21T08:13:00Z - - - 2023.2 - - - - - - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v deleted file mode 100755 index 6036c0244d..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/src/icapWrapper.v +++ /dev/null @@ -1,61 +0,0 @@ -`timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// -// Company: -// Engineer: -// -// Create Date: 06/22/2025 06:11:40 PM -// Design Name: -// Module Name: icapWrapper -// Project Name: -// Target Devices: -// Tool Versions: -// Description: -// -// Dependencies: -// -// Revision: -// Revision 0.01 - File Created -// Additional Comments: -// -////////////////////////////////////////////////////////////////////////////////// - - -module icapWrap( - input CLK, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP avail" *) output AVAIL, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP o" *) output [31:0] O, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP prdone" *) output PRDONE, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP prerror" *) output PRERROR, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP csib" *) input CSIB, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP i" *) input [31:0] I, - (* X_INTERFACE_INFO = "xilinx.com:interface:icap:1.0 ICAP rdwrb" *) input RDWRB - ); - - - -// ICAPE3: Internal Configuration Access Port -// UltraScale -// Xilinx HDL Language Template, version 2023.2 - -ICAPE3 #( - .DEVICE_ID(32'h03628093), // Specifies the pre-programmed Device ID value to be used for simulation - // purposes. - .ICAP_AUTO_SWITCH("DISABLE"), // Enable switch ICAP using sync word. - .SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation - // model. -) -ICAPE3_inst ( - .AVAIL(AVAIL), // 1-bit output: Availability status of ICAP. - .O(O), // 32-bit output: Configuration data output bus. - .PRDONE(PRDONE), // 1-bit output: Indicates completion of Partial Reconfiguration. - .PRERROR(PRERROR), // 1-bit output: Indicates error during Partial Reconfiguration. - .CLK(CLK), // 1-bit input: Clock input. - .CSIB(CSIB), // 1-bit input: Active-Low ICAP enable. - .I(I), // 32-bit input: Configuration data input bus. - .RDWRB(RDWRB) // 1-bit input: Read/Write Select input. -); - -// End of ICAPE3_inst instantiation - - -endmodule diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl deleted file mode 100644 index 0db18e9a9d..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_icap/xgui/icapWrap_v1_0.tcl +++ /dev/null @@ -1,10 +0,0 @@ -# Definitional proc to organize widgets for parameters. -proc init_gui { IPINST } { - ipgui::add_param $IPINST -name "Component_Name" - #Adding Page - ipgui::add_page $IPINST -name "Page 0" - - -} - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml deleted file mode 100644 index d489175403..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/component.xml +++ /dev/null @@ -1,1600 +0,0 @@ - - - user.org - user - MagicSeqTop - 1.0 - - - M_AXI - - - - - - - - - AWADDR - - - M_AXI_AWADDR - - - - - AWVALID - - - M_AXI_AWVALID - - - - - AWREADY - - - M_AXI_AWREADY - - - - - WDATA - - - M_AXI_WDATA - - - - - WSTRB - - - M_AXI_WSTRB - - - - - WVALID - - - M_AXI_WVALID - - - - - WREADY - - - M_AXI_WREADY - - - - - BRESP - - - M_AXI_BRESP - - - - - BVALID - - - M_AXI_BVALID - - - - - BREADY - - - M_AXI_BREADY - - - - - ARADDR - - - M_AXI_ARADDR - - - - - ARVALID - - - M_AXI_ARVALID - - - - - ARREADY - - - M_AXI_ARREADY - - - - - RDATA - - - M_AXI_RDATA - - - - - RRESP - - - M_AXI_RRESP - - - - - RVALID - - - M_AXI_RVALID - - - - - RREADY - - - M_AXI_RREADY - - - - - - S_AXI - - - - - - - - - AWADDR - - - S_AXI_AWADDR - - - - - AWVALID - - - S_AXI_AWVALID - - - - - AWREADY - - - S_AXI_AWREADY - - - - - WDATA - - - S_AXI_WDATA - - - - - WSTRB - - - S_AXI_WSTRB - - - - - WVALID - - - S_AXI_WVALID - - - - - WREADY - - - S_AXI_WREADY - - - - - BRESP - - - S_AXI_BRESP - - - - - BVALID - - - S_AXI_BVALID - - - - - BREADY - - - S_AXI_BREADY - - - - - ARADDR - - - S_AXI_ARADDR - - - - - ARVALID - - - S_AXI_ARVALID - - - - - ARREADY - - - S_AXI_ARREADY - - - - - RDATA - - - S_AXI_RDATA - - - - - RRESP - - - S_AXI_RRESP - - - - - RVALID - - - S_AXI_RVALID - - - - - RREADY - - - S_AXI_RREADY - - - - - - reset - - - - - - - RST - - - reset - - - - - - clk - - - - - - - CLK - - - clk - - - - - - ASSOCIATED_BUSIF - M_AXI:S_AXI - - - ASSOCIATED_RESET - reset - - - - - hw_intr - - - - - - - INTERRUPT - - - hw_intr - - - - - - SENSITIVITY - LEVEL_HIGH - - - - - - - M_AXI - M_AXI - 0x100000000 - 32 - - - - - S_AXI - S_AXI - - reg0 - reg0 - 0x0 - 0x10000 - 32 - register - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - Verilog - MagicSeqTop - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - 189b94c8 - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - Verilog - MagicSeqTop - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - 189b94c8 - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - 8684dac7 - - - - - - - clk - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - reset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_ARADDR - - in - - 15 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_ARVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_ARREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_RDATA - - out - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_RRESP - - out - - 1 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_RVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_RREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_AWADDR - - in - - 15 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_AWVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_AWREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_WDATA - - in - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_WSTRB - - in - - 3 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 1 - - - - - S_AXI_WVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_WREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_BRESP - - out - - 1 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_BVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_BREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_ARADDR - - out - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_ARVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_ARREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_RDATA - - in - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_RRESP - - in - - 1 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_RVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_RREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_AWADDR - - out - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_AWVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_AWREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_WDATA - - out - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_WSTRB - - out - - 3 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_WVALID - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_WREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_BRESP - - in - - 1 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_BVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_BREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - slaveReprog - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - nslaveReset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - slaveMgsStoreReset - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - slaveMgsLoadReset - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - slaveMgsStoreInit - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - slaveMgsLoadInit - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - mgsFinExec - - in - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_slaveInit - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_slaveFinInit - - out - - 7 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_slaveStartExec - - out - - 0 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_slaveStartExecAccept - - out - - 0 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - hw_ctrl_start - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - hw_intr_clear - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - hw_intr - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - GLOB_ADDR_WIDTH - Glob Addr Width - 32 - - - GLOB_DATA_WIDTH - Glob Data Width - 32 - - - ADDR_WIDTH - Addr Width - 16 - - - DATA_WIDTH - Data Width - 32 - - - BANK1_INDEX_WIDTH - Bank1 Index Width - 3 - - - BANK1_SRC_ADDR_WIDTH - Bank1 Src Addr Width - 32 - - - BANK1_SRC_SIZE_WIDTH - Bank1 Src Size Width - 26 - - - BANK1_DST_ADDR_WIDTH - Bank1 Dst Addr Width - 32 - - - BANK1_DST_SIZE_WIDTH - Bank1 Dst Size Width - 26 - - - BANK1_STATUS_WIDTH - Bank1 Status Width - 2 - - - BANK1_PROFILE_WIDTH - Bank1 Profile Width - 32 - - - BANK1_LD_MSK_WIDTH - Bank1 Ld Msk Width - 8 - - - BANK1_ST_MSK_WIDTH - Bank1 St Msk Width - 8 - - - BANK0_CONTROL_WIDTH - Bank0 Control Width - 4 - - - BANK0_STATUS_WIDTH - Bank0 Status Width - 4 - - - BANK0_CNT_WIDTH - Bank0 Cnt Width - 3 - - - BANK0_INTR_WIDTH - Bank0 Intr Width - 1 - - - BANK0_ROUNDTRIP_WIDTH - Bank0 Roundtrip Width - 16 - - - DMA_INIT_TASK_CNT - Dma Init Task Cnt - 8 - - - DMA_EXEC_TASK_CNT - Dma Exec Task Cnt - 1 - - - - - - choice_list_99a1d2b9 - LEVEL_HIGH - LEVEL_LOW - EDGE_RISING - EDGE_FALLING - - - - - xilinx_anylanguagesynthesis_view_fileset - - src/m_axi_read.v - verilogSource - IMPORTED_FILE - - - src/m_axi_write.v - verilogSource - IMPORTED_FILE - - - src/magicSeqCore.v - verilogSource - IMPORTED_FILE - - - src/s_axi_read.v - verilogSource - IMPORTED_FILE - - - src/s_axi_write.v - verilogSource - IMPORTED_FILE - - - src/slot.v - verilogSource - IMPORTED_FILE - - - src/slotTable.v - verilogSource - IMPORTED_FILE - - - src/magicSeq.v - verilogSource - CHECKSUM_feefee95 - IMPORTED_FILE - - - - xilinx_anylanguagebehavioralsimulation_view_fileset - - src/m_axi_read.v - verilogSource - IMPORTED_FILE - - - src/m_axi_write.v - verilogSource - IMPORTED_FILE - - - src/magicSeqCore.v - verilogSource - IMPORTED_FILE - - - src/s_axi_read.v - verilogSource - IMPORTED_FILE - - - src/s_axi_write.v - verilogSource - IMPORTED_FILE - - - src/slot.v - verilogSource - IMPORTED_FILE - - - src/slotTable.v - verilogSource - IMPORTED_FILE - - - src/magicSeq.v - verilogSource - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/MagicSeqTop_v1_0.tcl - tclSource - CHECKSUM_8684dac7 - XGUI_VERSION_2 - - - - MagicSeqTop - - - GLOB_ADDR_WIDTH - Glob Addr Width - 32 - - - GLOB_DATA_WIDTH - Glob Data Width - 32 - - - ADDR_WIDTH - Addr Width - 16 - - - DATA_WIDTH - Data Width - 32 - - - BANK1_INDEX_WIDTH - Bank1 Index Width - 3 - - - BANK1_SRC_ADDR_WIDTH - Bank1 Src Addr Width - 32 - - - BANK1_SRC_SIZE_WIDTH - Bank1 Src Size Width - 26 - - - BANK1_DST_ADDR_WIDTH - Bank1 Dst Addr Width - 32 - - - BANK1_DST_SIZE_WIDTH - Bank1 Dst Size Width - 26 - - - BANK1_STATUS_WIDTH - Bank1 Status Width - 2 - - - BANK1_PROFILE_WIDTH - Bank1 Profile Width - 32 - - - BANK1_LD_MSK_WIDTH - Bank1 Ld Msk Width - 8 - - - BANK1_ST_MSK_WIDTH - Bank1 St Msk Width - 8 - - - BANK0_CONTROL_WIDTH - Bank0 Control Width - 4 - - - BANK0_STATUS_WIDTH - Bank0 Status Width - 4 - - - BANK0_CNT_WIDTH - Bank0 Cnt Width - 3 - - - BANK0_INTR_WIDTH - Bank0 Intr Width - 1 - - - BANK0_ROUNDTRIP_WIDTH - Bank0 Roundtrip Width - 16 - - - DMA_INIT_TASK_CNT - Dma Init Task Cnt - 8 - - - DMA_EXEC_TASK_CNT - Dma Exec Task Cnt - 1 - - - Component_Name - MagicSeqTop_v1_0 - - - - - - virtex7 - qvirtex7 - versal - kintex7 - kintex7l - qkintex7 - qkintex7l - akintex7 - artix7 - artix7l - aartix7 - qartix7 - zynq - qzynq - azynq - spartan7 - aspartan7 - virtexu - zynquplus - virtexuplus - virtexuplusHBM - virtexuplus58g - kintexuplus - artixuplus - kintexu - - - /UserIP - - MagicSeqTop - package_project - 3 - 2025-08-21T09:29:51Z - - - 2023.2 - - - - - - - - - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v deleted file mode 100755 index e53b5aebf0..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_read.v +++ /dev/null @@ -1,48 +0,0 @@ -module m_axi_read #( - parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface - parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface - - parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots - parameter BANK1_SRC_ADDR_WIDTH = 32, - parameter BANK1_SRC_SIZE_WIDTH = 26, - parameter BANK1_DST_ADDR_WIDTH = 32, - parameter BANK1_DST_SIZE_WIDTH = 26, - parameter BANK1_STATUS_WIDTH = 2, - parameter BANK1_PROFILE_WIDTH = 32, - parameter BANK1_LD_MSK_WIDTH = 8, - parameter BANK1_ST_MSK_WIDTH = 8, - - parameter BANK0_CONTROL_WIDTH = 4, - parameter BANK0_STATUS_WIDTH = 4, - parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer - - parameter DMA_INIT_TASK_CNT = 8, //// (baseAddr0 + size0) + (baseAddr1 + size1) - parameter DMA_EXEC_TASK_CNT = 1 -)( - -input wire clk, -input wire reset, -/** ------------- AXI4-Lite Master Read Interface -it is supposed to connect to the DMA -*/ - -// Read Address Channel -output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_ARADDR, -output wire M_AXI_ARVALID, -input wire M_AXI_ARREADY, - -// Read Data Channel -input wire [GLOB_ADDR_WIDTH-1:0] M_AXI_RDATA, ////// read data output acctually it is a reg -input wire [1:0] M_AXI_RRESP, -input wire M_AXI_RVALID, -output wire M_AXI_RREADY -); - - -assign M_AXI_ARADDR = 0; -assign M_AXI_ARVALID = 0; - -assign M_AXI_RREADY = 0; - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v deleted file mode 100755 index a29e2eb030..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/m_axi_write.v +++ /dev/null @@ -1,205 +0,0 @@ -module m_axi_write #( - parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface - parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface - - parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots - parameter BANK1_SRC_ADDR_WIDTH = 32, - parameter BANK1_SRC_SIZE_WIDTH = 26, - parameter BANK1_DST_ADDR_WIDTH = 32, - parameter BANK1_DST_SIZE_WIDTH = 26, - parameter BANK1_STATUS_WIDTH = 2, - parameter BANK1_PROFILE_WIDTH = 32, - parameter BANK1_LD_MSK_WIDTH = 8, - parameter BANK1_ST_MSK_WIDTH = 8, - - parameter BANK0_CONTROL_WIDTH = 4, - parameter BANK0_STATUS_WIDTH = 4, - parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer - - parameter DMA_INIT_TASK_CNT = 8, //// (reset interrupt + startReadChannel + baseAddr0 + size0) + (reset interrupt + startWriteChannel + baseAddr1 + size1) - parameter DMA_EXEC_TASK_CNT = 1 -)( - input wire clk, - input wire reset, - - // AXI Lite Write Address Channel - output reg [GLOB_ADDR_WIDTH-1:0] M_AXI_AWADDR, ///// actually it is wire - output wire M_AXI_AWVALID, - input wire M_AXI_AWREADY, - - // AXI Lite Write Data Channel - output reg [GLOB_DATA_WIDTH-1:0] M_AXI_WDATA, ///// actually it is wire - output wire[(GLOB_DATA_WIDTH/8)-1:0] M_AXI_WSTRB, - output wire M_AXI_WVALID, - input wire M_AXI_WREADY, - - // AXI Lite Write Response Channel - input wire [1:0] M_AXI_BRESP, - input wire M_AXI_BVALID, - output wire M_AXI_BREADY, - - // dma base addr - input wire [GLOB_ADDR_WIDTH-1: 0] ext_bank0_out_dmaBaseAddr, - - // slave input - - input wire[DMA_INIT_TASK_CNT-1: 0] slaveInit , ///// trigger slave dma to do somthing - output reg [DMA_INIT_TASK_CNT-1: 0] slaveFinInit, - - input wire[DMA_EXEC_TASK_CNT-1: 0] slaveStartExec , - output reg [DMA_EXEC_TASK_CNT-1: 0] slaveStartExecAccept, ///// the slave dma is ready to start - - input wire [BANK1_DST_ADDR_WIDTH -1:0] slave_bank1_out_src_addr, // actually it is a reg - input wire [BANK1_DST_SIZE_WIDTH -1:0] slave_bank1_out_src_size, // actually it is a reg - input wire [BANK1_DST_ADDR_WIDTH -1:0] slave_bank1_out_des_addr, - input wire [BANK1_DST_SIZE_WIDTH -1:0] slave_bank1_out_des_size, - input wire [BANK1_STATUS_WIDTH -1:0] slave_bank1_out_status , // actually it is a reg - input wire [BANK1_PROFILE_WIDTH -1:0] slave_bank1_out_profile // actually it is a reg - -); - - -/** -* This module supposed to connet to dma -* -* -**/ - -//////// READ CHANNEL - -wire[GLOB_ADDR_WIDTH-1: 0] dmSrcStatusADDR = ext_bank0_out_dmaBaseAddr + 32'h04; - -wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcCtrlADDR = ext_bank0_out_dmaBaseAddr + 32'h00; -wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcDataAddrADDR = ext_bank0_out_dmaBaseAddr + 32'h18; -wire[GLOB_ADDR_WIDTH-1: 0] dmaSrcDataSizeADDR = ext_bank0_out_dmaBaseAddr + 32'h28; - -//////// WRITE CHANNEL - -wire[GLOB_ADDR_WIDTH-1: 0] dmDesStatusADDR = ext_bank0_out_dmaBaseAddr + 32'h34; - -wire[GLOB_ADDR_WIDTH-1: 0] dmaDesCtrlADDR = ext_bank0_out_dmaBaseAddr + 32'h30; -wire[GLOB_ADDR_WIDTH-1: 0] dmaDesDataAddrADDR = ext_bank0_out_dmaBaseAddr + 32'h48; -wire[GLOB_ADDR_WIDTH-1: 0] dmaDesDataSizeADDR = ext_bank0_out_dmaBaseAddr + 32'h58; - - -localparam STATUS_IDLE = 4'b0000; -localparam STATUS_WADDR = 4'b0001; -localparam STATUS_WDATA = 4'b0010; -localparam STATUS_RESP = 4'b0100; -localparam STATUS_UNLOCK = 4'b1000; - -/** -control main state machine -*/ - -reg[3:0] state; - -always @(posedge clk or negedge reset) begin - - if (~reset)begin - state = STATUS_IDLE; - end else begin - case(state) - STATUS_IDLE: begin - if ( (slaveInit != 0) | (slaveStartExec != 0)) begin state = STATUS_WADDR; end - end - STATUS_WADDR: begin - if (M_AXI_AWREADY) begin state = STATUS_WDATA; end - end - STATUS_WDATA: begin - if (M_AXI_WREADY) begin state = STATUS_RESP; end - end - STATUS_RESP: begin - if (M_AXI_BVALID) begin state = STATUS_UNLOCK; end - end - STATUS_UNLOCK: begin - state = STATUS_IDLE; - end - - default: begin - state = STATUS_IDLE; - end - endcase - end -end - -//// address channel -assign M_AXI_AWVALID = (state == STATUS_WADDR); -//// data channel -assign M_AXI_WSTRB = 4'b1111; -assign M_AXI_WVALID = (state == STATUS_WDATA); -//// resChannel -assign M_AXI_BREADY = (state == STATUS_RESP); - -///// manage address - -always @ (*) begin - - M_AXI_AWADDR = 0; - M_AXI_WDATA = 0; - - slaveFinInit = 0; - slaveStartExecAccept = 0; - - if (slaveInit != 0)begin - - if (state == STATUS_UNLOCK)begin //// STATUS_UNLOCK is one cycle - slaveFinInit = slaveInit; - end - - case(slaveInit) - - 8'b00000001: begin - M_AXI_AWADDR = dmSrcStatusADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0000}; //// start command - end - 8'b00000010: begin - M_AXI_AWADDR = dmDesStatusADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0000}; //// start command - end - //////////////////// set READ (RUN/SRCADDR/SRCSIZE) - 8'b00000100: begin - M_AXI_AWADDR = dmaSrcCtrlADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0001}; //// start command - end - 8'b00001000: begin - M_AXI_AWADDR = dmaSrcDataAddrADDR; - M_AXI_WDATA = slave_bank1_out_src_addr; - - end - 8'b00010000: begin - M_AXI_AWADDR = dmaSrcDataSizeADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - BANK1_DST_SIZE_WIDTH){1'b0}}, slave_bank1_out_src_size}; - end - //////////////////// set WRITE (RUN/DESADDR/DESSIZE) - 8'b00100000: begin - M_AXI_AWADDR = dmaDesCtrlADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - 13){1'b0}}, 13'b1_0000_0000_0001}; //// start command - end - 8'b01000000: begin - M_AXI_AWADDR = dmaDesDataAddrADDR; - M_AXI_WDATA = slave_bank1_out_des_addr; - end - 8'b10000000: begin - M_AXI_AWADDR = dmaDesDataSizeADDR; - M_AXI_WDATA = {{(GLOB_DATA_WIDTH - BANK1_DST_SIZE_WIDTH){1'b0}}, slave_bank1_out_des_size}; - end - default: begin - M_AXI_AWADDR = 0; - M_AXI_WDATA = 0; - slaveFinInit = 0; - slaveStartExecAccept = 0; - end - endcase - end - // end else if (slaveStartExec != 0) begin - // M_AXI_AWADDR = dmaCtrlAddrADDR; - // M_AXI_WDATA = 1; - // if (state == STATUS_UNLOCK)begin - // slaveFinInit = slaveInit; - // end - // end - -end - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v b/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v deleted file mode 100755 index 3af8df4627..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_seq/src/magicSeq.v +++ /dev/null @@ -1,634 +0,0 @@ -module MagicSeqTop #( - - parameter GLOB_ADDR_WIDTH = 32, // Address width for AXI interface - parameter GLOB_DATA_WIDTH = 32, // Data width for AXI interface - - parameter ADDR_WIDTH = 16, // Address width for AXI interface - parameter DATA_WIDTH = 32, // Data width for AXI interface - - parameter BANK1_INDEX_WIDTH = 3, // 2 ^ 2 = 4 slots - parameter BANK1_SRC_ADDR_WIDTH = 32, - parameter BANK1_SRC_SIZE_WIDTH = 26, - parameter BANK1_DST_ADDR_WIDTH = 32, - parameter BANK1_DST_SIZE_WIDTH = 26, - parameter BANK1_STATUS_WIDTH = 2, - parameter BANK1_PROFILE_WIDTH = 32, - parameter BANK1_LD_MSK_WIDTH = 8, - parameter BANK1_ST_MSK_WIDTH = 8, - - parameter BANK0_CONTROL_WIDTH = 4, - parameter BANK0_STATUS_WIDTH = 4, - parameter BANK0_CNT_WIDTH = BANK1_INDEX_WIDTH, /// the counter for the sequencer the BANK1_INDEX_WIDTH SHOULD BE EQUAL TO BANK0_CNT_WIDTH - parameter BANK0_INTR_WIDTH = 1, /// the round counter for the sequencer - parameter BANK0_ROUNDTRIP_WIDTH = 16, /// the round trip counter for the sequencer - - - parameter DMA_INIT_TASK_CNT = 8, //// (baseAddr0 + size0) + (baseAddr1 + size1) - parameter DMA_EXEC_TASK_CNT = 1 - -) ( - -input wire clk, -input wire reset, -/** -PS ------------ AXI4-Lite slave Read Interface -it is supposed to connect to the PS -*/ - -// Read Address Channel -input wire [ADDR_WIDTH-1:0] S_AXI_ARADDR, -input wire S_AXI_ARVALID, -output wire S_AXI_ARREADY, - -// Read Data Channel -output wire [DATA_WIDTH-1:0] S_AXI_RDATA, ////// read data output acctually it is a reg -output wire [1:0] S_AXI_RRESP, -output wire S_AXI_RVALID, -input wire S_AXI_RREADY, - -/** -PS ------------ AXI4-Lite slave write Interface -it is supposed to connect to the PS -*/ - -// AXI Lite Write Address Channel -input wire [ADDR_WIDTH-1:0] S_AXI_AWADDR, -input wire S_AXI_AWVALID, -output wire S_AXI_AWREADY, - -// AXI Lite Write Data Channel -input wire [DATA_WIDTH-1:0] S_AXI_WDATA, -input wire [(DATA_WIDTH/8)-1:0] S_AXI_WSTRB, -input wire S_AXI_WVALID, -output wire S_AXI_WREADY, - -// AXI Lite Write Response Channel -output wire [1:0] S_AXI_BRESP, -output wire S_AXI_BVALID, -input wire S_AXI_BREADY, - -/** - ------------ AXI4-Lite master read Interface -it is supposed to connect to the PS -*/ -// Read Address Channel -output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_ARADDR, -output wire M_AXI_ARVALID, -input wire M_AXI_ARREADY, - -// Read Data Channel -input wire [GLOB_ADDR_WIDTH-1:0] M_AXI_RDATA, ////// read data output acctually it is a reg -input wire [1:0] M_AXI_RRESP, -input wire M_AXI_RVALID, -output wire M_AXI_RREADY, - -/** - ------------ AXI4-Lite master write Interface -it is supposed to connect to the PS -*/ - -output wire [GLOB_ADDR_WIDTH-1:0] M_AXI_AWADDR, ///// actually it is wire -output wire M_AXI_AWVALID, -input wire M_AXI_AWREADY, - - // AXI Lite Write Data Channel -output wire[GLOB_DATA_WIDTH-1:0] M_AXI_WDATA, ///// actually it is wire -output wire[(GLOB_DATA_WIDTH/8)-1:0] M_AXI_WSTRB, -output wire M_AXI_WVALID, -input wire M_AXI_WREADY, - - // AXI Lite Write Response Channel -input wire [1:0] M_AXI_BRESP, -input wire M_AXI_BVALID, -output wire M_AXI_BREADY, - -output wire [(1 < - - user.org - user - MagicStreammerCore - 1.0 - - - M_AXI - - - - - - - TDATA - - - M_AXI_TDATA - - - - - TLAST - - - M_AXI_TLAST - - - - - TVALID - - - M_AXI_TVALID - - - - - TREADY - - - M_AXI_TREADY - - - - - - S_AXI - - - - - - - TDATA - - - S_AXI_TDATA - - - - - TLAST - - - S_AXI_TLAST - - - - - TVALID - - - S_AXI_TVALID - - - - - TREADY - - - S_AXI_TREADY - - - - - - reset - - - - - - - RST - - - reset - - - - - - clk - - - - - - - CLK - - - clk - - - - - - ASSOCIATED_BUSIF - M_AXI:S_AXI - - - ASSOCIATED_RESET - reset - - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - Verilog - MagicStreammerCore - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - d9829fdc - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - Verilog - MagicStreammerCore - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - d9829fdc - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - d79a4d11 - - - - - - - clk - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - reset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_TDATA - - in - - 31 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - S_AXI_TVALID - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_TREADY - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - S_AXI_TLAST - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 0 - - - - - M_AXI_TDATA - - out - - 31 - 0 - - - - reg - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_TVALID - - out - - - reg - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - M_AXI_TREADY - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - 1 - - - - - M_AXI_TLAST - - out - - - reg - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - storeReset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - loadReset - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - storeInit - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - loadInit - - in - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - finStore - - out - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_state - - out - - 3 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_amt_store_bytes - - out - - 10 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - dbg_amt_load_bytes - - out - - 10 - 0 - - - - wire - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - STATE_BIT_WIDTH - State Bit Width - 4 - - - - - - xilinx_anylanguagesynthesis_view_fileset - - src/magicStreamer.v - verilogSource - CHECKSUM_d9829fdc - IMPORTED_FILE - - - - xilinx_anylanguagebehavioralsimulation_view_fileset - - src/magicStreamer.v - verilogSource - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/MagicStreammerCore_v1_0.tcl - tclSource - CHECKSUM_d79a4d11 - XGUI_VERSION_2 - - - - MagicStreammerCore - - - DATA_WIDTH - Data Width - 32 - - - STORAGE_IDX_WIDTH - Storage Idx Width - 10 - - - STATE_BIT_WIDTH - State Bit Width - 4 - - - Component_Name - MagicStreammerCore_v1_0 - - - - - - virtex7 - qvirtex7 - versal - kintex7 - kintex7l - qkintex7 - qkintex7l - akintex7 - artix7 - artix7l - aartix7 - qartix7 - zynq - qzynq - azynq - spartan7 - aspartan7 - virtexu - zynquplus - virtexuplus - virtexuplusHBM - virtexuplus58g - kintexuplus - artixuplus - kintexu - - - /UserIP - - MagicStreammerCore - package_project - 2 - 2025-08-19T11:25:44Z - - - 2023.2 - - - - - - - - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v deleted file mode 100755 index da2f369d1f..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/src/magicStreamer.v +++ /dev/null @@ -1,161 +0,0 @@ -module MagicStreammerCore # -( - parameter integer DATA_WIDTH = 32, - parameter integer STORAGE_IDX_WIDTH = 10, //// 4 Kb - parameter integer STATE_BIT_WIDTH = 4 -) -( - input wire clk, - input wire reset, - - // AXIS Slave Interface store in terface - input wire [DATA_WIDTH-1:0] S_AXI_TDATA, -// input wire [DATA_WIDTH/8-1:0] S_AXI_TKEEP, // <= tkeep added //// we disable tkeep - input wire S_AXI_TVALID, - output wire S_AXI_TREADY, - input wire S_AXI_TLAST, - - // AXIS Master Interface load interface - output reg [DATA_WIDTH-1:0] M_AXI_TDATA, // it is supposed to be reg -// output wire [DATA_WIDTH/8-1:0] M_AXI_TKEEP, // it is supposed to be reg - output reg M_AXI_TVALID, // it is supposed to be reg - input wire M_AXI_TREADY, // it is supposed to be reg - output reg M_AXI_TLAST, // it is supposed to be reg - - // control signal - - input wire storeReset, - input wire loadReset, - input wire storeInit, - input wire loadInit, - - // store complete connect it to mgsFinExec - output wire finStore, - - // out put wire for debugging - output wire [STATE_BIT_WIDTH-1:0] dbg_state, - output wire [(STORAGE_IDX_WIDTH+1)-1:0] dbg_amt_store_bytes, - output wire [(STORAGE_IDX_WIDTH+1)-1:0] dbg_amt_load_bytes - -); - - - -///// declare state - -localparam STATUS_IDLE = 4'b0000; -localparam STATUS_STORE = 4'b0001; -localparam STATUS_LOAD = 4'b0010; - -localparam TRACKER_IDX_WIDTH = STORAGE_IDX_WIDTH + 1; ///// this is for tracker index width - -///// meta data -(* ram_style = "block" *) reg[DATA_WIDTH-1: 0] mainMem [0: ((1 << STORAGE_IDX_WIDTH) - 1)]; - -reg[STATE_BIT_WIDTH -1: 0] state; -reg[TRACKER_IDX_WIDTH-1: 0] amt_store_bytes; ///// store to this block -reg[TRACKER_IDX_WIDTH-1: 0] amt_load_bytes; ///// load to this block -reg storeIntr; - -///////////////////////////////////// -////// axi signal assign //////////// -///////////////////////////////////// - -///////// store -assign S_AXI_TREADY = (state == STATUS_STORE) && S_AXI_TVALID; -///////// load -////assign M_AXI_TKEEP = 4'b1111; -///////// interrupt signal -assign finStore = storeIntr; -/////////// debug signal -assign dbg_state = state; -assign dbg_amt_store_bytes = amt_store_bytes; -assign dbg_amt_load_bytes = amt_load_bytes; - -///////////////////////////////////// -////// control system //////////// -///////////////////////////////////// -always @(posedge clk, negedge reset) begin - - if (~reset) begin - state <= STATUS_IDLE; - amt_store_bytes <= 0; - amt_load_bytes <= 0; - storeIntr <= 0; - end else begin - case (state) - STATUS_IDLE : begin - if (storeReset) begin - amt_store_bytes <= 0; - storeIntr <= 0; - end else if (loadReset) begin - amt_load_bytes <= 0; - storeIntr <= 0; - end else if (storeInit) begin - state <= STATUS_STORE; - end else if (loadInit & (amt_store_bytes > 0)) begin - state <= STATUS_LOAD; - end - end - //////////// case store data to the internal memory - STATUS_STORE : begin - if (S_AXI_TVALID)begin //// we are sure that ready will send this time - amt_store_bytes <= amt_store_bytes + 1; - if (S_AXI_TLAST)begin - storeIntr <= 1; - state <= STATUS_IDLE; - end - end - end - STATUS_LOAD : begin - if (M_AXI_TREADY | (amt_load_bytes == 0)) begin //// last sending is success in this cycle/ send next - - if ( amt_load_bytes == amt_store_bytes )begin - /////// no data to send anymore - M_AXI_TVALID <= 0; - M_AXI_TLAST <= 0; - state <= STATUS_IDLE; - end else begin - M_AXI_TVALID <= 1; - M_AXI_TLAST <= (amt_load_bytes == (amt_store_bytes-1)); - amt_load_bytes <= amt_load_bytes + 1; - end - - end - ///// at here do nothing just wait for signal - - end - - - default: begin end - - endcase - end - -end - - - -///// M_DATA and MEM management - -always @(posedge clk) begin - if (state == STATUS_STORE)begin - if (S_AXI_TVALID)begin - mainMem[amt_store_bytes[STORAGE_IDX_WIDTH-1: 0]] <= S_AXI_TDATA; - end - - end else if (state == STATUS_LOAD) begin - - if (M_AXI_TREADY | (amt_load_bytes == 0))begin - if (amt_load_bytes == amt_store_bytes)begin - M_AXI_TDATA <= 48; - end else begin - M_AXI_TDATA <= mainMem[amt_load_bytes[STORAGE_IDX_WIDTH-1: 0]]; - end - end - - end -end - - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl deleted file mode 100644 index ca87eb5267..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer/xgui/MagicStreammerCore_v1_0.tcl +++ /dev/null @@ -1,54 +0,0 @@ -# Definitional proc to organize widgets for parameters. -proc init_gui { IPINST } { - ipgui::add_param $IPINST -name "Component_Name" - #Adding Page - set Page_0 [ipgui::add_page $IPINST -name "Page 0"] - ipgui::add_param $IPINST -name "DATA_WIDTH" -parent ${Page_0} - ipgui::add_param $IPINST -name "STATE_BIT_WIDTH" -parent ${Page_0} - - -} - -proc update_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to update DATA_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.DATA_WIDTH { PARAM_VALUE.DATA_WIDTH } { - # Procedure called to validate DATA_WIDTH - return true -} - -proc update_PARAM_VALUE.STATE_BIT_WIDTH { PARAM_VALUE.STATE_BIT_WIDTH } { - # Procedure called to update STATE_BIT_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.STATE_BIT_WIDTH { PARAM_VALUE.STATE_BIT_WIDTH } { - # Procedure called to validate STATE_BIT_WIDTH - return true -} - -proc update_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to update STORAGE_IDX_WIDTH when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.STORAGE_IDX_WIDTH { PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to validate STORAGE_IDX_WIDTH - return true -} - - -proc update_MODELPARAM_VALUE.DATA_WIDTH { MODELPARAM_VALUE.DATA_WIDTH PARAM_VALUE.DATA_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.DATA_WIDTH}] ${MODELPARAM_VALUE.DATA_WIDTH} -} - -proc update_MODELPARAM_VALUE.STORAGE_IDX_WIDTH { MODELPARAM_VALUE.STORAGE_IDX_WIDTH PARAM_VALUE.STORAGE_IDX_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.STORAGE_IDX_WIDTH}] ${MODELPARAM_VALUE.STORAGE_IDX_WIDTH} -} - -proc update_MODELPARAM_VALUE.STATE_BIT_WIDTH { MODELPARAM_VALUE.STATE_BIT_WIDTH PARAM_VALUE.STATE_BIT_WIDTH } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.STATE_BIT_WIDTH}] ${MODELPARAM_VALUE.STATE_BIT_WIDTH} -} - diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl deleted file mode 100644 index 33ec484957..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_prj/composer.tcl +++ /dev/null @@ -1,23 +0,0 @@ -create_project mgs_ip_prj . -part xczu9eg-ffvb1156-2-e -set_property board_part xilinx.com:zcu102:part0:3.4 [current_project] -add_files -norecurse ../magic_streamer_grp_src/streamGrp.v -update_compile_order -fileset sources_1 -add_files -norecurse ../magic_streamer/src/magicStreamer.v - - - - -ipx::package_project -root_dir ../magic_streamer_grp_ip -vendor user.org -library user -taxonomy /UserIP -import_files - - -set_property core_revision 2 [ipx::current_core] -ipx::create_xgui_files [ipx::current_core] -ipx::update_checksums [ipx::current_core] -ipx::check_integrity [ipx::current_core] - -ipx::save_core [ipx::current_core] -set_property ip_repo_paths ../magic_streamer_grp_ip [current_project] -update_ip_catalog - -close_project -exit diff --git a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v b/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v deleted file mode 100644 index 0ae634df5d..0000000000 --- a/hls4ml/templates/vitis_unified_partial/ips/magic_streamer_grp_src/streamGrp.v +++ /dev/null @@ -1,18 +0,0 @@ -`timescale 1ns / 1ps - -module streamGrp #( - // hls4ml-streamGrp-gen-parameter -)( - - // hls4ml-streamGrp-gen-io - - input wire clk, - input wire nreset - -); - - // hls4ml-streamGrp-gen-logic-assign - - // hls4ml-streamGrp-gen-create-module - -endmodule \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp b/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp deleted file mode 100644 index 5def3d4fce..0000000000 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include - -#include "WRAPPER_FILE_NAME.h" - -template -void enqueue_atom2layer(hls::stream& src_dma_stream, hls::stream& raw_stream, bool& isLastIndicate){ - - dma_data_packet dma_tmp; - for (int i = 0; i < (SIZE/INPUT_LAYER_ARR::size); i++){ - INPUT_LAYER_ARR ctype; - for (int j = 0; j < INPUT_LAYER_ARR::size; j++){ - src_dma_stream.read(dma_tmp); - ctype[j] = dma_tmp.data; - isLastIndicate = dma_tmp.last; - } - raw_stream.write(ctype); - } - -} - -template -void enqueue_layerStream2layer(hls::stream& src_mgs_stream, hls::stream& raw_stream, bool& isLastIndicate){ - - INPUT_LAYER_STREAM input_layer_stream_tmp; - for (unsigned i = 0; i < (SIZE/INPUT_LAYER_ARR::size); i++){ - INPUT_LAYER_ARR ctype; - src_mgs_stream.read(input_layer_stream_tmp); - ctype = input_layer_stream_tmp.data; - isLastIndicate = input_layer_stream_tmp.last; - raw_stream.write(ctype); - } - input_layer_stream_tmp.last = 0; - -} - - -template -void dequeue_layer2atom(hls::stream& des_dma_stream, hls::stream& raw_stream, bool isLastIndicate){ - dma_data_packet dma_tmp; - dma_tmp.last = 0; - for(unsigned i = 0; i < SIZE/OUTPUT_LAYER_ARR::size; ++i){ - OUTPUT_LAYER_ARR ctype = raw_stream.read(); - for(unsigned j = 0; j < OUTPUT_LAYER_ARR::size; ++j){ - dma_tmp.data = (ATOMIC_TYPE) (ctype[j]); - if(isLastIndicate){ - dma_tmp.last = (((i+1)*(j+1))==SIZE); - } - des_dma_stream.write(dma_tmp); - } - } - dma_tmp.last = 0; -} - -template -void dequeue_layer2layer(hls::stream& des_mgs_stream, hls::stream& raw_stream, bool isLastIndicate){ - - OUTPUT_LAYER_STREAM output_layer_stream_tmp; - output_layer_stream_tmp.last = 0; - for (unsigned i = 0; i < (SIZE/OUTPUT_LAYER_ARR::size); i++){ - OUTPUT_LAYER_ARR ctype = raw_stream.read(); - output_layer_stream_tmp.data = ctype; - if(isLastIndicate){ - output_layer_stream_tmp.last = ((i+1) == (SIZE/OUTPUT_LAYER_ARR::size)); - } - des_mgs_stream.write(output_layer_stream_tmp); - } - -} - -void MY_PROJECT_TOP_FUNC( -// hls-fpga-machine-learning insert multi-io - -) { - -// hls-fpga-machine-learning insert interface - -// hls-fpga-machine-learning insert local vars - -// hls-fpga-machine-learning insert isLast vars - -// hls-fpga-machine-learning insert enqueue - -// hls-fpga-machine-learning insert call - -// hls-fpga-machine-learning insert dequeue -} diff --git a/hls4ml/templates/vitis_unified_partial/myproject_axi.h b/hls4ml/templates/vitis_unified_partial/myproject_axi.h deleted file mode 100644 index be2955f956..0000000000 --- a/hls4ml/templates/vitis_unified_partial/myproject_axi.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FILENAME_H -#define FILENAME_H - -#include -#include "MY_PROJECT_AXI_INC.h" -#include "ap_axi_sdata.h" - -// hls-fpga-machine-learning insert include - -// hls-fpga-machine-learning insert definitions - -void MY_PROJECT_TOP_FUNC( - -// vitis-unified-wrapper-io - -); - - -#endif \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp b/hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp deleted file mode 100644 index 9a56f10d99..0000000000 --- a/hls4ml/templates/vitis_unified_partial/myproject_bridge.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#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_partial/myproject_test.cpp b/hls4ml/templates/vitis_unified_partial/myproject_test.cpp deleted file mode 100644 index 689d4f055b..0000000000 --- a/hls4ml/templates/vitis_unified_partial/myproject_test.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "firmware/myproject_axi.h" -#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_partial/workspace/projectName/vitis-comp.json b/hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json deleted file mode 100644 index c047eba31c..0000000000 --- a/hls4ml/templates/vitis_unified_partial/workspace/projectName/vitis-comp.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "{HLS_NAME}", - "type": "HLS", - "configuration": { - "componentType": "HLS", - "configFiles": ["{CONFIG_FILE}"], - "work_dir": "unifiedPrj" - } -} \ No newline at end of file From e3671460c6964d6aa4b2e35704086e5430d5996f Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 14:30:09 +0200 Subject: [PATCH 48/70] fix bridge gen top function name change --- .../writer/vitis_unified_writer/__init__.py | 10 +- .../vitis_unified_writer/test_bridge_gen.py | 2 +- .../vitis_unified_writer/test_cosim_gen.py | 225 +++++++++--------- 3 files changed, 119 insertions(+), 118 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index aac590b381..a0e0e932bf 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -69,8 +69,8 @@ def write_hls(self, model, is_multigraph=False): if is_multigraph: - super().write_hls(model, is_multigraph = True) - return + raise Exception("Vitis Unified does not support multigraphs; however, vitis unified partial backend is please use it instead") + ##### generate kernel and its driver self.generate_config(model) @@ -79,9 +79,9 @@ def write_hls(self, model, is_multigraph=False): ######### - self.make_export_path(model) - self.dg .write_driver (self.writer_meta, model, self.mg) - self.tcg.write_wrapper_test (self.writer_meta, model, self.mg) + self.make_export_path (model) + self.dg .write_driver (self.writer_meta, model, self.mg) + self.tcg.write_wrapper_test (self.writer_meta, model, self.mg) #self.write_new_tar(model) diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 75f8ee0f03..9918313180 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -74,7 +74,7 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): output_size_str = ', '.join(otuput_sizes) newline = '' - newline += indent + mg.get_top_model_name(model) + "(\n" + newline += indent + mg.get_top_wrap_func_name(model) + "(\n" newline += indent + inputs_str + ',\n' newline += indent + outputs_str + ',\n' newline += indent + input_size_str + ',\n' diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 16b3adbfec..4e969bd1e1 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -6,115 +6,116 @@ class VitisUnified_TestGen: @classmethod def write_wrapper_test(self, meta, model, mg): - - - #### warning we have to fix to float because the system locked by template - inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - - filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') - - 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 f.readlines(): - indent = ' ' * (len(line) - len(line.lstrip(' '))) - - #Insert numbers - if 'myproject' in line: - newline = line.replace('myproject', model.config.get_project_name()) - 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 - offset = 0 - for inputIdx, inp in enumerate(model_inputs): - ##### input should be float - newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template - inputPortName=mg.get_io_port_name(inp, True, inputIdx), - startIdx=str(offset) - ) - offset += inp.size() - for outputIdx, out in enumerate(model_outputs): - newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\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] - - for inpIdx, inp in enumerate(model_inputs): - input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) - input_ios.append(str(inp.size())) - - for outIdx, out in enumerate(model_outputs): - output_ios.append(mg.get_io_port_name(out, False, outIdx)) - output_ios.append(str(out.size())) - - # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) - top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' - newline += top_level - - elif '// hls-fpga-machine-learning insert predictions' in line: - newline = line - for outIdx, out in enumerate(model_outputs): - #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' - #### TODO fix this size retrieve - newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 - for inpIdx, inp in enumerate(model_inputs): - newline += indent + f'float {mg.get_io_port_name(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' - - for outIdx, out in enumerate(model_outputs): - newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\n" - - elif ( - '// hls-fpga-machine-learning insert output' in line - or '// hls-fpga-machine-learning insert quantized' in line - or '// hls-fpga-machine-learning insert tb-output' in line - ): - - newline = line - tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' - keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - newline += "/// warning keep is forced to be true\n" - - for outIdx, out in enumerate(model_outputs): - #### TODO fix this size retrieve - newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' - .format( actualType = "float", - arrName = mg.get_outputSizeArrName(model), - arrIdx = str(outIdx), - portName = mg.get_io_port_name(out, False, outIdx), - des = dest, - keepOutput = keep_output)) - - 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) - f.close() - fout.close() + pass + + # + # #### warning we have to fix to float because the system locked by template + # inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + # + # filedir = os.path.dirname(os.path.abspath(__file__)) + # f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) + # fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + # + # 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 f.readlines(): + # indent = ' ' * (len(line) - len(line.lstrip(' '))) + # + # #Insert numbers + # if 'myproject' in line: + # newline = line.replace('myproject', model.config.get_project_name()) + # 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 + # offset = 0 + # for inputIdx, inp in enumerate(model_inputs): + # ##### input should be float + # newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + # inputPortName=mg.get_io_port_name(inp, True, inputIdx), + # startIdx=str(offset) + # ) + # offset += inp.size() + # for outputIdx, out in enumerate(model_outputs): + # newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\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] + # + # for inpIdx, inp in enumerate(model_inputs): + # input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) + # input_ios.append(str(inp.size())) + # + # for outIdx, out in enumerate(model_outputs): + # output_ios.append(mg.get_io_port_name(out, False, outIdx)) + # output_ios.append(str(out.size())) + # + # # Concatenate the input, output, and bram variables. Filter out empty/null values + # all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) + # top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' + # newline += top_level + # + # elif '// hls-fpga-machine-learning insert predictions' in line: + # newline = line + # for outIdx, out in enumerate(model_outputs): + # #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + # #### TODO fix this size retrieve + # newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 + # for inpIdx, inp in enumerate(model_inputs): + # newline += indent + f'float {mg.get_io_port_name(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' + # + # for outIdx, out in enumerate(model_outputs): + # newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\n" + # + # elif ( + # '// hls-fpga-machine-learning insert output' in line + # or '// hls-fpga-machine-learning insert quantized' in line + # or '// hls-fpga-machine-learning insert tb-output' in line + # ): + # + # newline = line + # tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + # dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' + # keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" + # newline += "/// warning keep is forced to be true\n" + # + # for outIdx, out in enumerate(model_outputs): + # #### TODO fix this size retrieve + # newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + # .format( actualType = "float", + # arrName = mg.get_outputSizeArrName(model), + # arrIdx = str(outIdx), + # portName = mg.get_io_port_name(out, False, outIdx), + # des = dest, + # keepOutput = keep_output)) + # + # 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) + # f.close() + # fout.close() From ac04d40aa660c9dd1473b7045550aa2893c36f79 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 15:53:12 +0200 Subject: [PATCH 49/70] clean vitis config: test using bridge test and it pass --- hls4ml/backends/vitis_unified/__init__.py | 0 .../vitis_unified/vitis_unified_backend.py | 33 ++--- .../vitis_unified/vitis_unified_config.py | 140 ++---------------- 3 files changed, 25 insertions(+), 148 deletions(-) delete mode 100644 hls4ml/backends/vitis_unified/__init__.py diff --git a/hls4ml/backends/vitis_unified/__init__.py b/hls4ml/backends/vitis_unified/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 8f1d5f6ace..7b4b236ff4 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -130,7 +130,7 @@ def build( def create_initial_config( self, - board ='pynq-z2', + board ='zcu102', part =None, clock_period =5, clock_uncertainty ='12.5%', @@ -143,31 +143,24 @@ def create_initial_config( gmemBuf_out_size =12, xpfmPath ='/tools/Xilinx/Vitis/2023.2/base_platforms/' 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', - input_interim_type ='io_stream', #### it should be io_stream or io_free_stream/ io_stream - output_interim_type ='io_stream', **_ ): - if input_interim_type not in ['io_free_stream', 'io_stream']: - raise Exception(f'input_interim_type should be io_free_stream or io_stream, but got {input_interim_type}') - if output_interim_type not in ['io_free_stream', 'io_stream']: - raise Exception(f'output_interim_type should be io_free_stream or io_stream, but got {output_interim_type}') - config = super().create_initial_config(part, clock_period, clock_uncertainty, io_type) - config['AcceleratorConfig'] = {} - config['AcceleratorConfig']['Board'] = board - config['AcceleratorConfig']['Interface'] = interface # axi_stream, axi_master, axi_lite - config['AcceleratorConfig']['Driver'] = driver - config['AcceleratorConfig']['Precision'] = {} - config['AcceleratorConfig']['Precision']['Input'] = {} - config['AcceleratorConfig']['Precision']['Output'] = {} - config['AcceleratorConfig']['Precision']['Input'] = input_type # float, double or ap_fixed - config['AcceleratorConfig']['Precision']['Output'] = output_type # float, double or ap_fixed config['UnifiedConfig'] = {} - config['UnifiedConfig']['bufInSize'] = gmemBuf_in_size - config['UnifiedConfig']['bufOutSize'] = gmemBuf_out_size - config['UnifiedConfig']['XPFMPath'] = xpfmPath + config['UnifiedConfig']['bufInSize' ] = gmemBuf_in_size + config['UnifiedConfig']['bufOutSize' ] = gmemBuf_out_size + config['UnifiedConfig']['XPFMPath' ] = xpfmPath + config['UnifiedConfig']['Board' ] = board + config['UnifiedConfig']['Driver' ] = driver + config['UnifiedConfig']['InputDtype' ] = input_type # float, double or ap_fixed + config['UnifiedConfig']['OutputDtype'] = output_type # float, double or ap_fixed + + 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 diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index 7f78b8d69a..4dbce51444 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -8,98 +8,35 @@ class VitisUnifiedConfig: def __init__(self, config, model_inputs, model_outputs): self.config = config.config - self.board = "zcu102" - # self.board = self.config.get('AcceleratorConfig', {}).get('Board', 'pynq-z2') - # self.supported_boards = json.load(open(os.path.dirname(__file__) + '/supported_boards.json')) - # if self.board in self.supported_boards.keys(): - # board_info = self.supported_boards[self.board] - # self.part = board_info['part'] - # else: - # raise Exception('The board does not appear in supported_boards.json file') - - self.gmem_in_bufferSz = self.config.get("UnifiedConfig", {}).get("bufInSize", 12) - self.gmem_out_bufferSz = self.config.get("UnifiedConfig", {}).get("bufOutSize", 12) - self.XPFMPath = self.config.get("UnifiedConfig", {}).get("XPFMPath", "") - - # if self.config.get('Part') is not None: - # if self.config.get('Part') != self.part: - # print( - # 'WARNING: You set a Part that does not correspond to the Board you specified. The correct ' - # 'Part is now set.' - # ) - # self.config['Part'] = self.part - accel_config = self.config.get('AcceleratorConfig', None) - if accel_config is not None: - prec = accel_config.get('Precision') - if prec is None: - raise Exception('Precision must be provided in the AcceleratorConfig') - else: - if prec.get('Input') is None or prec.get('Output') is None: - raise Exception('Input and Output fields must be provided in the AcceleratorConfig->Precision') - else: - accel_config = { - 'Precision': {'Input': 'float', 'Output': 'float'}, - 'Driver': 'python', - 'Interface': 'axi_stream', - } - config.config['AcceleratorConfig'] = accel_config - - self.interface = self.config['AcceleratorConfig'].get('Interface', 'axi_stream') # axi_stream, axi_master, axi_lite - self.driver = self.config['AcceleratorConfig'].get('Driver', 'python') # python or c - self.input_type = self.config['AcceleratorConfig']['Precision'].get( - 'Input', 'float' - ) # float, double or ap_fixed - self.output_type = self.config['AcceleratorConfig']['Precision'].get( - 'Output', 'float' - ) # float, double or ap_fixed - self.platform = self.config['AcceleratorConfig'].get( - 'Platform', 'xilinx_u250_xdma_201830_2' - ) # Get platform folder name + self.board = self.config.get('UnifiedConfig', {}).get('Board', 'pynq-z2') + self.gmem_in_bufferSz = self.config["UnifiedConfig"]["bufInSize"] + self.gmem_out_bufferSz = self.config["UnifiedConfig"]["bufOutSize"] + self.XPFMPath = self.config["UnifiedConfig"]["XPFMPath"] + + self.driver = self.config['UnifiedConfig']['Driver'] + self.input_type = self.config['UnifiedConfig']['InputDtype' ] + self.output_type = self.config['UnifiedConfig']['OutputDtype'] assert ( len(model_inputs) >= 1 - ), "Only models with at least one input tensor are currently supported by VitisAcceleratorIPFlowPartialBackend" + ), "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 VitisAcceleratorIPFlowPartialBackend" + ), "Only models with one output tensor are currently supported by VitisUnified" self.inps = model_inputs.copy() self.outs = model_outputs.copy() inp_axi_t = self.input_type out_axi_t = self.output_type - if inp_axi_t not in ['float', 'double']: - self.input_type = self._next_factor8_type(config.backend.convert_precision_string(inp_axi_t)) - if out_axi_t not in ['float', 'double']: - self.output_type = self._next_factor8_type(config.backend.convert_precision_string(out_axi_t)) - if self.input_type == 'float': self.input_bitwidth = 32 - elif self.input_type == 'double': + else:# self.input_type == 'double': self.input_bitwidth = 64 - else: - self.input_bitwidth = config.backend.convert_precision_string(inp_axi_t).width if out_axi_t == 'float': self.output_bitwidth = 32 - elif out_axi_t == 'double': + else:# out_axi_t == 'double': self.output_bitwidth = 64 - else: - self.output_bitwidth = config.backend.convert_precision_string(out_axi_t).width - - def _next_factor8_type(self, p): - '''Return a new type with the width rounded to the next factor of 8 up to p's width - Args: - p : IntegerPrecisionType or FixedPrecisionType - Returns: - An IntegerPrecisionType or FixedPrecisionType with the width rounder up to the next factor of 8 - of p's width. Other parameters (fractional bits, extra modes) stay the same. - ''' - W = p.width - newW = int(np.ceil(W / 8) * 8) - if isinstance(p, FixedPrecisionType): - return FixedPrecisionType(newW, p.integer, p.signed, p.rounding_mode, p.saturation_mode, p.saturation_bits) - elif isinstance(p, IntegerPrecisionType): - return IntegerPrecisionType(newW, p.signed) def get_io_bitwidth(self): return self.input_bitwidth, self.output_bitwidth @@ -107,71 +44,18 @@ def get_io_bitwidth(self): def get_corrected_types(self): return self.input_type, self.output_type, self.inps, self.outs - def get_interface(self): - return self.interface - - def get_board_info(self, board=None): - if board is None: - board = self.board - if board in self.supported_boards.keys(): - return self.supported_boards[board] - else: - raise Exception('The board is still not supported') - - def get_part(self): - return self.part - def get_driver(self): return self.driver def get_board(self): return self.board - def get_platform(self): - return self.platform - - def get_clock_period(self): - return self.clock_period - - def get_driver_path(self): - if self.board.startswith('alveo'): - return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + self.driver + '_drivers/' + self.get_driver_file() - else: - return ( - '../templates/vitis_accelerator_ip_flow/' - + self.board - + '/' - + self.driver - + '_drivers/' - + self.get_driver_file() - ) - - def get_driver_file(self): - driver_ext = '.py' if self.driver == 'python' else '.h' - return self.interface + '_driver' + driver_ext - - def get_krnl_rtl_src_dir(self): - return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + '/krnl_rtl_src' - def get_input_type(self): return self.input_type def get_output_type(self): return self.output_type - def get_tcl_file_path(self): - board_info = self.get_board_info(self.board) - tcl_scripts = board_info.get('tcl_scripts', None) - if tcl_scripts is None: - raise Exception('No tcl scripts definition available for the board in supported_board.json') - tcl_script = tcl_scripts.get(self.interface, None) - if tcl_script is None: - raise Exception('No tcl script definition available for the desired interface in supported_board.json') - if self.board.startswith('alveo'): - return '../templates/vitis_accelerator_ip_flow/' + 'alveo/' + '/tcl_scripts/' + tcl_script - else: - return '../templates/vitis_accelerator_ip_flow/' + self.board + '/tcl_scripts/' + tcl_script - def get_gmem_in_bufferSz(self): return self.gmem_in_bufferSz From dfbbc3de86f1ee9c6abe1c09d167caf5d31b179f Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 15:57:09 +0200 Subject: [PATCH 50/70] add to check accept only io stream --- hls4ml/backends/vitis_unified/vitis_unified_backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 7b4b236ff4..22597dd365 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -134,8 +134,7 @@ def create_initial_config( part =None, clock_period =5, clock_uncertainty ='12.5%', - io_type ='io_parallel', - interface ='axi_stream', + io_type ='io_stream', driver ='python', input_type ='float', output_type ='float', @@ -157,6 +156,8 @@ def create_initial_config( config['UnifiedConfig']['InputDtype' ] = input_type # float, double or ap_fixed config['UnifiedConfig']['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"]: From 04d0e6d1d01ed0536d15d20f6e24fcea87b3f058 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 16:17:40 +0200 Subject: [PATCH 51/70] add bridge gen to support both float and double input --- hls4ml/backends/vitis_unified/vitis_unified_backend.py | 1 - hls4ml/backends/vitis_unified/vitis_unified_config.py | 4 ++++ hls4ml/writer/vitis_unified_writer/test_bridge_gen.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 22597dd365..fd1b2aaf38 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -171,7 +171,6 @@ def get_default_flow(self): def get_writer_flow(self): return self._writer_flow - def _register_flows(self): vitis_ip = 'vitis:ip' writer_passes = ['make_stamp', 'vitisunified:write_hls'] diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index 4dbce51444..bf745e7027 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -17,6 +17,10 @@ def __init__(self, config, model_inputs, model_outputs): self.driver = self.config['UnifiedConfig']['Driver'] self.input_type = self.config['UnifiedConfig']['InputDtype' ] self.output_type = self.config['UnifiedConfig']['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" diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 9918313180..fdf3667a30 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -54,7 +54,7 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): elif '// hls-fpga-machine-learning insert wrapper' in line: dtype = line.split('#', 1)[1].strip() - if dtype == 'float': + if dtype == meta.vitis_unified_config.get_input_type(): newline = '' input_vars = [] input_sizes = [] From b77e22f419d99a2474bb959eecf7747dd653ad95 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 17:21:12 +0200 Subject: [PATCH 52/70] fix size getting bug in cosim --- .../vitis_unified_writer/test_cosim_gen.py | 222 +++++++++--------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 4e969bd1e1..47eb0363c2 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -8,114 +8,114 @@ class VitisUnified_TestGen: def write_wrapper_test(self, meta, model, mg): pass - # - # #### warning we have to fix to float because the system locked by template - # inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - # - # filedir = os.path.dirname(os.path.abspath(__file__)) - # f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) - # fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') - # - # 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 f.readlines(): - # indent = ' ' * (len(line) - len(line.lstrip(' '))) - # - # #Insert numbers - # if 'myproject' in line: - # newline = line.replace('myproject', model.config.get_project_name()) - # 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 - # offset = 0 - # for inputIdx, inp in enumerate(model_inputs): - # ##### input should be float - # newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template - # inputPortName=mg.get_io_port_name(inp, True, inputIdx), - # startIdx=str(offset) - # ) - # offset += inp.size() - # for outputIdx, out in enumerate(model_outputs): - # newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\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] - # - # for inpIdx, inp in enumerate(model_inputs): - # input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) - # input_ios.append(str(inp.size())) - # - # for outIdx, out in enumerate(model_outputs): - # output_ios.append(mg.get_io_port_name(out, False, outIdx)) - # output_ios.append(str(out.size())) - # - # # Concatenate the input, output, and bram variables. Filter out empty/null values - # all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) - # top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' - # newline += top_level - # - # elif '// hls-fpga-machine-learning insert predictions' in line: - # newline = line - # for outIdx, out in enumerate(model_outputs): - # #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' - # #### TODO fix this size retrieve - # newline += indent + f'for(int i = 0; i < {mg.get_outputSizeArrName(model)}[{outIdx}]; 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 - # for inpIdx, inp in enumerate(model_inputs): - # newline += indent + f'float {mg.get_io_port_name(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' - # - # for outIdx, out in enumerate(model_outputs): - # newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\n" - # - # elif ( - # '// hls-fpga-machine-learning insert output' in line - # or '// hls-fpga-machine-learning insert quantized' in line - # or '// hls-fpga-machine-learning insert tb-output' in line - # ): - # - # newline = line - # tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - # dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' - # keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - # newline += "/// warning keep is forced to be true\n" - # - # for outIdx, out in enumerate(model_outputs): - # #### TODO fix this size retrieve - # newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' - # .format( actualType = "float", - # arrName = mg.get_outputSizeArrName(model), - # arrIdx = str(outIdx), - # portName = mg.get_io_port_name(out, False, outIdx), - # des = dest, - # keepOutput = keep_output)) - # - # 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) - # f.close() - # fout.close() + + #### warning we have to fix to float because the system locked by template + inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() + + filedir = os.path.dirname(os.path.abspath(__file__)) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) + fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + + 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 f.readlines(): + indent = ' ' * (len(line) - len(line.lstrip(' '))) + + #Insert numbers + if 'myproject' in line: + newline = line.replace('myproject', model.config.get_project_name()) + 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 + offset = 0 + for inputIdx, inp in enumerate(model_inputs): + ##### input should be float + newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + inputPortName=mg.get_io_port_name(inp, True, inputIdx), + startIdx=str(offset) + ) + offset += inp.size() + for outputIdx, out in enumerate(model_outputs): + newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\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] + + for inpIdx, inp in enumerate(model_inputs): + input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) + input_ios.append(str(inp.size())) + + for outIdx, out in enumerate(model_outputs): + output_ios.append(mg.get_io_port_name(out, False, outIdx)) + output_ios.append(str(out.size())) + + # Concatenate the input, output, and bram variables. Filter out empty/null values + all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) + top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' + newline += top_level + + elif '// hls-fpga-machine-learning insert predictions' in line: + newline = line + for outIdx, out in enumerate(model_outputs): + #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + #### TODO fix this size retrieve + newline += indent + f'for(int i = 0; i < {out.size()}[{outIdx}]; 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 + for inpIdx, inp in enumerate(model_inputs): + newline += indent + f'float {mg.get_io_port_name(inp, True, inpIdx)}[{str(inp.size())}] = {{}};\n' + + for outIdx, out in enumerate(model_outputs): + newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\n" + + elif ( + '// hls-fpga-machine-learning insert output' in line + or '// hls-fpga-machine-learning insert quantized' in line + or '// hls-fpga-machine-learning insert tb-output' in line + ): + + newline = line + tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') + dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' + keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" + newline += "/// warning keep is forced to be true\n" + + for outIdx, out in enumerate(model_outputs): + #### TODO fix this size retrieve + newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + .format( actualType = "float", + arrName = out.size(), + arrIdx = str(outIdx), + portName = mg.get_io_port_name(out, False, outIdx), + des = dest, + keepOutput = keep_output)) + + 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) + f.close() + fout.close() From e14f2c6bf306e6fae283f7c6dce1d2024d7ba39d Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 26 Aug 2025 20:43:28 +0200 Subject: [PATCH 53/70] fix config to gen two kernel hardware cfg for csim and csim --- .../vitis_unified/vitis_unified_backend.py | 10 +++++++- .../vitis_unified/hls_kernel_config.cfg | 14 +++++------ .../vitis_unified/myproject_test.cpp | 3 ++- .../writer/vitis_unified_writer/__init__.py | 3 ++- .../writer/vitis_unified_writer/build_gen.py | 16 ++++++++----- .../writer/vitis_unified_writer/meta_gen.py | 4 ++-- .../vitis_unified_writer/test_cosim_gen.py | 24 +++++++++++-------- .../writer/vitis_unified_writer/wrap_gen.py | 2 +- 8 files changed, 47 insertions(+), 29 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index fd1b2aaf38..b1bb73aae7 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -112,13 +112,16 @@ def build( kerlink_cwd = mg.get_vitis_linker_dir(model) if synth: + self.prepare_sim_config_file(model, True) self.run_term_command(model, "csynth", csynth_cmd, log_to_stdout, csynth_cwd) self.run_term_command(model, "package", package_cmd, log_to_stdout, package_cwd) if csim: + self.prepare_sim_config_file(model, True) self.run_term_command(model, "csim", csim_cmd, log_to_stdout, csim_cwd) if cosim: + self.prepare_sim_config_file(model, False) self.run_term_command(model, "cosim", cosim_cmd, log_to_stdout, cosim_cwd) ##if bitfile @@ -126,7 +129,12 @@ def build( self.run_term_command(model, "kerlink", kerlink_cmd, log_to_stdout, kerlink_cwd) - + 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, diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg index c7cda021b1..7f26ce764a 100644 --- a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -4,18 +4,18 @@ part={PART} clock={CLK} clock_uncertainty={CLK_UC} flow_target=vivado -syn.file={OUTDIR}/firmware/{FILE_NAME_DM}.cpp -syn.file={OUTDIR}/firmware/{FILE_NAME_AXIS}.cpp +syn.file={OUTDIR}/firmware/{FILE_NAME_WRAP}.cpp syn.file={OUTDIR}/firmware/{FILE_NAME_BASE}.cpp -syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_DM}.cpp,-std=c++0x -syn.file_cflags={OUTDIR}/firmware/{FILE_NAME_AXIS}.cpp,-std=c++0x +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}/{PRJ_NAME}_test.cpp + +tb.file={OUTDIR}/{SIM_FILE_NAME}.cpp tb.file={OUTDIR}/firmware/weights tb.file={OUTDIR}/tb_data -tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-std=c++0x -tb.file_cflags={OUTDIR}/{PRJ_NAME}_test.cpp,-DRTL_SIM +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 diff --git a/hls4ml/templates/vitis_unified/myproject_test.cpp b/hls4ml/templates/vitis_unified/myproject_test.cpp index 689d4f055b..a8d031e304 100644 --- a/hls4ml/templates/vitis_unified/myproject_test.cpp +++ b/hls4ml/templates/vitis_unified/myproject_test.cpp @@ -7,7 +7,8 @@ #include #include -#include "firmware/myproject_axi.h" +// hls-fpga-machine-learning insert include + #include "firmware/nnet_utils/nnet_helpers.h" // hls-fpga-machine-learning insert bram diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index a0e0e932bf..928c95e048 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -48,7 +48,8 @@ def write_build_script(self, model): self.bg.write_bridge_build_script(self.writer_meta, model, self.mg) #### for hls kernel generation self.bg.build_unified_project_ske(self.writer_meta, model, self.mg) - self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg) + self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg, True) + self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg, False) #### for v++ to link hls to the system self.bg.write_launch_vitis_linker_dir(self.writer_meta, model, self.mg) self.bg.write_launch_vitis_linker_launcher(self.writer_meta, model, self.mg) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 530b3ae792..27c6d68164 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -31,10 +31,11 @@ def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC) @classmethod - def write_hls_kernel_cfg(self, meta, model, mg): + def write_hls_kernel_cfg(self, meta, model, mg, is_csim = False): #### is_csim else cosim filedir = os.path.dirname(os.path.abspath(__file__)) + sufix = "csim" if is_csim else "cosim" fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') - fout = open(f"{model.config.get_output_dir()}/hls_kernel_config.cfg", 'w') + fout = open(f"{model.config.get_output_dir()}/hls_kernel_config_{sufix}.cfg", 'w') for line in fin.readlines(): if "{PART}" in line: @@ -47,14 +48,17 @@ def write_hls_kernel_cfg(self, meta, model, mg): line = line.replace("{OUTDIR}", model.config.get_output_dir()) if "{TOP_NAME}" in line: line = line.replace("{TOP_NAME}", mg.get_top_wrap_func_name(model)) - if "{FILE_NAME_DM}" in line: - line = line.replace("{FILE_NAME_DM}", mg.get_wrapper_file_name(model)) - if "{FILE_NAME_AXIS}" in line: - line = line.replace("{FILE_NAME_AXIS}", mg.get_wrapper_file_name(model)) + if "{FILE_NAME_WRAP}" in line: + line = line.replace("{FILE_NAME_WRAP}", mg.get_wrapper_file_name(model)) + if "{SIM_FILE_NAME}" in line: + line = line.replace("{SIM_FILE_NAME}", mg.get_sim_file_name()) if "{FILE_NAME_BASE}" in line: line = line.replace("{FILE_NAME_BASE}", mg.get_main_file_name(model)) if "{OUTPUT_KERNEL_TYPE}" in line: line = line.replace("{OUTPUT_KERNEL_TYPE}", mg.get_output_kernel_type()) + if is_csim and ("-DRTL_SIM" in line): + line = "#" + line + fout.write(line) diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index d45893abde..f8cdd849b0 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -17,8 +17,8 @@ def get_wrapper_file_name(self, model): return f"{model.config.get_project_name()}_dm" @classmethod - def get_main_wrapper_file_name(self, model): - return model.config.get_project_name() + def get_sim_file_name(cls): #### false is cosim + return f"myproject_test" @classmethod def get_main_file_name(self, model): diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 47eb0363c2..16389283ea 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -14,7 +14,7 @@ def write_wrapper_test(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) - fout = open(f'{model.config.get_output_dir()}/{model.config.get_project_name()}_test.cpp', 'w') + fout = open(f'{model.config.get_output_dir()}/{mg.get_sim_file_name()}.cpp', 'w') model_inputs = model.get_input_variables() model_outputs = model.get_output_variables() @@ -28,6 +28,9 @@ def write_wrapper_test(self, meta, model, mg): #Insert numbers if 'myproject' in line: newline = line.replace('myproject', model.config.get_project_name()) + elif '// hls-fpga-machine-learning insert include' in line: + newline = line + f'#include "firmware/{mg.get_wrapper_file_name(model)}.h"\n' + elif '// hls-fpga-machine-learning insert bram' in line: newline = line for bram in model_brams: @@ -38,32 +41,34 @@ def write_wrapper_test(self, meta, model, mg): offset = 0 for inputIdx, inp in enumerate(model_inputs): ##### input should be float - newline += ' float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + newline += indent + 'float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template inputPortName=mg.get_io_port_name(inp, True, inputIdx), startIdx=str(offset) ) offset += inp.size() for outputIdx, out in enumerate(model_outputs): - newline += f" float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\n" + newline += indent + f"float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\n" elif '// hls-fpga-machine-learning insert top-level-function' in line: newline = line input_ios = [] + input_sizes = [] output_ios = [] + output_sizes = [] bram_ios = [b.name for b in model_brams] for inpIdx, inp in enumerate(model_inputs): input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) - input_ios.append(str(inp.size())) + input_sizes.append(str(inp.size())) for outIdx, out in enumerate(model_outputs): output_ios.append(mg.get_io_port_name(out, False, outIdx)) - output_ios.append(str(out.size())) + output_sizes.append(str(out.size())) # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [*input_ios, *output_ios, *bram_ios])) + all_vars = ','.join(filter(None, [*input_ios, *output_ios, *input_sizes, *output_sizes, *bram_ios])) top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' newline += top_level @@ -72,7 +77,7 @@ def write_wrapper_test(self, meta, model, mg): for outIdx, out in enumerate(model_outputs): #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' #### TODO fix this size retrieve - newline += indent + f'for(int i = 0; i < {out.size()}[{outIdx}]; i++) {{\n' + 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' @@ -98,10 +103,9 @@ def write_wrapper_test(self, meta, model, mg): for outIdx, out in enumerate(model_outputs): #### TODO fix this size retrieve - newline += (indent + 'nnet::print_result<{actualType}, {arrName}[{arrIdx}]>({portName}, {des}, {keepOutput});\n' + newline += (indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' .format( actualType = "float", - arrName = out.size(), - arrIdx = str(outIdx), + cpysize = out.size(), portName = mg.get_io_port_name(out, False, outIdx), des = dest, keepOutput = keep_output)) diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index 6889f0f83b..50e05ae9c6 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -53,7 +53,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): for line in fin.readlines(): if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_wrapper_file_name(model)) + line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_file_name(model)) if "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) elif "DMX_BUF_IN_SZ" in line: From 6a357cb4054f63a3d959bcf4230bc2cfcf2472d5 Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 27 Aug 2025 15:44:41 +0200 Subject: [PATCH 54/70] fix cosimulation bug from segment fault buffer size and invalid result from insufficient buffer size --- .../vitis_unified/vitis_unified_backend.py | 18 ++++----- .../vitis_unified/vitis_unified_config.py | 29 +++++---------- .../templates/vitis_unified/myproject_dm.cpp | 6 +-- hls4ml/templates/vitis_unified/myproject_dm.h | 2 + .../vitis_unified_writer/test_cosim_gen.py | 37 ++++++++++++------- .../writer/vitis_unified_writer/wrap_gen.py | 25 +++++++------ 6 files changed, 61 insertions(+), 56 deletions(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index b1bb73aae7..49ac14f68a 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -146,8 +146,8 @@ def create_initial_config( driver ='python', input_type ='float', output_type ='float', - gmemBuf_in_size =12, - gmemBuf_out_size =12, + in_stream_buf_size =128, + out_stream_buf_size =128, xpfmPath ='/tools/Xilinx/Vitis/2023.2/base_platforms/' 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', **_ @@ -156,13 +156,13 @@ def create_initial_config( config = super().create_initial_config(part, clock_period, clock_uncertainty, io_type) config['UnifiedConfig'] = {} - config['UnifiedConfig']['bufInSize' ] = gmemBuf_in_size - config['UnifiedConfig']['bufOutSize' ] = gmemBuf_out_size - config['UnifiedConfig']['XPFMPath' ] = xpfmPath - config['UnifiedConfig']['Board' ] = board - config['UnifiedConfig']['Driver' ] = driver - config['UnifiedConfig']['InputDtype' ] = input_type # float, double or ap_fixed - config['UnifiedConfig']['OutputDtype'] = output_type # float, double or ap_fixed + config['UnifiedConfig']["in_stream_buf_Size" ] = in_stream_buf_size + config['UnifiedConfig']["out_stream_buf_Size"] = out_stream_buf_size + config['UnifiedConfig']['XPFMPath' ] = xpfmPath + config['UnifiedConfig']['Board' ] = board + config['UnifiedConfig']['Driver' ] = driver + config['UnifiedConfig']['InputDtype' ] = input_type # float, double or ap_fixed + config['UnifiedConfig']['OutputDtype' ] = output_type # float, double or ap_fixed if io_type != "io_stream": raise Exception("io_type must be io_stream") diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index bf745e7027..a8046bb191 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -6,12 +6,15 @@ from hls4ml.model.layers import FixedPrecisionType, IntegerPrecisionType class VitisUnifiedConfig: + + def __init__(self, config, model_inputs, model_outputs): self.config = config.config self.board = self.config.get('UnifiedConfig', {}).get('Board', 'pynq-z2') - self.gmem_in_bufferSz = self.config["UnifiedConfig"]["bufInSize"] - self.gmem_out_bufferSz = self.config["UnifiedConfig"]["bufOutSize"] + self.in_steram_bufferSz = self.config["UnifiedConfig"]["in_stream_buf_Size" ] + self.out_stream_bufferSz = self.config["UnifiedConfig"]["out_stream_buf_Size"] + self.XPFMPath = self.config["UnifiedConfig"]["XPFMPath"] self.driver = self.config['UnifiedConfig']['Driver'] @@ -29,21 +32,7 @@ def __init__(self, config, model_inputs, model_outputs): ), "Only models with one output tensor are currently supported by VitisUnified" self.inps = model_inputs.copy() self.outs = model_outputs.copy() - inp_axi_t = self.input_type - out_axi_t = self.output_type - - if self.input_type == 'float': - self.input_bitwidth = 32 - else:# self.input_type == 'double': - self.input_bitwidth = 64 - - if out_axi_t == 'float': - self.output_bitwidth = 32 - else:# out_axi_t == 'double': - self.output_bitwidth = 64 - def get_io_bitwidth(self): - return self.input_bitwidth, self.output_bitwidth def get_corrected_types(self): return self.input_type, self.output_type, self.inps, self.outs @@ -60,11 +49,11 @@ def get_input_type(self): def get_output_type(self): return self.output_type - def get_gmem_in_bufferSz(self): - return self.gmem_in_bufferSz + def get_in_stream_bufferSz(self): + return self.in_steram_bufferSz - def get_gmem_out_bufferSz(self): - return self.gmem_out_bufferSz + def get_out_stream_bufferSz(self): + return self.out_stream_bufferSz def get_XPFMPath(self): return self.XPFMPath \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 286b9ae9a0..b1196ba755 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -2,10 +2,10 @@ #include #include //#include "ap_axi_sdata.h" -#include "MY_PROJECT_AXI_INC.h" +#include "MY_PROJECT_DM_INC.h" -#define DMX_BUF_IN_SZ VAL -#define DMX_BUF_OUT_SZ VAL +#define STREAM_BUF_IN_SZ VAL +#define STREAM_BUF_OUT_SZ VAL template diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h index 63acb7ac57..6233feff0b 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.h +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -3,6 +3,8 @@ #include +#include "MY_PROJECT_INC.h" + void MY_PROJECT_TOP_FUNC( diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 16389283ea..1a6d803d6f 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -89,26 +89,37 @@ def write_wrapper_test(self, meta, model, mg): for outIdx, out in enumerate(model_outputs): newline += indent + f"float {mg.get_io_port_name(out, False, outIdx)}[{str(out.size())}] = {{}};\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": ### it can be both or file + for outIdx, out in enumerate(model_outputs): + #### TODO fix this size retrieve + newline += ( + indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' + .format(actualType="float", + cpysize=out.size(), + portName=mg.get_io_port_name(out, False, outIdx), + des="fout", + keepOutput="false")) elif ( '// hls-fpga-machine-learning insert output' in line or '// hls-fpga-machine-learning insert quantized' in line - or '// hls-fpga-machine-learning insert tb-output' in line ): newline = line tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') - dest = 'fout' if ((tb_stream == 'file') or ('// hls-fpga-machine-learning insert tb-output' in line) ) else 'std::cout' - keep_output = "true" if ("// hls-fpga-machine-learning insert tb-output" in line) else "false" - newline += "/// warning keep is forced to be true\n" - - for outIdx, out in enumerate(model_outputs): - #### TODO fix this size retrieve - newline += (indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' - .format( actualType = "float", - cpysize = out.size(), - portName = mg.get_io_port_name(out, False, outIdx), - des = dest, - keepOutput = keep_output)) + keep_output = str(tb_stream != "stdout").lower() + + if tb_stream != "file": + for outIdx, out in enumerate(model_outputs): + #### TODO fix this size retrieve + newline += (indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' + .format( actualType = "float", + cpysize = out.size(), + portName = mg.get_io_port_name(out, False, outIdx), + des = "std::cout", + keepOutput = keep_output)) elif '// hls-fpga-machine-learning insert namespace' in line: newline = '' diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index 50e05ae9c6..3fa53f19f1 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -52,22 +52,23 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): for line in fin.readlines(): - if "MY_PROJECT_AXI_INC" in line: - line = line.replace("MY_PROJECT_AXI_INC", mg.get_main_file_name(model)) - if "MY_PROJECT_TOP_FUNC" in line: + if "MY_PROJECT_DM_INC" in line: + line = line.replace("MY_PROJECT_DM_INC", mg.get_wrapper_file_name(model)) + elif "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) - elif "DMX_BUF_IN_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_in_bufferSz())) - elif "DMX_BUF_OUT_SZ" in line: - line = line.replace("VAL", str(meta.vitis_unified_config.get_gmem_out_bufferSz())) + elif "STREAM_BUF_IN_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_in_stream_bufferSz())) + elif "STREAM_BUF_OUT_SZ" in line: + line = line.replace("VAL", str(meta.vitis_unified_config.get_out_stream_bufferSz())) + elif "// vitis-unified-wrapper-io" in line: line = self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: for inp_idx, inp in enumerate(inps): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx}\n" + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx} depth={str(inp.size())}\n" line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(inp, True, inp_idx)} bundle = control\n" for out_idx, out in enumerate(outs): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx}\n" + line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx} depth={str(out.size())}\n" line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(out, False, out_idx)} bundle = control\n" elif "// vitis-unified-wrapper-stream-dec" in line: @@ -78,9 +79,9 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): elif "// vitis-unified-wrapper-stream-config" in line: for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth=DMX_BUF_IN_SZ\n" + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth=STREAM_BUF_IN_SZ\n" for out_idx, out in enumerate(outs): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth=DMX_BUF_OUT_SZ\n" + line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth=STREAM_BUF_OUT_SZ\n" elif "// vitis-unified-wrapper-load" in line: for inp_idx, inp in enumerate(inps): @@ -116,6 +117,8 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): if "FILENAME" in line: line = line.replace("FILENAME", mg.get_wrapper_file_name(model).upper()) + elif "MY_PROJECT_INC.h" in line: + line = line.replace("MY_PROJECT_INC", mg.get_main_file_name(model)) elif "MY_PROJECT_TOP_FUNC" in line: line = line.replace("MY_PROJECT_TOP_FUNC", mg.get_top_wrap_func_name(model)) elif "// vitis-unified-wrapper-io" in line: From 5e87503ecffe26fdaa96fece200b3232b4ce0b95 Mon Sep 17 00:00:00 2001 From: tanawin Date: Wed, 27 Aug 2025 16:06:05 +0200 Subject: [PATCH 55/70] add fifo-flag in hls compile kernel --- hls4ml/templates/vitis_unified/hls_kernel_config.cfg | 3 ++- hls4ml/writer/vitis_unified_writer/build_gen.py | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg index 7f26ce764a..f888096df1 100644 --- a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -20,4 +20,5 @@ 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 \ No newline at end of file +package.output.syn=1 +cosim.enable_fifo_sizing=true \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 27c6d68164..aa6da0ddfe 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -56,10 +56,8 @@ def write_hls_kernel_cfg(self, meta, model, mg, is_csim = False): #### is_csim e line = line.replace("{FILE_NAME_BASE}", mg.get_main_file_name(model)) if "{OUTPUT_KERNEL_TYPE}" in line: line = line.replace("{OUTPUT_KERNEL_TYPE}", mg.get_output_kernel_type()) - if is_csim and ("-DRTL_SIM" in line): - line = "#" + line - - + if is_csim and ( ( "enable_fifo_sizing" in line ) or ("-DRTL_SIM" in line)): + line = "#" + line fout.write(line) From 0525079abdc4d4256a126bf3e59fd42541188230 Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 28 Aug 2025 07:54:49 +0200 Subject: [PATCH 56/70] push fifo --- .../passes/fifo_depth_optimization.py | 125 ++++++++++++++++++ .../vitis_unified/vitis_unified_backend.py | 30 +++-- 2 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py 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..12968774d7 --- /dev/null +++ b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py @@ -0,0 +1,125 @@ + +###### we inherit it from vitis +import json +import zipfile +from hls4ml.model.optimizer.optimizer import ConfigurableOptimizerPass, ModelOptimizerPass +from hls4ml.backends.vitis.passes.fifo_depth_optimization import (initialize_large_fifos, \ + generate_depths_file, \ + set_optimized_fifo_depths) + + + +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 _ in range(4): + next(names_file) + for line in names_file: + layer_name = line.split(',')[1] + csv_file_name = line.split(',')[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() + optmized_fifo_depths[layer_name[:-4]] = int( + lines[-1] + ) # remove "_i_U" 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, + validation = False, + export = False, + vsynth = False, + fifo_opt = True, + bitfile = False, + log_to_stdout = True + ) + +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.mg.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 \ No newline at end of file diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 49ac14f68a..6cc89615df 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -61,16 +61,16 @@ def run_term_command(self, model, taskName: str, command: str, logStdOut: bool, def build( self, model, - reset=False, - csim=False, - synth=False, - cosim=False, - validation=False, - export=False, - vsynth=False, - fifo_opt=False, - bitfile=False, - log_to_stdout=True + reset = False, + csim = False, + synth = False, + cosim = False, + validation = False, + export = False, + vsynth = False, + fifo_opt = False, + bitfile = False, + log_to_stdout = True ): ##### it builds and return vivado reports if 'linux' in sys.platform: @@ -85,8 +85,6 @@ def build( raise Exception("Current Vitis Unified not support validation. Please set validation=False to run Vitis Unified.") if export: raise Exception("Current Vitis Unified not support export. Please set export=False to run Vitis Unified.") - if fifo_opt: - raise Exception("Current Vitis Unified not support fifo_opt. Please set fifo_opt=False to run Vitis Unified.") output_dir = model.config.get_output_dir() @@ -120,7 +118,7 @@ def build( self.prepare_sim_config_file(model, True) self.run_term_command(model, "csim", csim_cmd, log_to_stdout, csim_cwd) - if cosim: + if cosim or fifo_opt: self.prepare_sim_config_file(model, False) self.run_term_command(model, "cosim", cosim_cmd, log_to_stdout, cosim_cwd) @@ -185,3 +183,9 @@ def _register_flows(self): 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) + + From 671c1aef656e333b4f1f5046ab62110a0d043344 Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 28 Aug 2025 14:42:34 +0200 Subject: [PATCH 57/70] upgrade new wrapper --- .../templates/vitis_unified/myproject_dm.cpp | 27 +++++++++++++------ hls4ml/templates/vitis_unified/myproject_dm.h | 3 +-- .../writer/vitis_unified_writer/wrap_gen.py | 20 +++++--------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index b1196ba755..28154e5807 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -9,38 +9,44 @@ template -void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int size) { +void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int amtQuery) { mem_rd: - - for (int i = 0; i < size; i = i + INPUT_LAYER_ARR::size) { + int baseQuery = 0; + for (int i = 0; i < amtQuery; i++) { #pragma HLS PIPELINE II=1 INPUT_LAYER_ARR tmp; for (int j = 0; j < INPUT_LAYER_ARR::size; j++){ - tmp[j] = in[i+j]; + tmp[j] = in[baseQuery]; + baseQuery++; } inStream.write(tmp); } } template -void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int size) { +void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int amtQuery) { mem_wr: - for (int i = 0; i < size; i = i + OUT_LAYER_ARR::size){ + int baseQuery = 0; + for (int i = 0; i < amtQuery; i++){ #pragma HLS PIPELINE II=1 OUT_LAYER_ARR tmp = out_stream.read(); for (int j = 0; j < OUT_LAYER_ARR::size; j++){ - out[i+j] = tmp[j]; + out[baseQuery] = tmp[j]; + baseQuery++; } + } } void MY_PROJECT_TOP_FUNC( // vitis-unified-wrapper-io + ,int amtQuery ){ // vitis-unified-wrapper-interface +#pragma HLS INTERFACE s_axilite port=amtQuery bundle=control #pragma HLS INTERFACE s_axilite port=return bundle=control @@ -54,9 +60,14 @@ void MY_PROJECT_TOP_FUNC( // vitis-unified-wrapper-load + + for (int q = 0; q < amtQuery; q++){ // vitis-unified-wrapper-compute -// // vitis-unified-wrapper-store + } + + +// vitis-unified-wrapper-store } \ No newline at end of file diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h index 6233feff0b..01abce32d9 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.h +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -9,8 +9,7 @@ void MY_PROJECT_TOP_FUNC( // vitis-unified-wrapper-io - - + ,int amtQuery ); #endif \ No newline at end of file diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index 3fa53f19f1..e9e6e98818 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -17,22 +17,16 @@ def gen_io_str(self, mg, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): inputPtrList = [] outputPtrList = [] - inputSizeList = [] - outputSizeList = [] for inp_idx, inp in enumerate(inps): inputPtrList.append(f"{indent} {inp_gmem_t}* {mg.get_io_port_name(inp, True, inp_idx)}") - inputSizeList.append(f"{indent} int {mg.get_io_port_size_name(inp, True, inp_idx)}") for out_idx, out in enumerate(outs): outputPtrList.append(f"{indent} {out_gmem_t}* {mg.get_io_port_name(out, False, out_idx)}") - outputSizeList.append(f"{indent} int {mg.get_io_port_size_name(out, False, out_idx)}") line = ", ".join(inputPtrList) + ",\n" - line += ", ".join(outputPtrList) + ",\n" - line += ", ".join(inputSizeList) + ",\n" - line += ", ".join(outputSizeList) + line += ", ".join(outputPtrList) + "\n" return line @@ -65,11 +59,9 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): line = self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: for inp_idx, inp in enumerate(inps): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx} depth={str(inp.size())}\n" - line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(inp, True, inp_idx)} bundle = control\n" + line += f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx} depth={str(inp.size())}\n" for out_idx, out in enumerate(outs): - line += f"{indent} #pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx} depth={str(out.size())}\n" - line += f"{indent} #pragma HLS INTERFACE s_axilite port={mg.get_io_port_size_name(out, False, out_idx)} bundle = control\n" + line += f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx} depth={str(out.size())}\n" elif "// vitis-unified-wrapper-stream-dec" in line: for inp_idx, inp in enumerate(inps): @@ -85,19 +77,19 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): elif "// vitis-unified-wrapper-load" in line: for inp_idx, inp in enumerate(inps): - line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, {mg.get_io_port_size_name(inp, True, inp_idx)});\n" + line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery);\n" elif "// vitis-unified-wrapper-compute" in line: poolList = [] for inp_idx, inp in enumerate(inps): poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") for out_idx, out in enumerate(outs): poolList.append(f"{mg.get_local_stream_name(out, False, out_idx)}") - joinedIo = ", \n".join(poolList) + joinedIo = f",\n{indent}{indent}{indent}".join(poolList) line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" elif "// vitis-unified-wrapper-store" in line: for out_idx, out in enumerate(outs): - line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, {mg.get_io_port_size_name(out, False, out_idx)});\n" + line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, amtQuery);\n" fout.write(line) From f5189b95963d0fcee823a4ecf9b37bd930021538 Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 28 Aug 2025 14:51:06 +0200 Subject: [PATCH 58/70] upgrade the parameter of cosim and bridge sim --- hls4ml/writer/vitis_unified_writer/test_bridge_gen.py | 6 +----- hls4ml/writer/vitis_unified_writer/test_cosim_gen.py | 8 +------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index fdf3667a30..bf914411b3 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -69,17 +69,13 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): otuput_sizes.append(out.size_cpp()) inputs_str = ', '.join(input_vars) - input_size_str = ', '.join(input_sizes) outputs_str = ', '.join(output_vars) - output_size_str = ', '.join(otuput_sizes) newline = '' newline += indent + mg.get_top_wrap_func_name(model) + "(\n" newline += indent + inputs_str + ',\n' newline += indent + outputs_str + ',\n' - newline += indent + input_size_str + ',\n' - newline += indent + output_size_str + '\n' - newline += indent + ");\n" + newline += indent + "1);\n" ##### amount query should be one only elif '// hls-fpga-machine-learning insert trace_outputs' in line: diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 1a6d803d6f..71d3a6ba53 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -54,21 +54,17 @@ def write_wrapper_test(self, meta, model, mg): newline = line input_ios = [] - input_sizes = [] output_ios = [] - output_sizes = [] bram_ios = [b.name for b in model_brams] for inpIdx, inp in enumerate(model_inputs): input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) - input_sizes.append(str(inp.size())) for outIdx, out in enumerate(model_outputs): output_ios.append(mg.get_io_port_name(out, False, outIdx)) - output_sizes.append(str(out.size())) # Concatenate the input, output, and bram variables. Filter out empty/null values - all_vars = ','.join(filter(None, [*input_ios, *output_ios, *input_sizes, *output_sizes, *bram_ios])) + all_vars = ' ,'.join(filter(None, [*input_ios, *output_ios, *bram_ios, "1"])) top_level = indent + f'{mg.get_top_wrap_func_name(model)}({all_vars});\n' newline += top_level @@ -94,7 +90,6 @@ def write_wrapper_test(self, meta, model, mg): tb_stream = model.config.get_writer_config().get('TBOutputStream', 'both') if tb_stream != "stdout": ### it can be both or file for outIdx, out in enumerate(model_outputs): - #### TODO fix this size retrieve newline += ( indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' .format(actualType="float", @@ -113,7 +108,6 @@ def write_wrapper_test(self, meta, model, mg): if tb_stream != "file": for outIdx, out in enumerate(model_outputs): - #### TODO fix this size retrieve newline += (indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' .format( actualType = "float", cpysize = out.size(), From 2d83c57056517f50907e27209464ccb4ec5be475 Mon Sep 17 00:00:00 2001 From: tanawin Date: Thu, 28 Aug 2025 17:31:36 +0200 Subject: [PATCH 59/70] fix missing wrap problem --- .../vitis_unified/driver/pynq/pynq_driver.py | 8 +---- .../templates/vitis_unified/myproject_dm.cpp | 35 ++++++++++--------- .../writer/vitis_unified_writer/driver_gen.py | 11 ++---- .../writer/vitis_unified_writer/wrap_gen.py | 4 +-- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py index 980883ab7b..227ba53563 100644 --- a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py +++ b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py @@ -14,6 +14,7 @@ def __init__(self, description): super().__init__(description=description) self.REG_ADDR_AP_CTRL = 0x00 + self.REG_ADDR_AMT_QUERY = VAL self.INP_PORT_NAMEs = [ #### hls-driver-input-dbg-name @@ -22,9 +23,6 @@ def __init__(self, description): self.REG_ADDR_INP_PTRs = [ #### hls-driver-input-ptr ] - self.REG_ADDR_INP_SZs = [ - #### hls-driver-input-size - ] self.OUT_PORT_NAMEs = [ #### hls-driver-output-dbg-name @@ -34,10 +32,6 @@ def __init__(self, description): #### hls-driver-output-ptr ] - self.REG_ADDR_OUT_SZs = [ - #### hls-driver-output-size - ] - bindto = ['xilinx.com:hls::1.0'] ######## TODO interrupt diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 28154e5807..0043487b93 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -9,32 +9,33 @@ template -void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int amtQuery) { +void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int amtQuery, const int TENSOR_SIZE) { mem_rd: int baseQuery = 0; - for (int i = 0; i < amtQuery; i++) { -#pragma HLS PIPELINE II=1 - INPUT_LAYER_ARR tmp; - for (int j = 0; j < INPUT_LAYER_ARR::size; j++){ - tmp[j] = in[baseQuery]; - baseQuery++; - } - inStream.write(tmp); + for (int q = 0; q < amtQuery; 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 amtQuery) { +void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int amtQuery, const int TENSOR_SIZE) { mem_wr: int baseQuery = 0; - for (int i = 0; i < amtQuery; i++){ -#pragma HLS PIPELINE II=1 - OUT_LAYER_ARR tmp = out_stream.read(); - for (int j = 0; j < OUT_LAYER_ARR::size; j++){ - out[baseQuery] = tmp[j]; - baseQuery++; + for (int q = 0; q < amtQuery; 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++; + } } - } } diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py index 2f4ad4db06..0039af3cd3 100644 --- a/hls4ml/writer/vitis_unified_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -17,13 +17,10 @@ def write_driver(self, meta, model, mg): strideInPtrAddr = 4*3 strideOutPtrAddr = 4*3 - strideInSizeAddr = 4*2 - strideOutSizeAddr = 4*2 startInPtrAddr = 0x10 startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) - startInSizeAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) - startOutSizeAddr = startInSizeAddr + strideInSizeAddr * len(inps) + startAmtQueryAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) def genHexAddrList(startAddr, stride, size, indent): addrs = [f"{indent}{hex(startAddr + inp_idx * stride)}" for inp_idx in range(size)] @@ -34,20 +31,18 @@ def genHexAddrList(startAddr, stride, size, indent): for line in fin.readlines(): + if "REG_ADDR_AMT_QUERY" in line: + line = line.replace("VAL", str(hex(startAmtQueryAddr))) if "#### hls-driver-input-dbg-name" in line: input_names = [ f'{indentStr}"{mg.get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inps) ] line += ",\n".join(input_names) + "\n" if "#### hls-driver-input-ptr" in line: line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" - if "#### hls-driver-input-size" in line: - line += ",\n".join(genHexAddrList(startInSizeAddr, strideInSizeAddr, len(inps), indentStr)) + "\n" if "#### hls-driver-output-dbg-name" in line: output_names = [ f'{indentStr}"{mg.get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outs) ] line += ",\n".join(output_names) + "\n" if "#### hls-driver-output-ptr" in line: line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" - if "#### hls-driver-output-size" in line: - line += ",\n".join(genHexAddrList(startOutSizeAddr, strideOutSizeAddr, len(outs), indentStr)) + "\n" if "" in line: line = line.replace("", mg.get_top_wrap_func_name(model)) diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index e9e6e98818..f918f395b0 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -77,7 +77,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): elif "// vitis-unified-wrapper-load" in line: for inp_idx, inp in enumerate(inps): - line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery);\n" + line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery, {str(inp.size())});\n" elif "// vitis-unified-wrapper-compute" in line: poolList = [] for inp_idx, inp in enumerate(inps): @@ -89,7 +89,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): elif "// vitis-unified-wrapper-store" in line: for out_idx, out in enumerate(outs): - line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, amtQuery);\n" + line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, amtQuery, {str(out.size())});\n" fout.write(line) From fbf1deee870dc588d779e41be41599f6e05e28aa Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 08:57:55 +0200 Subject: [PATCH 60/70] fix missing wrap problem --- .gitignore | 4 +- test/pytest/test_backend/cmpResult.py | 31 +++ test/pytest/test_backend/vitis_unified.py | 225 ++++++++++++++++++++++ 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 test/pytest/test_backend/cmpResult.py create mode 100644 test/pytest/test_backend/vitis_unified.py diff --git a/.gitignore b/.gitignore index 1f93c68d5d..7ee704bea8 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ hls4mlprj_* *.ipynb_checkpoints/ .idea/* -myTest/* \ No newline at end of file +myTest/* +test/pytest/test_backend/input_file/* +test/pytest/test_backend/output_file/* \ No newline at end of file diff --git a/test/pytest/test_backend/cmpResult.py b/test/pytest/test_backend/cmpResult.py new file mode 100644 index 0000000000..0da81286ea --- /dev/null +++ b/test/pytest/test_backend/cmpResult.py @@ -0,0 +1,31 @@ +import os +from pathlib import Path + +import numpy as np +from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, Concatenate +from tensorflow.keras.models import Model, load_model + +import hls4ml +import hls4ml.model + +test_root_path = Path(__file__).parent +os.environ['XILINX_VITIS'] = "/tools/Xilinx/Vitis/2023.2" +os.environ['PATH'] = os.environ['XILINX_VITIS'] + '/bin:' + os.environ['PATH'] + +def checkEqual(a, b): + equal = np.array_equal(a, b) + if equal: + print("Test pass both are equal \U0001F642") + else: + print("Test Fail both are not equal \U0001F62C") + + + +bridge_result = np.load(test_root_path / "output_file/outputGenbit.npy") +zcu_result = np.load(test_root_path / "output_file/zcu102_mandriver.npy") +zcu_flat = zcu_result.reshape(zcu_result.shape[0], -1) + +print(bridge_result.shape) +print(zcu_result.shape) + +checkEqual(bridge_result, zcu_flat) diff --git a/test/pytest/test_backend/vitis_unified.py b/test/pytest/test_backend/vitis_unified.py new file mode 100644 index 0000000000..479f4d2920 --- /dev/null +++ b/test/pytest/test_backend/vitis_unified.py @@ -0,0 +1,225 @@ +from pathlib import Path + +import numpy as np +import pytest +import os +from tensorflow.keras.layers import Activation, Dense, GlobalAveragePooling1D, Input +from tensorflow.keras.models import Model + +import hls4ml +import hls4ml.model + +from tensorflow.keras.layers import Activation, Dense, GlobalAveragePooling1D, Input, Conv2D, MaxPooling2D, UpSampling2D, Concatenate +from tensorflow.keras.models import Model, load_model + +test_root_path = Path(__file__).parent + +os.environ['XILINX_VITIS'] = "/tools/Xilinx/Vitis/2023.2" +os.environ['PATH'] = os.environ['XILINX_VITIS'] + '/bin:' + os.environ['PATH'] + + +def create_io_file_dir(): + os.makedirs(test_root_path / "input_file" , exist_ok=True) + os.makedirs(test_root_path / "output_file", exist_ok=True) + + +def checkEqual(a, b): + + equal = np.array_equal(a, b) + if equal: + print("Test pass both are equal \U0001F642") + else: + print("Test Fail both are not equal \U0001F62C") + return equal + + +def create_simple_testcase(inputShape=(4, 4, 1), fileName = "inputX.npy"): + n_in = np.random.rand(*inputShape).astype(np.float32) + os.makedirs(test_root_path/ "input_file", exist_ok=True) + np.save(test_root_path/ "input_file" / fileName, n_in) + +def create_simple_unet(input_shape=(4, 4, 1), modelName = "simpleSkip.keras"): + inputs = Input(input_shape) + # Encoder + c1 = Conv2D(2, (3, 3), activation='relu', padding='same')(inputs) + p1 = MaxPooling2D((2, 2))(c1) + # Bottleneck + bn = Conv2D(4, (3, 3), activation='relu', padding='same')(p1) + # Decoder + u1 = UpSampling2D((2, 2))(bn) + concat1 = Concatenate()([u1, c1]) + c2 = Conv2D(2, (3, 3), activation='relu', padding='same')(concat1) + # Output layer (1 channel) + outputs = Conv2D(1, (1, 1), activation='sigmoid')(c2) + model = Model(inputs, outputs) + model.compile(optimizer='adam', loss='binary_crossentropy') + model.save(test_root_path/ "input_file" / modelName) + + +def gen_prj_dir(backend, io_type, strategy, granularity, prefix): + return str( + test_root_path + / f"hls4mlprj_{prefix}_{backend}_{strategy}_{io_type}_{granularity}" + ) + + +def create_hls_model(model, config, backend, io_type, strategy, granularity, prefix): + output_dir = gen_prj_dir(backend, io_type, strategy, granularity, prefix) + ############### mono model build + hls_model = hls4ml.converters.convert_from_keras_model( + model, hls_config=config, output_dir=output_dir, backend=backend, io_type=io_type, + board='zcu102', part='xczu9eg-ffvb1156-2-e', clock_period='10ns', + input_type="float", output_type="float" + ) + hls_model.compile() + return hls_model + +def create_hls_model4_cosim(model, config, backend, io_type, strategy, granularity, input_data_tb, output_data_tb, prefix): + output_dir = gen_prj_dir(backend, io_type, strategy, granularity, prefix) + ############### mono model build + hls_model = hls4ml.converters.convert_from_keras_model( + model, hls_config=config, output_dir=output_dir, backend=backend, io_type=io_type, + board='zcu102', part='xczu9eg-ffvb1156-2-e', clock_period='10ns', + input_type="float", output_type="float", + input_data_tb = input_data_tb, output_data_tb = output_data_tb + ) + hls_model.compile() + return hls_model + +def predict_hls_model(hls_model, input_data): + y_hls4ml = hls_model.predict(input_data) + return y_hls4ml + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('amt_query', [10]) +def test_backend_predict(io_type, strategy, granularity, amt_query): + create_io_file_dir() + #### create and load data set + create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName = "inputX.npy") + input_data = np.load(test_root_path/ "input_file" / "inputX.npy") + #### create and load model + model_name = "simpleSkip.keras" + create_simple_unet(modelName = model_name) + model = load_model(test_root_path/ "input_file" / model_name) + #### config the keras model + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + + #### create hls4ml model + vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "bridge") + vitis_model = create_hls_model(model, config, "Vitis", io_type, strategy, granularity, "bridge") + + #### predict test + + y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) + y_hls4ml = predict_hls_model(vitis_model, input_data) + + assert checkEqual(y_hls4ml_unified, y_hls4ml), "the result from vitis unified and vitis are not equal!" + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('amt_query', [10]) +def test_co_simulation(io_type, strategy, granularity, amt_query): + create_io_file_dir() + #### create and load data set + create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputCosim.npy") + input_data = np.load(test_root_path / "input_file" / "inputCosim.npy") + #### create and load model + model_name = "simpleSkipCosim.keras" + create_simple_unet(modelName=model_name) + model = load_model(test_root_path / "input_file" / model_name) + #### config the keras model + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + + #### predict it first + vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "precosim") + y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) + np.save(test_root_path/ "output_file" / "outputCosim.npy", y_hls4ml_unified) + + input_data_tb = str(test_root_path / "input_file" / f"inputCosim.npy") + output_data_tb = str(test_root_path / "output_file" / f"outputCosim.npy") + + #### create hls4ml model + vitis_unified_model_cosim = create_hls_model4_cosim(model, config, "VitisUnified", io_type, + strategy, granularity,input_data_tb, output_data_tb, "cosim") + #### do cosim + vitis_unified_model_cosim.compile() + vitis_unified_model_cosim.build(synth=True, cosim=True) + + bridge_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/tb_output_predictions.dat" + cosim_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/rtl_cosim_results.log" + + bridge_result = np.loadtxt(bridge_result_path) + cosim_result = np.loadtxt(cosim_result_path) + + assert np.allclose(bridge_result, cosim_result, rtol=0.0, atol=1e-4), "the result from bridge and cosim are not equal!" + +#test_co_simulation("io_stream", 'latency', 'name', 10) + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('amt_query', [10]) +def test_fifo_depth(io_type, strategy, granularity, amt_query): + create_io_file_dir() + #### create and load data set + create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputFifoDepth.npy") + input_data = np.load(test_root_path / "input_file" / "inputFifoDepth.npy") + #### create and load model + model_name = "simpleSkipFifoDepth.keras" + create_simple_unet(modelName=model_name) + model = load_model(test_root_path / "input_file" / model_name) + #### config the keras model + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + + #### predict it first + vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "fifodepth") + y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) + np.save(test_root_path/ "output_file" / "outputFifoDepth.npy", y_hls4ml_unified) + + input_data_tb = str(test_root_path / "input_file" / f"inputFifoDepth.npy") + output_data_tb = str(test_root_path / "output_file" / f"outputFifoDepth.npy") + + #### create hls4ml model + config['Flows'] = ['vitisunified:fifo_depth_optimization'] + vitis_unified_model_fifo = create_hls_model4_cosim(model, config, "VitisUnified", io_type, + strategy, granularity,input_data_tb, output_data_tb, "fifodepth") + #### do cosim + vitis_unified_model_fifo.compile() + + fifodepth_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "fifodepth") + "/fifo_depths.json" + assert os.path.exists(fifodepth_result_path), "the fifo_depth file is not exist" + + + +#test_fifo_depth("io_stream", 'latency', 'name', 10) + + +@pytest.mark.parametrize('io_type', ['io_stream']) +@pytest.mark.parametrize('strategy', ['latency']) +@pytest.mark.parametrize('granularity', ['name']) +@pytest.mark.parametrize('amt_query', [10000]) +def test_gen_unified(io_type, strategy, granularity, amt_query): + create_io_file_dir() + #### create and load data set + create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputGenbit.npy") + input_data = np.load(test_root_path / "input_file" / "inputGenbit.npy") + #### create and load model + model_name = "simpleSkipGenBit.keras" + create_simple_unet(modelName=model_name) + model = load_model(test_root_path / "input_file" / model_name) + #### config the keras model + config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) + + #### predict it first + vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "gen_unified") + y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) + np.save(test_root_path/ "output_file" / "outputGenbit.npy", y_hls4ml_unified) + + vitis_unified_model.compile() + vitis_unified_model.build(synth=True, bitfile=True) + +#test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file From 1ece84edbfb0a0d578b9fb8bc5b8b4797525fc1a Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 14:43:21 +0200 Subject: [PATCH 61/70] update the driver and testing --- .../vitis_unified/driver/pynq/pynq_driver.py | 54 ++- test/pytest/test_backend/cmpResult.py | 2 +- test/pytest/test_backend/pynq_example.ipynb | 372 ++++++++++++++++++ test/pytest/test_backend/vitis_unified.py | 5 +- 4 files changed, 418 insertions(+), 15 deletions(-) create mode 100644 test/pytest/test_backend/pynq_example.ipynb diff --git a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py index 227ba53563..a279de9f72 100644 --- a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py +++ b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py @@ -15,6 +15,13 @@ def __init__(self, description): self.REG_ADDR_AP_CTRL = 0x00 self.REG_ADDR_AMT_QUERY = 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 @@ -34,30 +41,57 @@ def __init__(self, description): bindto = ['xilinx.com:hls::1.0'] - ######## TODO interrupt + 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 setSingleBit(self, addr, idx): + def clear_done_status(self): + print("ap_done register clear") + self.write(self.REG_ADDR_ISR, 0x01) + print("clear ap_done interrupt successful") + + def prepare_intr(self): + print("prepare your interrupt") + self.enable_gie() + self.enable_done_intr() + self.clear_done_status() + print("----------------------") + + + def set_single_bit(self, addr, idx): self.write(addr, 1 << idx) - def ctrlStart(self): + def ctrl_start(self): self.write(0x00, 0x01) # ap_start = 1 - def waitUntilDone(self): + def wait_until_done(self): while (self.read(0x00) & 0x2) == 0: # Wait for ap_done time.sleep(0.001) - def setInput(self, idx, buffer): + def set_input(self, idx, buffer): - print(f"input {self.INP_PORT_NAMEs[idx]} will be set to addr: {buffer.physical_address} with elements: {buffer.size}") + 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) - self.write(self.REG_ADDR_INP_SZs[idx], buffer.size) buffer.flush() - def setOutput(self, idx, buffer): + def set_output(self, idx, buffer): - print(f"input {self.OUT_PORT_NAMEs[idx]} will be set to addr: {buffer.physical_address} with elements: {buffer.size}") + 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) - self.write(self.REG_ADDR_OUT_SZs[idx], buffer.size) \ No newline at end of file + + def set_amt_query(self, val): + print(f"amount of queries will be set to: {val} at address: {hex(self.REG_ADDR_AMT_QUERY)}") + self.write(self.REG_ADDR_AMT_QUERY, val) \ No newline at end of file diff --git a/test/pytest/test_backend/cmpResult.py b/test/pytest/test_backend/cmpResult.py index 0da81286ea..d5561962d9 100644 --- a/test/pytest/test_backend/cmpResult.py +++ b/test/pytest/test_backend/cmpResult.py @@ -22,7 +22,7 @@ def checkEqual(a, b): bridge_result = np.load(test_root_path / "output_file/outputGenbit.npy") -zcu_result = np.load(test_root_path / "output_file/zcu102_mandriver.npy") +zcu_result = np.load(test_root_path / "output_file/out_hw.npy") zcu_flat = zcu_result.reshape(zcu_result.shape[0], -1) print(bridge_result.shape) diff --git a/test/pytest/test_backend/pynq_example.ipynb b/test/pytest/test_backend/pynq_example.ipynb new file mode 100644 index 0000000000..987f3ed962 --- /dev/null +++ b/test/pytest/test_backend/pynq_example.ipynb @@ -0,0 +1,372 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "a0e69eaf", + "metadata": {}, + "outputs": [], + "source": [ + "# import the library\n", + "from pynq import Overlay # import the overlay\n", + "from pynq import allocate # import for CMA (contingeous memory allocation)\n", + "from pynq import DefaultIP # import the ip connector library for extension\n", + "from pynq import Interrupt\n", + "import pynq_driver\n", + "import asyncio\n", + "import numpy as np\n", + "import os\n", + "import subprocess\n", + "import re\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89082d04", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": "\ntry {\nrequire(['notebook/js/codecell'], function(codecell) {\n codecell.CodeCell.options_default.highlight_modes[\n 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n Jupyter.notebook.get_cells().map(function(cell){\n if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n });\n});\n} catch (e) {};\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "\ntry {\nrequire(['notebook/js/codecell'], function(codecell) {\n codecell.CodeCell.options_default.highlight_modes[\n 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n Jupyter.notebook.get_cells().map(function(cell){\n if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n });\n});\n} catch (e) {};\n" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "overlay = Overlay(\"system.bit\")\n", + "help(overlay)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b19361e3", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "overlay.interrupt_pins" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e5b0e03", + "metadata": {}, + "outputs": [], + "source": [ + "# create an instance of the interrupt\n", + "my_interrupt = Interrupt()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9459e8ae", + "metadata": {}, + "outputs": [], + "source": [ + "# Load input from .npy file\n", + "input_array = np.load(\"inputGenbit.npy\").astype(np.float32) # shape (20,4,4,1)\n", + "output_array = np.zeros(input_array.shape, dtype=np.float32)\n", + "\n", + "# Allocate physically contiguous memory for input and output\n", + "input_buffer = allocate(shape=input_array.shape, dtype=np.float32)\n", + "output_buffer = allocate(shape=output_array.shape, dtype=np.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "625c2b1f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "input array shape (10000, 4, 4, 1)\n", + "output array shape (10000, 4, 4, 1)\n" + ] + } + ], + "source": [ + "# check input shape\n", + "print(f\"input array shape {input_array.shape}\")\n", + "print(f\"output array shape {output_array.shape}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7de66a89", + "metadata": {}, + "outputs": [], + "source": [ + "# copy data to input buffer\n", + "np.copyto(input_buffer, input_array)\n", + "input_buffer.flush()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d18bac75", + "metadata": {}, + "outputs": [], + "source": [ + "# get the ip and initialize the system\n", + "ip = overlay.myproject_gem_1 # Replace with your IP instance name\n", + "ip.set_input (0, input_buffer)\n", + "ip.set_output(0, output_buffer)\n", + "ip.set_amt_query(input_array.shape[0])\n", + "ip.prepare_intr()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d12a031a", + "metadata": {}, + "outputs": [], + "source": [ + "async def wait_for_acc():\n", + " print(\"starting the accelerator\")\n", + " ip.ctrl_start()\n", + " print(\"waiting for the accelerator to finish\")\n", + " await my_interrupt.wait()\n", + " print(\"accelerator has finished\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81750e60", + "metadata": {}, + "outputs": [], + "source": [ + "#### get event loop from asyncio\n", + "loop = asyncio.get_event_loop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe5f7eb2", + "metadata": {}, + "outputs": [], + "source": [ + "task = loop.create_task(wait_for_acc())\n", + "loop.run_until_complete(task)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "372b1982", + "metadata": {}, + "outputs": [], + "source": [ + "output_buffer.invalidate()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "6a7834c2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.49609375]\n", + " [0.49609375]\n", + " [0.49609375]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5029297 ]]]\n", + "\n", + "\n", + " [[[0.5 ]\n", + " [0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.49609375]\n", + " [0.49609375]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]]\n", + "\n", + "\n", + " [[[0.5 ]\n", + " [0.48828125]\n", + " [0.49609375]\n", + " [0.49609375]]\n", + "\n", + " [[0.5 ]\n", + " [0.48828125]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.49609375]\n", + " [0.49609375]\n", + " [0.49609375]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]]\n", + "\n", + "\n", + " ...\n", + "\n", + "\n", + " [[[0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]\n", + " [0.5029297 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]\n", + " [0.5029297 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]]\n", + "\n", + "\n", + " [[[0.5 ]\n", + " [0.4921875 ]\n", + " [0.49609375]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.4921875 ]\n", + " [0.48828125]\n", + " [0.5029297 ]]\n", + "\n", + " [[0.49609375]\n", + " [0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.50683594]]]\n", + "\n", + "\n", + " [[[0.5 ]\n", + " [0.49609375]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.51464844]]\n", + "\n", + " [[0.5 ]\n", + " [0.4921875 ]\n", + " [0.5 ]\n", + " [0.5 ]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]]]\n" + ] + } + ], + "source": [ + "print(output_buffer)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31e1098e", + "metadata": {}, + "outputs": [], + "source": [ + "# convert it to numpy array\n", + "print(\"we got output shape:\", output_buffer.shape)\n", + "outNp = np.array(output_buffer)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9bf5d406", + "metadata": {}, + "outputs": [], + "source": [ + "# save it to .npy file\n", + "np.save(\"out_hw.npy\", outNp)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/test/pytest/test_backend/vitis_unified.py b/test/pytest/test_backend/vitis_unified.py index 479f4d2920..75bd6fb381 100644 --- a/test/pytest/test_backend/vitis_unified.py +++ b/test/pytest/test_backend/vitis_unified.py @@ -3,9 +3,6 @@ import numpy as np import pytest import os -from tensorflow.keras.layers import Activation, Dense, GlobalAveragePooling1D, Input -from tensorflow.keras.models import Model - import hls4ml import hls4ml.model @@ -222,4 +219,4 @@ def test_gen_unified(io_type, strategy, granularity, amt_query): vitis_unified_model.compile() vitis_unified_model.build(synth=True, bitfile=True) -#test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file +test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file From 143ae14758d2e80225e5b45e54b0d550ceb6b263 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 15:40:03 +0200 Subject: [PATCH 62/70] push ready to test code and its example driver --- test/pytest/test_backend/pynq_example.ipynb | 513 +++++++++++++++++--- test/pytest/test_backend/vitis_unified.py | 2 +- 2 files changed, 449 insertions(+), 66 deletions(-) diff --git a/test/pytest/test_backend/pynq_example.ipynb b/test/pytest/test_backend/pynq_example.ipynb index 987f3ed962..f0e62618b7 100644 --- a/test/pytest/test_backend/pynq_example.ipynb +++ b/test/pytest/test_backend/pynq_example.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "a0e69eaf", "metadata": {}, "outputs": [], @@ -23,23 +23,81 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "89082d04", "metadata": {}, "outputs": [ { "data": { - "application/javascript": "\ntry {\nrequire(['notebook/js/codecell'], function(codecell) {\n codecell.CodeCell.options_default.highlight_modes[\n 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n Jupyter.notebook.get_cells().map(function(cell){\n if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n });\n});\n} catch (e) {};\n" + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] }, "metadata": {}, "output_type": "display_data" }, { "data": { - "application/javascript": "\ntry {\nrequire(['notebook/js/codecell'], function(codecell) {\n codecell.CodeCell.options_default.highlight_modes[\n 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n Jupyter.notebook.get_cells().map(function(cell){\n if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n });\n});\n} catch (e) {};\n" + "application/javascript": [ + "\n", + "try {\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n", + "} catch (e) {};\n" + ] }, "metadata": {}, "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on Overlay in module pynq.overlay:\n", + "\n", + "\n", + " Default documentation for overlay system.bit. The following\n", + " attributes are available on this overlay:\n", + " \n", + " IP Blocks\n", + " ----------\n", + " myproject_gem_1 : pynq_driver.MyDfxCtrl\n", + " axi_intc_0 : pynq.overlay.DefaultIP\n", + " ps_e : pynq.overlay.DefaultIP\n", + " \n", + " Hierarchies\n", + " -----------\n", + " None\n", + " \n", + " Interrupts\n", + " ----------\n", + " None\n", + " \n", + " GPIO Outputs\n", + " ------------\n", + " None\n", + " \n", + " Memories\n", + " ------------\n", + " PSDDR : Memory\n", + "\n" + ] } ], "source": [ @@ -49,10 +107,299 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "b19361e3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/json": { + "axi_intc_0_intr_1_interrupt_concat/In0": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In0", + "index": 0 + }, + "axi_intc_0_intr_1_interrupt_concat/In1": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In1", + "index": 1 + }, + "axi_intc_0_intr_1_interrupt_concat/In10": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In10", + "index": 10 + }, + "axi_intc_0_intr_1_interrupt_concat/In11": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In11", + "index": 11 + }, + "axi_intc_0_intr_1_interrupt_concat/In12": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In12", + "index": 12 + }, + "axi_intc_0_intr_1_interrupt_concat/In13": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In13", + "index": 13 + }, + "axi_intc_0_intr_1_interrupt_concat/In14": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In14", + "index": 14 + }, + "axi_intc_0_intr_1_interrupt_concat/In15": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In15", + "index": 15 + }, + "axi_intc_0_intr_1_interrupt_concat/In16": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In16", + "index": 16 + }, + "axi_intc_0_intr_1_interrupt_concat/In17": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In17", + "index": 17 + }, + "axi_intc_0_intr_1_interrupt_concat/In18": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In18", + "index": 18 + }, + "axi_intc_0_intr_1_interrupt_concat/In19": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In19", + "index": 19 + }, + "axi_intc_0_intr_1_interrupt_concat/In2": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In2", + "index": 2 + }, + "axi_intc_0_intr_1_interrupt_concat/In20": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In20", + "index": 20 + }, + "axi_intc_0_intr_1_interrupt_concat/In21": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In21", + "index": 21 + }, + "axi_intc_0_intr_1_interrupt_concat/In22": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In22", + "index": 22 + }, + "axi_intc_0_intr_1_interrupt_concat/In23": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In23", + "index": 23 + }, + "axi_intc_0_intr_1_interrupt_concat/In24": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In24", + "index": 24 + }, + "axi_intc_0_intr_1_interrupt_concat/In25": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In25", + "index": 25 + }, + "axi_intc_0_intr_1_interrupt_concat/In26": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In26", + "index": 26 + }, + "axi_intc_0_intr_1_interrupt_concat/In27": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In27", + "index": 27 + }, + "axi_intc_0_intr_1_interrupt_concat/In28": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In28", + "index": 28 + }, + "axi_intc_0_intr_1_interrupt_concat/In29": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In29", + "index": 29 + }, + "axi_intc_0_intr_1_interrupt_concat/In3": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In3", + "index": 3 + }, + "axi_intc_0_intr_1_interrupt_concat/In30": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In30", + "index": 30 + }, + "axi_intc_0_intr_1_interrupt_concat/In31": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In31", + "index": 31 + }, + "axi_intc_0_intr_1_interrupt_concat/In4": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In4", + "index": 4 + }, + "axi_intc_0_intr_1_interrupt_concat/In5": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In5", + "index": 5 + }, + "axi_intc_0_intr_1_interrupt_concat/In6": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In6", + "index": 6 + }, + "axi_intc_0_intr_1_interrupt_concat/In7": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In7", + "index": 7 + }, + "axi_intc_0_intr_1_interrupt_concat/In8": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In8", + "index": 8 + }, + "axi_intc_0_intr_1_interrupt_concat/In9": { + "controller": "axi_intc_0", + "fullpath": "axi_intc_0_intr_1_interrupt_concat/In9", + "index": 9 + }, + "irq_const_tieoff/dout": { + "controller": "axi_intc_0", + "fullpath": "irq_const_tieoff/dout", + "index": 31 + }, + "myproject_gem_1/interrupt": { + "controller": "axi_intc_0", + "fullpath": "myproject_gem_1/interrupt", + "index": 1 + } + }, + "text/plain": [ + "{'irq_const_tieoff/dout': {'controller': 'axi_intc_0',\n", + " 'index': 31,\n", + " 'fullpath': 'irq_const_tieoff/dout'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In0': {'controller': 'axi_intc_0',\n", + " 'index': 0,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In0'},\n", + " 'myproject_gem_1/interrupt': {'controller': 'axi_intc_0',\n", + " 'index': 1,\n", + " 'fullpath': 'myproject_gem_1/interrupt'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In1': {'controller': 'axi_intc_0',\n", + " 'index': 1,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In1'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In2': {'controller': 'axi_intc_0',\n", + " 'index': 2,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In2'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In3': {'controller': 'axi_intc_0',\n", + " 'index': 3,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In3'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In4': {'controller': 'axi_intc_0',\n", + " 'index': 4,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In4'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In5': {'controller': 'axi_intc_0',\n", + " 'index': 5,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In5'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In6': {'controller': 'axi_intc_0',\n", + " 'index': 6,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In6'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In7': {'controller': 'axi_intc_0',\n", + " 'index': 7,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In7'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In8': {'controller': 'axi_intc_0',\n", + " 'index': 8,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In8'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In9': {'controller': 'axi_intc_0',\n", + " 'index': 9,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In9'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In10': {'controller': 'axi_intc_0',\n", + " 'index': 10,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In10'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In11': {'controller': 'axi_intc_0',\n", + " 'index': 11,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In11'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In12': {'controller': 'axi_intc_0',\n", + " 'index': 12,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In12'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In13': {'controller': 'axi_intc_0',\n", + " 'index': 13,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In13'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In14': {'controller': 'axi_intc_0',\n", + " 'index': 14,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In14'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In15': {'controller': 'axi_intc_0',\n", + " 'index': 15,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In15'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In16': {'controller': 'axi_intc_0',\n", + " 'index': 16,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In16'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In17': {'controller': 'axi_intc_0',\n", + " 'index': 17,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In17'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In18': {'controller': 'axi_intc_0',\n", + " 'index': 18,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In18'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In19': {'controller': 'axi_intc_0',\n", + " 'index': 19,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In19'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In20': {'controller': 'axi_intc_0',\n", + " 'index': 20,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In20'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In21': {'controller': 'axi_intc_0',\n", + " 'index': 21,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In21'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In22': {'controller': 'axi_intc_0',\n", + " 'index': 22,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In22'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In23': {'controller': 'axi_intc_0',\n", + " 'index': 23,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In23'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In24': {'controller': 'axi_intc_0',\n", + " 'index': 24,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In24'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In25': {'controller': 'axi_intc_0',\n", + " 'index': 25,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In25'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In26': {'controller': 'axi_intc_0',\n", + " 'index': 26,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In26'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In27': {'controller': 'axi_intc_0',\n", + " 'index': 27,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In27'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In28': {'controller': 'axi_intc_0',\n", + " 'index': 28,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In28'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In29': {'controller': 'axi_intc_0',\n", + " 'index': 29,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In29'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In30': {'controller': 'axi_intc_0',\n", + " 'index': 30,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In30'},\n", + " 'axi_intc_0_intr_1_interrupt_concat/In31': {'controller': 'axi_intc_0',\n", + " 'index': 31,\n", + " 'fullpath': 'axi_intc_0_intr_1_interrupt_concat/In31'}}" + ] + }, + "execution_count": 3, + "metadata": { + "application/json": { + "expanded": false, + "root": "interrupt_pins" + } + }, + "output_type": "execute_result" + } + ], "source": [ "\n", "overlay.interrupt_pins" @@ -60,18 +407,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "0e5b0e03", "metadata": {}, "outputs": [], "source": [ "# create an instance of the interrupt\n", - "my_interrupt = Interrupt()" + "my_interrupt = Interrupt('myproject_gem_1/interrupt')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "9459e8ae", "metadata": {}, "outputs": [], @@ -87,7 +434,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "625c2b1f", "metadata": {}, "outputs": [ @@ -108,7 +455,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "7de66a89", "metadata": {}, "outputs": [], @@ -120,10 +467,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "d18bac75", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "input gmem_in0_ptr_input_1 will be set to addr: 0x78400000 with elements: 160000\n", + "output gmem_out0_ptr_layer12_out will be set to addr: 0x78500000 with elements: 160000\n", + "amount of queries will be set to: 10000 at address: 0x28\n", + "prepare your interrupt\n", + "global interrupt enable register\n", + "enable gie successful\n", + "ap_done interrupt enable register\n", + "enable ap_done interrupt successful\n", + "ap_done register clear\n", + "clear ap_done interrupt successful\n", + "----------------------\n" + ] + } + ], "source": [ "# get the ip and initialize the system\n", "ip = overlay.myproject_gem_1 # Replace with your IP instance name\n", @@ -135,7 +500,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "d12a031a", "metadata": {}, "outputs": [], @@ -150,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "81750e60", "metadata": {}, "outputs": [], @@ -161,10 +526,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "fe5f7eb2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "starting the accelerator\n", + "waiting for the accelerator to finish\n", + "accelerator has finished\n" + ] + } + ], "source": [ "task = loop.create_task(wait_for_acc())\n", "loop.run_until_complete(task)" @@ -172,7 +547,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "372b1982", "metadata": {}, "outputs": [], @@ -182,7 +557,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "6a7834c2", "metadata": {}, "outputs": [ @@ -195,11 +570,6 @@ " [0.5 ]\n", " [0.5 ]]\n", "\n", - " [[0.49609375]\n", - " [0.49609375]\n", - " [0.49609375]\n", - " [0.5 ]]\n", - "\n", " [[0.5 ]\n", " [0.5 ]\n", " [0.5 ]\n", @@ -208,12 +578,17 @@ " [[0.5 ]\n", " [0.5 ]\n", " [0.5 ]\n", - " [0.5029297 ]]]\n", + " [0.49609375]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.4921875 ]\n", + " [0.4765625 ]]]\n", "\n", "\n", " [[[0.5 ]\n", " [0.5 ]\n", - " [0.49609375]\n", + " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", @@ -221,102 +596,102 @@ " [0.5 ]\n", " [0.5 ]]\n", "\n", - " [[0.49609375]\n", - " [0.49609375]\n", + " [[0.5 ]\n", + " [0.5 ]\n", " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", - " [0.5 ]\n", - " [0.5 ]]]\n", + " [0.48046875]\n", + " [0.48046875]]]\n", "\n", "\n", " [[[0.5 ]\n", - " [0.48828125]\n", - " [0.49609375]\n", - " [0.49609375]]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]]\n", "\n", " [[0.5 ]\n", - " [0.48828125]\n", " [0.5 ]\n", - " [0.5 ]]\n", + " [0.5 ]\n", + " [0.49609375]]\n", "\n", - " [[0.49609375]\n", - " [0.49609375]\n", - " [0.49609375]\n", - " [0.5 ]]\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.5 ]\n", + " [0.48828125]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", " [0.5 ]\n", - " [0.5 ]]]\n", + " [0.4921875 ]]]\n", "\n", "\n", " ...\n", "\n", "\n", " [[[0.5 ]\n", - " [0.49609375]\n", + " [0.5 ]\n", " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", - " [0.49609375]\n", " [0.5 ]\n", - " [0.5029297 ]]\n", + " [0.5 ]\n", + " [0.5 ]]\n", "\n", " [[0.5 ]\n", - " [0.49609375]\n", " [0.5 ]\n", - " [0.5029297 ]]\n", + " [0.5 ]\n", + " [0.48046875]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", - " [0.5 ]\n", - " [0.5 ]]]\n", + " [0.4921875 ]\n", + " [0.46875 ]]]\n", "\n", "\n", " [[[0.5 ]\n", - " [0.4921875 ]\n", - " [0.49609375]\n", + " [0.5 ]\n", + " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", - " [0.4921875 ]\n", - " [0.48828125]\n", - " [0.5029297 ]]\n", - "\n", - " [[0.49609375]\n", " [0.5 ]\n", - " [0.49609375]\n", + " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", " [0.5 ]\n", - " [0.50683594]]]\n", + " [0.48046875]]\n", + "\n", + " [[0.5 ]\n", + " [0.5 ]\n", + " [0.49609375]\n", + " [0.484375 ]]]\n", "\n", "\n", " [[[0.5 ]\n", - " [0.49609375]\n", + " [0.5 ]\n", " [0.5 ]\n", " [0.5 ]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", " [0.5 ]\n", - " [0.51464844]]\n", + " [0.5 ]]\n", "\n", " [[0.5 ]\n", - " [0.4921875 ]\n", " [0.5 ]\n", - " [0.5 ]]\n", + " [0.5 ]\n", + " [0.49609375]]\n", "\n", " [[0.5 ]\n", " [0.5 ]\n", - " [0.5 ]\n", - " [0.5 ]]]]\n" + " [0.48828125]\n", + " [0.48828125]]]]\n" ] } ], @@ -326,10 +701,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "31e1098e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "we got output shape: (10000, 4, 4, 1)\n" + ] + } + ], "source": [ "# convert it to numpy array\n", "print(\"we got output shape:\", output_buffer.shape)\n", @@ -338,7 +721,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "9bf5d406", "metadata": {}, "outputs": [], diff --git a/test/pytest/test_backend/vitis_unified.py b/test/pytest/test_backend/vitis_unified.py index 75bd6fb381..745289e345 100644 --- a/test/pytest/test_backend/vitis_unified.py +++ b/test/pytest/test_backend/vitis_unified.py @@ -219,4 +219,4 @@ def test_gen_unified(io_type, strategy, granularity, amt_query): vitis_unified_model.compile() vitis_unified_model.build(synth=True, bitfile=True) -test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file +#test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file From 7097f6341c8636a8dcd1d0116368b84450475df1 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 16:27:59 +0200 Subject: [PATCH 63/70] delete polute file and unconment the compile --- environment.yml | 22 ---------------------- hls4ml/model/graph.py | 2 +- 2 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 environment.yml diff --git a/environment.yml b/environment.yml deleted file mode 100644 index 040c3cb5a7..0000000000 --- a/environment.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: hls4ml-tutorial-dev -channels: - - conda-forge -dependencies: - - python=3.10.16 - - notebook<7 - - jupyter_contrib_nbextensions - - jupyterhub - - jupyter-book - - jsonschema-with-format-nongpl - - pydot==1.4.2 - - graphviz==7.1.0 - - scikit-learn==1.2.2 - - tensorflow==2.14.0 - - tensorflow-datasets==4.8.3 - - webcolors - - widgetsnbextension==3.6.0 - - pip==23.0.1 - - pip: - - pysr==0.16.3 - - xgboost==1.7.5 - - zstd diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index 03727cbdad..cc44fb6084 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1532,7 +1532,7 @@ def write(self): def compile(self): self.write() - #self._compile() + self._compile() def predict(self, x, sim='csim'): if sim == 'csim': From 48e49d4b0152441350950de621e029cbc29d916a Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 16:37:01 +0200 Subject: [PATCH 64/70] remove debug print on multigraph --- hls4ml/model/graph.py | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index cc44fb6084..6a55a4976b 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -1166,7 +1166,6 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] Create a MultiModelGraph by splitting a base ModelGraph at specified layer names, each initiating a subgraph. """ - print("from multi model graph") cls._validate_split_points(base_model, split_before_layers) all_nodes = list(base_model.graph.values()) layer_names = [node.name for node in all_nodes] @@ -1199,7 +1198,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] graph_dict = OrderedDict() pooled_input_layer = [] - print("-------------- idx = ", idx, " -----------------------------") + #print("-------------- idx = ", idx, " -----------------------------") ################################################################ ##### check the current slice node and create new input node ### @@ -1227,8 +1226,6 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] named_new_input_layer = dict() #### inputIdx is index in input of target Node for inputIdx, targetNode in requiredReroute: ### note that tagetNode may be same within requiredRerote - if idx == 1: - print("debug here") ioName = targetNode.inputs[inputIdx] ###### nodeUpdateList[0][1] is the sample Node (Layer) that must be inject to the system input_layer = cls._create_input_node(subgraph, targetNode, #### list of (inputIdx, Node) @@ -1240,8 +1237,6 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] targetNode.inputs[inputIdx] = input_layer.outputs[0] #### update link meta data - if idx == 1: - print("debug here") src_gid, src_graph_out_idx = cls.get_src_subGraph_and_output_idx(subgraphs, ioName) input_node_links[idx].append((src_gid, src_graph_out_idx)) @@ -1271,7 +1266,6 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] subgraph.graph = graph_dict ###### config input - print("idx is ", idx) if idx > 0: subgraph.inputs = [curInputNode.outputs[0] for curInputNode in pooled_input_layer] else: @@ -1279,25 +1273,12 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] ###### config output pooled_outputs = [] - print("checking output") for layer in slice_: outputIdxs = cls.check_io_idx_from_node(slice_, layer, False) - print(f"layer name {layer.name} : {outputIdxs}") for outIdx in outputIdxs: pooled_outputs.append(layer.outputs[outIdx]) subgraph.outputs = pooled_outputs - # subgraph.inputs = input_layer.outputs if idx > 0 else base_model.inputs - # subgraph.outputs = slice_[-1].outputs if idx < len(node_slices) - 1 else base_model.outputs - - print("input ---->") - print(subgraph.inputs) - print("output ---->") - print(subgraph.outputs) - - - - subgraph._applied_flows = base_model._applied_flows # NOTE might need to examine other subgraph-related flows (i.e., fifo_optimizer) subgraph.apply_flow('vivado:specific_types') @@ -1309,7 +1290,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] subgraphs.append(subgraph) - cls.print_input_node_link_debug(input_node_links) + #cls.print_input_node_link_debug(input_node_links) return cls(subgraphs, input_node_links) From d588181b8dc4140251afcd062713f0795cc1bcce Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 18:34:55 +0200 Subject: [PATCH 65/70] change xpfm default Path --- hls4ml/backends/vitis_unified/vitis_unified_backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 6cc89615df..3fd3b28198 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -146,7 +146,7 @@ def create_initial_config( output_type ='float', in_stream_buf_size =128, out_stream_buf_size =128, - xpfmPath ='/tools/Xilinx/Vitis/2023.2/base_platforms/' + xpfmPath ='/opt/Xilinx/Vitis/2023.2/base_platforms/' 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', **_ ): From b2ee0e3eec11dd478f20626c9fcc804a0f369f90 Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 21:31:10 +0200 Subject: [PATCH 66/70] revert the multigraph modification because it is not relate to this branch at all --- hls4ml/model/graph.py | 263 ++++-------------------------------------- 1 file changed, 25 insertions(+), 238 deletions(-) diff --git a/hls4ml/model/graph.py b/hls4ml/model/graph.py index 6a55a4976b..e3c293dd46 100644 --- a/hls4ml/model/graph.py +++ b/hls4ml/model/graph.py @@ -8,7 +8,6 @@ import threading import uuid from collections import OrderedDict -from operator import indexOf import numpy as np import numpy.ctypeslib as npc @@ -1037,249 +1036,61 @@ def save(self, file_path): class MultiModelGraph: - def __init__(self, graphs: list[ModelGraph], input_node_links = None): + def __init__(self, graphs: list[ModelGraph]): """ Create a stitched model from pre-optimized subgraphs. """ self.graphs = graphs - self.input_node_links = input_node_links self._initialize_config(self.graphs[0]) self._bind_modelgraph_methods() self._initialize_io_attributes(self.graphs) - - - - ##### node link is the meta data that used to store how the new generated input node when the graph was chopped connect with the source data node - - ##### |-------------graph 0 ------------| - ##### [ [(src_graph_idx, output_idx), ....], ] - - - - @staticmethod - def check_io_idx_from_node(node_slices, inspectNode, isAnalyzeInput: bool): - - """ - check the Input of the inspectNode (incase isAnalyzeInput=True) that is come from outside current graph - check the Output of the inspectNode (incase isAnalyzeInput=False) that is come from outside current graph - return idx of the io array to indicate which io should be rerouted - """ - - requiredReroute = [] - - io_of_inspect_node = inspectNode.inputs if isAnalyzeInput else inspectNode.outputs - - for idx, ioName in enumerate(io_of_inspect_node): - shouldReroute = True - for curNode in node_slices: - #### the same node must be skipped - if curNode.name == inspectNode.name: - continue - io_of_scanning_node = curNode.outputs if isAnalyzeInput else curNode.inputs - if ioName in io_of_scanning_node: - shouldReroute = False - break - if shouldReroute: - requiredReroute.append(idx) - # if isAnalyzeInput: - # print("reroute IN put = ", idx, " ", ioName) - # print(" nodeName", inspectNode.name) - # print(" inputs", inspectNode.inputs) - # print(" outputs", inspectNode.outputs) - # print("-----------------") - return requiredReroute - - @staticmethod - def get_src_node_from_output_name(base_model: ModelGraph, output_name: str): - for layer_name, node in base_model.graph.items(): - if output_name in node.outputs: - return node, node.outputs.indexOf(output_name) - - @staticmethod - def get_src_subGraph_and_output_idx(subGraphs, output_name): - - for gid, subGraph in enumerate(subGraphs): - if output_name in subGraph.outputs: - return gid, subGraph.outputs.index(output_name) - - return -1, -1 - - - - @staticmethod - def group_for_creating_new_io(meta, isAnalyzeInput: bool): - - """ - some io that we gather from each node from the graph may have the same input source - if that so we should group it together - meta is list of (ioIdx, ofNode) - return {io_name: [(ioIdx, ofNode), ....]} - """ - rerouted_result = dict() - - for idx, node in meta: - ioName = node.inputs[idx] if isAnalyzeInput else node.outputs[idx] - if ioName not in rerouted_result: - rerouted_result[ioName] = [] - rerouted_result[ioName].append((idx, node)) - - return rerouted_result - - @staticmethod - def add_config_for_multi_model(baseConfig, newConfig, amount_graph, graph_idx, input_raw: bool, output_raw: bool): - - ######### we focus on copy 'MultiGraphConfig' - if 'MultiGraphConfig' in baseConfig: - newConfig['MultiGraphConfig'] = copy.deepcopy(baseConfig.get('MultiGraphConfig', {})) - ######## create the structure - newConfig.setdefault('MultiGraphConfig', {}) - newConfig['MultiGraphConfig']['amtGraph'] = amount_graph - newConfig['MultiGraphConfig']['graphIdx'] = graph_idx - newConfig['MultiGraphConfig']['MgsMeta' ] = [] - - newConfig['MultiGraphConfig'].setdefault('IOInterimType', {}) - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Input' , None ) - newConfig['MultiGraphConfig']['IOInterimType'].setdefault('Output', None ) - - newConfig['MultiGraphConfig']['IOInterimType']['Input'] = "io_free_stream" if input_raw else 'io_stream' - newConfig['MultiGraphConfig']['IOInterimType']['Output'] = "io_free_stream" if output_raw else 'io_stream' - - - - - # print(newConfig) - - @staticmethod - def print_input_node_link_debug(input_node_links): - print("------ input_node_links ----------") - for gid, input_metas in enumerate(input_node_links): - print(f" ----- @ graph idx {gid}") - for idx, (src_gid, src_output_idx) in enumerate(input_metas): - print(f" input {idx}: get data from graph {src_gid} output {src_output_idx}") - - ######## try to copy from the base model, if it it exist - @classmethod - def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str], free_axi_interim: bool = False): + def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str]): """ Create a MultiModelGraph by splitting a base ModelGraph at specified layer names, each initiating a subgraph. """ cls._validate_split_points(base_model, split_before_layers) - all_nodes = list(base_model.graph.values()) - layer_names = [node.name for node in all_nodes] + all_nodes = list(base_model.graph.values()) + layer_names = [node.name for node in all_nodes] split_indices = sorted(layer_names.index(s) for s in split_before_layers) - bounds = [0] + split_indices + [len(all_nodes)] + bounds = [0] + split_indices + [len(all_nodes)] node_slices: list[list] = [all_nodes[bounds[i] : bounds[i + 1]] for i in range(len(bounds) - 1)] base_input_layer = base_model.graph[base_model.inputs[0]] input_layer_kind = base_input_layer.attributes['class_name'] next_index = max(n.index for n in all_nodes) - input_node_links = [ [] for _ in range(len(node_slices))] - subgraphs: list['ModelGraph'] = [] for idx, slice_ in enumerate(node_slices): - - #### clone and modify the config cfg_copy = copy.copy(base_model.config) cfg_copy.config = copy.copy(base_model.config.config) - cls.add_config_for_multi_model(base_model.config.config, - cfg_copy.config, - len(node_slices), idx, - free_axi_interim and (idx != 0), - free_axi_interim and (idx != (len(node_slices)-1))) - cfg_copy.config['ProjectName'] = f'{base_model.config.get_project_name()}_graph{idx + 1}' cfg_copy.config['OutputDir'] = os.path.join(base_model.config.get_output_dir(), f'graph{idx + 1}') - subgraph = base_model.__class__(cfg_copy, inputs=[], outputs=[]) - graph_dict = OrderedDict() - - pooled_input_layer = [] - #print("-------------- idx = ", idx, " -----------------------------") + subgraph = ModelGraph(cfg_copy, inputs=[], outputs=[]) + graph_dict: OrderedDict[str, Layer] = OrderedDict() - ################################################################ - ##### check the current slice node and create new input node ### - ################################################################ if idx > 0: - requiredReroute = [] - - ###### get input for each slice - for checkingNode in slice_: - nodeInputChangeList = cls.check_io_idx_from_node(slice_, checkingNode, True) - #### node input change list = [changeIdx: int, ....] - #### add to requiredReroute - for changeIdx in nodeInputChangeList: - requiredReroute.append((changeIdx, checkingNode)) - - ###### grouping it, incase the io have been reused many time - ######### rerouteGrp { "ioName" : [(inputIdx, Node), ....]} - - - #rerouteGrp = cls.group_for_creating_new_io(requiredReroute, True) - - - ###### create reroute for for each new input - - named_new_input_layer = dict() - #### inputIdx is index in input of target Node - for inputIdx, targetNode in requiredReroute: ### note that tagetNode may be same within requiredRerote - ioName = targetNode.inputs[inputIdx] - ###### nodeUpdateList[0][1] is the sample Node (Layer) that must be inject to the system - input_layer = cls._create_input_node(subgraph, targetNode, #### list of (inputIdx, Node) - input_layer_kind, next_index, - next_node_portName = ioName, - namedNewInputLayer = named_new_input_layer) - pooled_input_layer.append(input_layer) - graph_dict[input_layer.name] = input_layer - targetNode.inputs[inputIdx] = input_layer.outputs[0] - - #### update link meta data - src_gid, src_graph_out_idx = cls.get_src_subGraph_and_output_idx(subgraphs, ioName) - input_node_links[idx].append((src_gid, src_graph_out_idx)) - - - # print("added name is ", input_layer.name ) - # print("output from input layer", input_layer.outputs) - # print("input from input layer", input_layer.inputs) - - next_index += 1 - - ####### the input node should have 1 input node right so - + next_index += 1 + input_layer = cls._create_input_node(subgraph, slice_[0], input_layer_kind, next_index) + graph_dict[input_layer.name] = input_layer + slice_[0].inputs = input_layer.outputs else: input_layer = base_input_layer - pooled_input_layer.append(input_layer) - input_node_links[idx].append((-1, -1)) - - ############################## - ##### config new graph ####### - ############################## for node in slice_: - graph_dict[node.name] = node - node.model = subgraph # fix for layer.model.get_layer_output_variable() + node.model = subgraph # fix for layer.model.get_layer_output_variable() for out_name in node.outputs: subgraph.output_vars[out_name] = base_model.output_vars[out_name] - subgraph.graph = graph_dict - - ###### config input - if idx > 0: - subgraph.inputs = [curInputNode.outputs[0] for curInputNode in pooled_input_layer] - else: - subgraph.inputs = base_model.inputs - - ###### config output - pooled_outputs = [] - for layer in slice_: - outputIdxs = cls.check_io_idx_from_node(slice_, layer, False) - for outIdx in outputIdxs: - pooled_outputs.append(layer.outputs[outIdx]) + graph_dict[node.name] = node - subgraph.outputs = pooled_outputs + subgraph.graph = graph_dict + subgraph.inputs = input_layer.outputs if idx > 0 else base_model.inputs + subgraph.outputs = slice_[-1].outputs if idx < len(node_slices) - 1 else base_model.outputs subgraph._applied_flows = base_model._applied_flows + # NOTE might need to examine other subgraph-related flows (i.e., fifo_optimizer) subgraph.apply_flow('vivado:specific_types') subgraph.apply_flow('vitis:apply_templates') @@ -1290,9 +1101,7 @@ def from_model_graph(cls, base_model: ModelGraph, split_before_layers: list[str] subgraphs.append(subgraph) - #cls.print_input_node_link_debug(input_node_links) - - return cls(subgraphs, input_node_links) + return cls(subgraphs) @staticmethod def _validate_split_points(model: ModelGraph, split_names: list[str]): @@ -1307,36 +1116,21 @@ def _validate_split_points(model: ModelGraph, split_names: list[str]): raise ValueError(f"Split layer '{name}' not found in the model.") if len(node.inputs) > 1: raise ValueError(f"Cannot split at layer '{name}' (multiple inputs detected).") - - hostName = None - for key, value in model.graph.items(): - if value.outputs[0] == node.inputs[0]: - hostName = key - - if model.graph[hostName].class_name == 'Reshape' or node.class_name == 'Reshape': + if model.graph[node.inputs[0]].class_name == 'Reshape' or node.class_name == 'Reshape': raise ValueError(f"Cannot split at '{name}': Reshape layer found in this or previous layer.") @staticmethod - def _create_input_node(model, next_node, kind, index, next_node_portName = None, namedNewInputLayer = None): + def _create_input_node(model, next_node, kind, index): layer_name = f'{next_node.name}_input' - - if (namedNewInputLayer is not None): - if layer_name in namedNewInputLayer: - newLayerName = layer_name + "_" + str(namedNewInputLayer[layer_name]) - namedNewInputLayer[layer_name] = namedNewInputLayer[layer_name] + 1 - layer_name = newLayerName - else: - namedNewInputLayer[layer_name] = 0 - attrs = { 'name': layer_name, 'class_name': kind, 'data_format': 'channels_last', - 'input_shape': next_node.get_input_variable(next_node_portName).shape, + 'input_shape': next_node.get_input_variable().shape, } model.index = index node = model.make_node(kind, layer_name, attrs, [layer_name], [layer_name], initialize=True) - model.output_vars[layer_name].type.precision = next_node.get_input_variable(next_node_portName).type.precision + model.output_vars[layer_name].type.precision = next_node.get_input_variable().type.precision return node def _initialize_config(self, first_graph): @@ -1349,10 +1143,6 @@ def _initialize_config(self, first_graph): self._update_project_config(first_graph) self.backend = first_graph.config.backend - ####### after Multigraph split already some config may have been augment after - self.backend.augment_multigraph_writer(self) - - def _bind_modelgraph_methods(self): # Bind necessary ModelGraph methods to this instance self._compile = ModelGraph._compile.__get__(self, MultiModelGraph) @@ -1480,8 +1270,6 @@ def build_wrapper(idx, g, **kwargs): self.graph_reports = build_results - self.backend.build(self, compose_streamers = True) - if stitch_design or sim_stitched_design or export_stitched_design: failed_graphs = [name for name, report in build_results.items() if report is None] if failed_graphs: @@ -1508,8 +1296,7 @@ def write(self): self.nn_config = self.parse_nn_config() self.config.config['Stamp'] = self._make_stamp() # Bypass VitisWriter and invoke write_hls directly from VivadoWriter - #super(self.backend.writer.__class__, self.backend.writer).write_hls(self, is_multigraph=True) - self.backend.writer.write_hls(self, is_multigraph=True) + super(self.backend.writer.__class__, self.backend.writer).write_hls(self, is_multigraph=True) def compile(self): self.write() @@ -1679,7 +1466,7 @@ def _replace_logos(self): print(f'Error copying hls4ml logo to {g.config.get_output_dir()} project: {e}') -def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str], free_axi_interim = False): +def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str]): """ Create a MultiModelGraph by splitting a base ModelGraph before the specified layer names. @@ -1691,4 +1478,4 @@ def to_multi_model_graph(model: ModelGraph, split_before_layers: list[str], free Returns: multi_model_graph (MultiModelGraph): the partitioned multi model graph """ - return MultiModelGraph.from_model_graph(model, split_before_layers, free_axi_interim) + return MultiModelGraph.from_model_graph(model, split_before_layers) From b17d2b2791db4e3f767bb6d9c285aae82f14978d Mon Sep 17 00:00:00 2001 From: tanawin Date: Fri, 29 Aug 2025 21:45:13 +0200 Subject: [PATCH 67/70] get the code out that not related to vitisUnified backend --- .gitignore | 3 +-- hls4ml/backends/vivado/vivado_backend.py | 7 ------- hls4ml/converters/__init__.py | 1 - hls4ml/templates/vivado/nnet_utils/nnet_helpers.h | 1 - 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 7ee704bea8..f41167678f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ sdist/ *.egg-info/ vivado_prj .vscode +.idea my-hls-test *.tar.gz docs/_build @@ -15,7 +16,5 @@ hls4mlprj_* *~ *.ipynb_checkpoints/ -.idea/* -myTest/* test/pytest/test_backend/input_file/* test/pytest/test_backend/output_file/* \ No newline at end of file diff --git a/hls4ml/backends/vivado/vivado_backend.py b/hls4ml/backends/vivado/vivado_backend.py index f54c03d63a..d5309c377f 100644 --- a/hls4ml/backends/vivado/vivado_backend.py +++ b/hls4ml/backends/vivado/vivado_backend.py @@ -288,13 +288,6 @@ def create_initial_config( return config - def augment_multigraph_writer(self, multi_model_config): - """Augment the configuration of a multi-graph model.""" - """ - no return value - """ - pass - def build( self, model, diff --git a/hls4ml/converters/__init__.py b/hls4ml/converters/__init__.py index eb6c587b31..89f4fc04b9 100644 --- a/hls4ml/converters/__init__.py +++ b/hls4ml/converters/__init__.py @@ -167,7 +167,6 @@ def convert_from_keras_model( hls_config=None, **kwargs, ): - """Convert Keras model to hls4ml model based on the provided configuration. Args: diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h index 655102971d..225bce181d 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_helpers.h @@ -10,7 +10,6 @@ #include #include #include -#include namespace nnet { From 3f6a37e3aedd939fbd6716bcdd09bb84744045cb Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 2 Sep 2025 12:11:39 +0200 Subject: [PATCH 68/70] update code to precommit style --- .gitignore | 2 +- hls4ml/backends/__init__.py | 19 +- .../passes/fifo_depth_optimization.py | 64 +++---- .../vitis_unified/vitis_unified_backend.py | 111 ++++++------ .../vitis_unified/vitis_unified_config.py | 37 ++-- hls4ml/templates/vitis_unified/build_lib.sh | 2 +- .../{pynq_driver.py => pynq_driver.py.hls4ml} | 39 ++-- .../vitis_unified/hls_kernel_config.cfg | 2 +- .../templates/vitis_unified/myproject_dm.cpp | 68 +++---- hls4ml/templates/vitis_unified/myproject_dm.h | 8 +- .../workspace/projectName/vitis-comp.json | 2 +- .../workspace/sysProj/buildAcc.sh | 2 +- .../workspace/sysProj/buildConfig.cfg | 2 +- hls4ml/writer/__init__.py | 2 +- .../writer/vitis_unified_writer/__init__.py | 69 ++++--- .../writer/vitis_unified_writer/build_gen.py | 42 ++--- .../writer/vitis_unified_writer/driver_gen.py | 22 +-- hls4ml/writer/vitis_unified_writer/meta.py | 4 +- .../writer/vitis_unified_writer/meta_gen.py | 25 +-- .../vitis_unified_writer/test_bridge_gen.py | 18 +- .../vitis_unified_writer/test_cosim_gen.py | 64 +++---- .../writer/vitis_unified_writer/wrap_gen.py | 76 ++++---- hls4ml/writer/vitis_writer.py | 4 +- test/pytest/test_backend/cmpResult.py | 15 +- test/pytest/test_backend/vitis_unified.py | 170 ++++++++++-------- 25 files changed, 420 insertions(+), 449 deletions(-) rename hls4ml/templates/vitis_unified/driver/pynq/{pynq_driver.py => pynq_driver.py.hls4ml} (72%) diff --git a/.gitignore b/.gitignore index f41167678f..8151cd3af9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ hls4mlprj_* *.ipynb_checkpoints/ test/pytest/test_backend/input_file/* -test/pytest/test_backend/output_file/* \ No newline at end of file +test/pytest/test_backend/output_file/* diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 2a53a50aca..599d875c64 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -3,6 +3,7 @@ from hls4ml.backends.oneapi.oneapi_backend import OneAPIBackend from hls4ml.backends.quartus.quartus_backend import QuartusBackend from hls4ml.backends.symbolic.symbolic_backend import SymbolicExpressionBackend +from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend from hls4ml.backends.vivado.vivado_backend import VivadoBackend from hls4ml.backends.vivado_accelerator.vivado_accelerator_backend import VivadoAcceleratorBackend from hls4ml.backends.vivado_accelerator.vivado_accelerator_config import VivadoAcceleratorConfig # noqa: F401 @@ -11,14 +12,12 @@ from hls4ml.backends.vitis.vitis_backend import VitisBackend # isort: skip -from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend -from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig -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) -register_backend('oneAPI' , OneAPIBackend) +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) +register_backend('oneAPI', OneAPIBackend) diff --git a/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py index 12968774d7..d8e75862cd 100644 --- a/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py +++ b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py @@ -1,15 +1,15 @@ - -###### we inherit it from vitis -import json +# we inherit it from vitis import zipfile -from hls4ml.model.optimizer.optimizer import ConfigurableOptimizerPass, ModelOptimizerPass -from hls4ml.backends.vitis.passes.fifo_depth_optimization import (initialize_large_fifos, \ - generate_depths_file, \ - set_optimized_fifo_depths) +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): +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! @@ -23,26 +23,16 @@ def get_vitis_optimized_fifo_depths(model, cus_hls_prj_path = None): # 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' - + 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/' - ) + 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' - ) + names_file_path = cus_hls_prj_path + '/.autopilot/db/channel_info.csv' csv_fifo_depth_files = {} with open(names_file_path) as names_file: @@ -67,18 +57,19 @@ def get_vitis_optimized_fifo_depths(model, cus_hls_prj_path = None): def execute_cosim_to_profile_fifos(model): model.write() model.build( - reset = False, - csim = False, - synth = True, - cosim = False, - validation = False, - export = False, - vsynth = False, - fifo_opt = True, - bitfile = False, - log_to_stdout = True + reset=False, + csim=False, + synth=True, + cosim=False, + validation=False, + export=False, + vsynth=False, + fifo_opt=True, + bitfile=False, + log_to_stdout=True, ) + class FifoDepthOptimization(ConfigurableOptimizerPass, ModelOptimizerPass): def __init__(self): @@ -103,23 +94,20 @@ def transform(self, model): """ 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.') + 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.') - + raise RuntimeError('To use this optimization you have to set `IOType` field to `io_stream` in the HLS config.') hlsPrjPath = model.config.backend.writer.mg.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") + 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 \ No newline at end of file + return False diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 3fd3b28198..8c5fdad829 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -1,14 +1,11 @@ import os -import sys import subprocess +import sys from shutil import copy2 - from hls4ml.backends import VitisBackend, VivadoBackend from hls4ml.model.flow import register_flow -from hls4ml.report import parse_vivado_report - -from hls4ml.writer.vitis_unified_writer.meta_gen import VitisUnified_MetaGen as mg +from hls4ml.writer.vitis_unified_writer.meta_gen import VitisUnified_MetaGen as mg class VitisUnifiedBackend(VitisBackend): @@ -17,7 +14,6 @@ def __init__(self): self._register_layer_attributes() self._register_flows() - def run_term_command(self, model, taskName: str, command: str, logStdOut: bool, cwd): print("-------------------------------------------------------") @@ -29,16 +25,16 @@ def run_term_command(self, model, taskName: str, command: str, logStdOut: bool, out_log_path = os.path.join(output_dir, f'{taskName}_out.log') err_log_path = os.path.join(output_dir, f'{taskName}_err.log') - out_target = None if logStdOut else open(out_log_path, 'w') - err_target = None if logStdOut else open(err_log_path, 'w') + out_target = None if logStdOut else open(out_log_path, 'w') + err_target = None if logStdOut else open(err_log_path, 'w') try: - runningProcess = subprocess.Popen( - command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True - ) + runningProcess = subprocess.Popen(command, shell=True, cwd=cwd, stdout=out_target, stderr=err_target, text=True) runningProcess.communicate() if runningProcess.returncode != 0: - raise Exception(f'Package failed for {taskName} for project {model.config.get_project_name()}. See logs for details.') + raise Exception( + f'Package failed for {taskName} for project {model.config.get_project_name()}. See logs for details.' + ) stdout, stderr = runningProcess.communicate() print(f"stdout: {stdout}") @@ -56,54 +52,51 @@ def run_term_command(self, model, taskName: str, command: str, logStdOut: bool, if err_target: err_target.close() - - def build( self, model, - reset = False, - csim = False, - synth = False, - cosim = False, - validation = False, - export = False, - vsynth = False, - fifo_opt = False, - bitfile = False, - log_to_stdout = True + reset=False, + csim=False, + synth=False, + cosim=False, + validation=False, + export=False, + vsynth=False, + fifo_opt=False, + bitfile=False, + log_to_stdout=True, ): - ##### it builds and return vivado reports + # it builds and return vivado reports if 'linux' in sys.platform: found = os.system('command -v vitis > /dev/null') if found != 0: raise Exception('Vitis installation not found. Make sure "vitis" is on PATH.') - ##### TODO support this system if csim: raise Exception("Current Vitis Unified not support csim. Please set csim=False to run Vitis Unified.") if validation: - raise Exception("Current Vitis Unified not support validation. Please set validation=False to run Vitis Unified.") + raise Exception( + "Current Vitis Unified not support validation. Please set validation=False to run Vitis Unified." + ) if export: raise Exception("Current Vitis Unified not support export. Please set export=False to run Vitis Unified.") 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 unifiedPrj" - ).format(configPath=hls_config_file) + # build command + csynth_cmd = ("v++ -c --mode hls --config {configPath} --work_dir unifiedPrj").format(configPath=hls_config_file) csynth_cwd = mg.get_vitis_hls_dir(model) - ##### util template (used in csim/cosim/package) + # util template (used in csim/cosim/package) util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" - ##### package command + # package command package_cmd = util_command.format(op="package", configPath=hls_config_file) package_cwd = mg.get_vitis_hls_dir(model) - cosim_cmd = util_command.format(op="cosim" , configPath=hls_config_file) - cosim_cwd = mg.get_vitis_hls_dir(model) - csim_cmd = util_command.format(op="csim" , configPath=hls_config_file) + cosim_cmd = util_command.format(op="cosim", configPath=hls_config_file) + cosim_cwd = mg.get_vitis_hls_dir(model) + csim_cmd = util_command.format(op="csim", configPath=hls_config_file) csim_cwd = mg.get_vitis_hls_dir(model) kerlink_cmd = "./buildAcc.sh" @@ -122,11 +115,10 @@ def build( self.prepare_sim_config_file(model, False) self.run_term_command(model, "cosim", cosim_cmd, log_to_stdout, cosim_cwd) - ##if bitfile + # if bitfile if bitfile: self.run_term_command(model, "kerlink", kerlink_cmd, log_to_stdout, kerlink_cwd) - 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" @@ -136,31 +128,30 @@ def prepare_sim_config_file(self, model, is_csim): 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, - xpfmPath ='/opt/Xilinx/Vitis/2023.2/base_platforms/' - 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', - **_ + 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, + xpfmPath='/opt/Xilinx/Vitis/2023.2/base_platforms/' 'xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm', + **_, ): config = super().create_initial_config(part, clock_period, clock_uncertainty, io_type) config['UnifiedConfig'] = {} - config['UnifiedConfig']["in_stream_buf_Size" ] = in_stream_buf_size - config['UnifiedConfig']["out_stream_buf_Size"] = out_stream_buf_size - config['UnifiedConfig']['XPFMPath' ] = xpfmPath - config['UnifiedConfig']['Board' ] = board - config['UnifiedConfig']['Driver' ] = driver - config['UnifiedConfig']['InputDtype' ] = input_type # float, double or ap_fixed - config['UnifiedConfig']['OutputDtype' ] = output_type # float, double or ap_fixed + config['UnifiedConfig']["in_stream_buf_Size"] = in_stream_buf_size + config['UnifiedConfig']["out_stream_buf_Size"] = out_stream_buf_size + config['UnifiedConfig']['XPFMPath'] = xpfmPath + config['UnifiedConfig']['Board'] = board + config['UnifiedConfig']['Driver'] = driver + config['UnifiedConfig']['InputDtype'] = input_type # float, double or ap_fixed + config['UnifiedConfig']['OutputDtype'] = output_type # float, double or ap_fixed if io_type != "io_stream": raise Exception("io_type must be io_stream") @@ -183,9 +174,7 @@ def _register_flows(self): self._writer_flow = register_flow('write', writer_passes, requires=['vitis:ip'], backend=self.name) self._default_flow = vitis_ip - ########### register fifo depth optimization + # 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 index a8046bb191..0b262de502 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -1,39 +1,24 @@ -import json -import os - -import numpy as np - -from hls4ml.model.layers import FixedPrecisionType, IntegerPrecisionType - class VitisUnifiedConfig: - def __init__(self, config, model_inputs, model_outputs): self.config = config.config self.board = self.config.get('UnifiedConfig', {}).get('Board', 'pynq-z2') - self.in_steram_bufferSz = self.config["UnifiedConfig"]["in_stream_buf_Size" ] + self.in_steram_bufferSz = self.config["UnifiedConfig"]["in_stream_buf_Size"] self.out_stream_bufferSz = self.config["UnifiedConfig"]["out_stream_buf_Size"] - self.XPFMPath = self.config["UnifiedConfig"]["XPFMPath"] - - self.driver = self.config['UnifiedConfig']['Driver'] - self.input_type = self.config['UnifiedConfig']['InputDtype' ] - self.output_type = self.config['UnifiedConfig']['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.XPFMPath = self.config["UnifiedConfig"]["XPFMPath"] + + self.driver = self.config['UnifiedConfig']['Driver'] + self.input_type = self.config['UnifiedConfig']['InputDtype'] + self.output_type = self.config['UnifiedConfig']['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 get_corrected_types(self): return self.input_type, self.output_type, self.inps, self.outs @@ -56,4 +41,4 @@ def get_out_stream_bufferSz(self): return self.out_stream_bufferSz def get_XPFMPath(self): - return self.XPFMPath \ No newline at end of file + return self.XPFMPath diff --git a/hls4ml/templates/vitis_unified/build_lib.sh b/hls4ml/templates/vitis_unified/build_lib.sh index a2b0d636e3..2645804f90 100644 --- a/hls4ml/templates/vitis_unified/build_lib.sh +++ b/hls4ml/templates/vitis_unified/build_lib.sh @@ -28,4 +28,4 @@ ${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR="${WEIGHTS_DIR}" -c firmware/${PROJEC ${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 \ No newline at end of file +rm -f *.o diff --git a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py.hls4ml similarity index 72% rename from hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py rename to hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py.hls4ml index a279de9f72..e8c1d0de5c 100644 --- a/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py +++ b/hls4ml/templates/vitis_unified/driver/pynq/pynq_driver.py.hls4ml @@ -1,13 +1,14 @@ # 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 -import numpy as np import os -import subprocess import re +import subprocess import time +import numpy as np +from pynq import DefaultIP # import the ip connector library for extension +from pynq import Overlay # import the overlay +from pynq import allocate # import for CMA (contingeous memory allocation) + class MyDfxCtrl(DefaultIP): def __init__(self, description): @@ -15,28 +16,25 @@ def __init__(self, description): self.REG_ADDR_AP_CTRL = 0x00 self.REG_ADDR_AMT_QUERY = VAL - ##################### - self.REG_ADDR_GIE = 0x04 - self.REG_ADDR_IER = 0x08 - self.REG_ADDR_ISR = 0x0C - - + self.REG_ADDR_GIE = 0x04 + self.REG_ADDR_IER = 0x08 + self.REG_ADDR_ISR = 0x0C self.INP_PORT_NAMEs = [ - #### hls-driver-input-dbg-name + # hls-driver-input-dbg-name ] self.REG_ADDR_INP_PTRs = [ - #### hls-driver-input-ptr + # hls-driver-input-ptr ] self.OUT_PORT_NAMEs = [ - #### hls-driver-output-dbg-name + # hls-driver-output-dbg-name ] self.REG_ADDR_OUT_PTRs = [ - #### hls-driver-output-ptr + # hls-driver-output-ptr ] bindto = ['xilinx.com:hls::1.0'] @@ -68,7 +66,6 @@ def prepare_intr(self): self.clear_done_status() print("----------------------") - def set_single_bit(self, addr, idx): self.write(addr, 1 << idx) @@ -81,17 +78,21 @@ def wait_until_done(self): 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}") + 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}") + 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_AMT_QUERY)}") - self.write(self.REG_ADDR_AMT_QUERY, val) \ No newline at end of file + self.write(self.REG_ADDR_AMT_QUERY, val) diff --git a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg index f888096df1..c1d12a0c18 100644 --- a/hls4ml/templates/vitis_unified/hls_kernel_config.cfg +++ b/hls4ml/templates/vitis_unified/hls_kernel_config.cfg @@ -21,4 +21,4 @@ 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 \ No newline at end of file +cosim.enable_fifo_sizing=true diff --git a/hls4ml/templates/vitis_unified/myproject_dm.cpp b/hls4ml/templates/vitis_unified/myproject_dm.cpp index 0043487b93..fa373d5a4c 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.cpp +++ b/hls4ml/templates/vitis_unified/myproject_dm.cpp @@ -1,37 +1,36 @@ -#include #include #include +#include //#include "ap_axi_sdata.h" #include "MY_PROJECT_DM_INC.h" #define STREAM_BUF_IN_SZ VAL #define STREAM_BUF_OUT_SZ VAL - -template -void load_input(ATOMIC_TYPE* in, hls::stream& inStream, int amtQuery, const int TENSOR_SIZE) { +template +void load_input(ATOMIC_TYPE *in, hls::stream &inStream, int amtQuery, const int TENSOR_SIZE) { mem_rd: int baseQuery = 0; for (int q = 0; q < amtQuery; 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); + 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 amtQuery, const int TENSOR_SIZE) { +template +void store_result(ATOMIC_TYPE *out, hls::stream &out_stream, int amtQuery, const int TENSOR_SIZE) { mem_wr: int baseQuery = 0; - for (int q = 0; q < amtQuery; q++){ - for (int i = 0; i < TENSOR_SIZE/OUT_LAYER_ARR::size; i++){ + for (int q = 0; q < amtQuery; 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++){ + for (int j = 0; j < OUT_LAYER_ARR::size; j++) { out[baseQuery] = tmp[j]; baseQuery++; } @@ -39,36 +38,27 @@ void store_result(ATOMIC_TYPE* out, hls::stream& out_stream, int } } - void MY_PROJECT_TOP_FUNC( -// vitis-unified-wrapper-io - ,int amtQuery - -){ - -// vitis-unified-wrapper-interface -#pragma HLS INTERFACE s_axilite port=amtQuery bundle=control -#pragma HLS INTERFACE s_axilite port=return bundle=control + // vitis-unified-wrapper-io + , int amtQuery +) { -// vitis-unified-wrapper-stream-dec + // vitis-unified-wrapper-interface + #pragma HLS INTERFACE s_axilite port=amtQuery bundle=control + #pragma HLS INTERFACE s_axilite port=return bundle=control + // vitis-unified-wrapper-stream-dec -// vitis-unified-wrapper-stream-config + // vitis-unified-wrapper-stream-config + #pragma HLS dataflow -#pragma HLS dataflow - -// vitis-unified-wrapper-load - - - for (int q = 0; q < amtQuery; q++){ -// vitis-unified-wrapper-compute + // vitis-unified-wrapper-load + for (int q = 0; q < amtQuery; q++) { + // vitis-unified-wrapper-compute } - -// vitis-unified-wrapper-store - - -} \ No newline at end of file + // vitis-unified-wrapper-store +} diff --git a/hls4ml/templates/vitis_unified/myproject_dm.h b/hls4ml/templates/vitis_unified/myproject_dm.h index 01abce32d9..d8ca8eb0f7 100644 --- a/hls4ml/templates/vitis_unified/myproject_dm.h +++ b/hls4ml/templates/vitis_unified/myproject_dm.h @@ -5,11 +5,9 @@ #include "MY_PROJECT_INC.h" - void MY_PROJECT_TOP_FUNC( -// vitis-unified-wrapper-io - ,int amtQuery -); + // vitis-unified-wrapper-io + , int amtQuery); -#endif \ No newline at end of file +#endif diff --git a/hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json b/hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json index c047eba31c..9c7eb3fb62 100644 --- a/hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json +++ b/hls4ml/templates/vitis_unified/workspace/projectName/vitis-comp.json @@ -6,4 +6,4 @@ "configFiles": ["{CONFIG_FILE}"], "work_dir": "unifiedPrj" } -} \ No newline at end of file +} diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh index 8bed88a2fa..38da5ac4e5 100644 --- a/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildAcc.sh @@ -3,4 +3,4 @@ v++ -l -t hw --platform {PLATFORM_XPFM} {KERNEL_XO} --config buildConfig.cfg -o [ -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 \ No newline at end of file +cp _x/link/vivado/vpl/prj/prj.gen/sources_1/bd/vitis_design/hw_handoff/vitis_design.hwh ../../export/system.hwh diff --git a/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg index 01218a1178..c1266844d0 100644 --- a/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg +++ b/hls4ml/templates/vitis_unified/workspace/sysProj/buildConfig.cfg @@ -1,2 +1,2 @@ [vivado] -gui={GUI_STATUS} \ No newline at end of file +gui={GUI_STATUS} diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 48897ce1a7..52b00604b5 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -2,8 +2,8 @@ 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_writer import VitisWriter 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 from hls4ml.writer.writers import Writer, get_writer, register_writer # noqa: F401 diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 928c95e048..790d2d1443 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -1,11 +1,8 @@ import os -from pathlib import Path -import stat -from shutil import copyfile from hls4ml.writer.vitis_writer import VitisWriter -from .meta import VitisUnifiedWriterMeta +from .meta import VitisUnifiedWriterMeta class VitisUnifiedWriter(VitisWriter): @@ -14,49 +11,50 @@ def __init__(self): super().__init__() self.writer_meta = VitisUnifiedWriterMeta() - from .build_gen import VitisUnified_BuildGen - from .driver_gen import VitisUnified_DriverGen - from .meta_gen import VitisUnified_MetaGen + from .build_gen import VitisUnified_BuildGen + from .driver_gen import VitisUnified_DriverGen + from .meta_gen import VitisUnified_MetaGen from .test_bridge_gen import VitisUnified_BridgeGen - from .test_cosim_gen import VitisUnified_TestGen - from .wrap_gen import VitisUnified_WrapperGen - - self.bg = VitisUnified_BuildGen - self.dg = VitisUnified_DriverGen - self.mg = VitisUnified_MetaGen - self.tbg = VitisUnified_BridgeGen - self.tcg = VitisUnified_TestGen - self.wg = VitisUnified_WrapperGen - - + from .test_cosim_gen import VitisUnified_TestGen + from .wrap_gen import VitisUnified_WrapperGen + self.bg = VitisUnified_BuildGen + self.dg = VitisUnified_DriverGen + self.mg = VitisUnified_MetaGen + self.tbg = VitisUnified_BridgeGen + self.tcg = VitisUnified_TestGen + self.wg = VitisUnified_WrapperGen def write_board_script_override(self, model): pass + def write_build_prj_override(self, model): pass + def write_build_opts(self, model): pass + def write_tar(self, model): pass - def write_bridge(self, model): ### test bench gen + def write_bridge(self, model): # test bench gen self.tbg.write_bridge(self.writer_meta, model, self.mg) def write_build_script(self, model): - #### for bridge simulation + # for bridge simulation self.bg.write_bridge_build_script(self.writer_meta, model, self.mg) - #### for hls kernel generation + # for hls kernel generation self.bg.build_unified_project_ske(self.writer_meta, model, self.mg) self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg, True) self.bg.write_hls_kernel_cfg(self.writer_meta, model, self.mg, False) - #### for v++ to link hls to the system + # for v++ to link hls to the system self.bg.write_launch_vitis_linker_dir(self.writer_meta, model, self.mg) self.bg.write_launch_vitis_linker_launcher(self.writer_meta, model, self.mg) self.bg.write_launch_vitis_linker_cfg(self.writer_meta, model, self.mg) def generate_config(self, model): from hls4ml.backends import VitisUnifiedConfig + self.writer_meta.vitis_unified_config = VitisUnifiedConfig( model.config, model.get_input_variables(), model.get_output_variables() ) @@ -68,26 +66,23 @@ def make_export_path(self, model): def write_hls(self, model, is_multigraph=False): - if is_multigraph: - raise Exception("Vitis Unified does not support multigraphs; however, vitis unified partial backend is please use it instead") + raise Exception( + "Vitis Unified does not support multigraphs; however, vitis unified partial backend is please use it instead" + ) - - ##### generate kernel and its driver + # generate kernel and its driver self.generate_config(model) - super().write_hls(model, is_multigraph = False) + super().write_hls(model, is_multigraph=False) self.wg.write_wrapper(self.writer_meta, model, self.mg) + self.make_export_path(model) + self.dg.write_driver(self.writer_meta, model, self.mg) + self.tcg.write_wrapper_test(self.writer_meta, model, self.mg) - ######### - self.make_export_path (model) - self.dg .write_driver (self.writer_meta, model, self.mg) - self.tcg.write_wrapper_test (self.writer_meta, model, self.mg) - - - #self.write_new_tar(model) - #if not is_multigraph: + # self.write_new_tar(model) + # if not is_multigraph: - #else: + # else: # self.write_bridge_multigraph(model) - # self.modify_write_build_script_multigraph(model) \ No newline at end of file + # self.modify_write_build_script_multigraph(model) diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index aa6da0ddfe..71f527cb93 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -2,9 +2,9 @@ import stat from pathlib import Path - from .meta import VitisUnifiedWriterMeta + class VitisUnified_BuildGen: @classmethod @@ -26,16 +26,16 @@ def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): fin.close() fout.close() - #### change permission + # change permission 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) @classmethod - def write_hls_kernel_cfg(self, meta, model, mg, is_csim = False): #### is_csim else cosim + def write_hls_kernel_cfg(self, meta, model, mg, is_csim=False): # is_csim else cosim filedir = os.path.dirname(os.path.abspath(__file__)) - sufix = "csim" if is_csim else "cosim" - fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg'), 'r') - fout = open(f"{model.config.get_output_dir()}/hls_kernel_config_{sufix}.cfg", 'w') + sufix = "csim" if is_csim else "cosim" + fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg')) + fout = open(f"{model.config.get_output_dir()}/hls_kernel_config_{sufix}.cfg", 'w') for line in fin.readlines(): if "{PART}" in line: @@ -56,8 +56,8 @@ def write_hls_kernel_cfg(self, meta, model, mg, is_csim = False): #### is_csim e line = line.replace("{FILE_NAME_BASE}", mg.get_main_file_name(model)) if "{OUTPUT_KERNEL_TYPE}" in line: line = line.replace("{OUTPUT_KERNEL_TYPE}", mg.get_output_kernel_type()) - if is_csim and ( ( "enable_fifo_sizing" in line ) or ("-DRTL_SIM" in line)): - line = "#" + line + if is_csim and (("enable_fifo_sizing" in line) or ("-DRTL_SIM" in line)): + line = "#" + line fout.write(line) @@ -65,20 +65,20 @@ def write_hls_kernel_cfg(self, meta, model, mg, is_csim = False): #### is_csim e fout.close() @classmethod - def build_unified_project_ske(self, meta, model, mg, workspaceDir = None): + def build_unified_project_ske(self, meta, model, mg, workspaceDir=None): if workspaceDir is None: workspaceDir = mg.get_vitis_unified_working_directory_dir(model) - hlsDir = mg.get_vitis_hls_dir(model) - execDir = mg.get_vitis_hls_dir(model) + hlsDir = mg.get_vitis_hls_dir(model) + execDir = mg.get_vitis_hls_dir(model) vitisComp = os.path.join(str(hlsDir), "vitis-comp.json") - ###### create my own project for this graph + # create my own project for this graph os.makedirs(workspaceDir, exist_ok=True) - os.makedirs(hlsDir , exist_ok=True) - os.makedirs(execDir , exist_ok=True) - ###### create project vitis-comp.json to + os.makedirs(hlsDir, exist_ok=True) + os.makedirs(execDir, exist_ok=True) + # create project vitis-comp.json to filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, "../../templates/vitis_unified/workspace/projectName/vitis-comp.json"), 'r') + fin = open(os.path.join(filedir, "../../templates/vitis_unified/workspace/projectName/vitis-comp.json")) fout = open(vitisComp, 'w') for line in fin.readlines(): @@ -98,7 +98,7 @@ def write_launch_vitis_linker_dir(self, meta, model, mg): @classmethod def write_launch_vitis_linker_launcher(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh'), 'r') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh')) fout = open(f"{mg.get_vitis_linker_dir(model)}/buildAcc.sh", 'w') for line in fin.readlines(): @@ -120,18 +120,18 @@ def write_launch_vitis_linker_launcher(self, meta, model, mg): @classmethod def write_launch_vitis_linker_cfg(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg'), 'r') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg')) fout = open(f"{mg.get_vitis_linker_dir(model)}/buildConfig.cfg", 'w') for line in fin.readlines(): if "{CLK}" in line: - line = line.replace("{CLK}", str(100_000_000))#model.config.get_config_value('ClockPeriod')) + line = line.replace("{CLK}", str(100_000_000)) # model.config.get_config_value('ClockPeriod')) if "{KERNEL_NAME}" in line: line = line.replace("{KERNEL_NAME}", mg.get_top_wrap_func_name(model)) if "{GUI_STATUS}" in line: line = line.replace("{GUI_STATUS}", "true") - line="" + line = "" fout.write(line) fin.close() - fout.close() \ No newline at end of file + fout.close() diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py index 0039af3cd3..3082fdb837 100644 --- a/hls4ml/writer/vitis_unified_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -1,26 +1,22 @@ import os -import stat -from pathlib import Path -from .meta import VitisUnifiedWriterMeta - class VitisUnified_DriverGen: @classmethod def write_driver(self, meta, model, mg): filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py'), 'r') - fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/driver/pynq/pynq_driver.py.hls4ml')) + fout = open(f'{model.config.get_output_dir()}/export/pynq_driver.py', 'w') inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() - strideInPtrAddr = 4*3 - strideOutPtrAddr = 4*3 + strideInPtrAddr = 4 * 3 + strideOutPtrAddr = 4 * 3 startInPtrAddr = 0x10 - startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) - startAmtQueryAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) + startOutPtrAddr = startInPtrAddr + strideInPtrAddr * len(inps) + startAmtQueryAddr = startOutPtrAddr + strideOutPtrAddr * len(outs) def genHexAddrList(startAddr, stride, size, indent): addrs = [f"{indent}{hex(startAddr + inp_idx * stride)}" for inp_idx in range(size)] @@ -34,12 +30,12 @@ def genHexAddrList(startAddr, stride, size, indent): if "REG_ADDR_AMT_QUERY" in line: line = line.replace("VAL", str(hex(startAmtQueryAddr))) if "#### hls-driver-input-dbg-name" in line: - input_names = [ f'{indentStr}"{mg.get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inps) ] + input_names = [f'{indentStr}"{mg.get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inps)] line += ",\n".join(input_names) + "\n" if "#### hls-driver-input-ptr" in line: line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" if "#### hls-driver-output-dbg-name" in line: - output_names = [ f'{indentStr}"{mg.get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outs) ] + output_names = [f'{indentStr}"{mg.get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outs)] line += ",\n".join(output_names) + "\n" if "#### hls-driver-output-ptr" in line: line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" @@ -49,4 +45,4 @@ def genHexAddrList(startAddr, stride, size, indent): fout.write(line) fin.close() - fout.close() \ No newline at end of file + fout.close() diff --git a/hls4ml/writer/vitis_unified_writer/meta.py b/hls4ml/writer/vitis_unified_writer/meta.py index 180eb6e09a..19917da0d9 100644 --- a/hls4ml/writer/vitis_unified_writer/meta.py +++ b/hls4ml/writer/vitis_unified_writer/meta.py @@ -1,7 +1,5 @@ - - class VitisUnifiedWriterMeta: def __init__(self): super().__init__() - self.vitis_unified_config = None \ No newline at end of file + self.vitis_unified_config = None diff --git a/hls4ml/writer/vitis_unified_writer/meta_gen.py b/hls4ml/writer/vitis_unified_writer/meta_gen.py index f8cdd849b0..a30a5769fd 100644 --- a/hls4ml/writer/vitis_unified_writer/meta_gen.py +++ b/hls4ml/writer/vitis_unified_writer/meta_gen.py @@ -1,15 +1,8 @@ import os -from pathlib import Path -import stat +# file and directory -from shutil import copyfile - -####################################################### -## file and directory ################################# -####################################################### - class VitisUnified_MetaGen: @classmethod @@ -17,8 +10,8 @@ def get_wrapper_file_name(self, model): return f"{model.config.get_project_name()}_dm" @classmethod - def get_sim_file_name(cls): #### false is cosim - return f"myproject_test" + def get_sim_file_name(cls): + return "myproject_test" @classmethod def get_main_file_name(self, model): @@ -51,20 +44,20 @@ def get_xo_file_name(self, model): def get_xo_file_path(self, model): return os.path.join(self.get_vitis_hls_exec_dir(model), self.get_xo_file_name(model)) - ####################################################### - ## naming of variable function helper ################# - ####################################################### + # naming of variable function helper - ####### FOR GMEM WRAPPER + # FOR GMEM WRAPPER @classmethod def get_io_port_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" return f"gmem_{ioDirect}{str(idx)}_ptr_{tensorVar.name}" + @classmethod def get_io_port_size_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" return f"gmem_{ioDirect}{str(idx)}_size_{tensorVar.name}" + @classmethod def get_local_stream_name(self, tensorVar, isInput: bool, idx: int): ioDirect = "in" if isInput else "out" @@ -87,11 +80,11 @@ def get_top_model_name(self, model): def get_top_wrap_func_name(self, model): return f"{model.config.get_project_name()}_gem" - ### it is renamed for stitch layer + # it is renamed for stitch layer @classmethod def rename_type(self, tensorVar, layerIdx: int, isInput: bool): return "result_" + tensorVar.type.name + f"_at_layer_{str(layerIdx)}" @classmethod def get_output_kernel_type(cls): - return "xo" \ No newline at end of file + return "xo" diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index bf914411b3..2d131b4b14 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -1,6 +1,8 @@ import os + from .meta import VitisUnifiedWriterMeta + class VitisUnified_BridgeGen: @classmethod @@ -36,10 +38,9 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): dtype = line.split('#', 1)[1].strip() - input_ios = [] + input_ios = [] output_ios = [] - for idx, inp in enumerate(model_inputs): input_ios.append(f"{dtype} {mg.get_io_port_name(inp, True, idx)}[{inp.size_cpp()}]") for idx, out in enumerate(model_outputs): @@ -68,15 +69,14 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): output_vars.append(mg.get_io_port_name(out, False, idx)) otuput_sizes.append(out.size_cpp()) - inputs_str = ', '.join(input_vars) + inputs_str = ', '.join(input_vars) outputs_str = ', '.join(output_vars) newline = '' newline += indent + mg.get_top_wrap_func_name(model) + "(\n" newline += indent + inputs_str + ',\n' newline += indent + outputs_str + ',\n' - newline += indent + "1);\n" ##### amount query should be one only - + newline += indent + "1);\n" # amount query should be one only elif '// hls-fpga-machine-learning insert trace_outputs' in line: newline = '' @@ -86,9 +86,9 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): vars = layer.get_variables() for var in vars: newline += ( - indent - + 'nnet::trace_outputs->insert(std::pair(' - + f'"{layer.name}", (void *) malloc({var.size_cpp()} * element_size)));\n' + 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: @@ -103,4 +103,4 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): fout.write(newline) fin.close() - fout.close() \ No newline at end of file + fout.close() diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index 71d3a6ba53..d80ad96914 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -1,5 +1,4 @@ import os -from .meta import VitisUnifiedWriterMeta class VitisUnified_TestGen: @@ -8,15 +7,13 @@ class VitisUnified_TestGen: def write_wrapper_test(self, meta, model, mg): pass - - #### warning we have to fix to float because the system locked by template inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() filedir = os.path.dirname(os.path.abspath(__file__)) - f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) + f = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_test.cpp')) fout = open(f'{model.config.get_output_dir()}/{mg.get_sim_file_name()}.cpp', 'w') - model_inputs = model.get_input_variables() + 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'] @@ -25,7 +22,7 @@ def write_wrapper_test(self, meta, model, mg): for line in f.readlines(): indent = ' ' * (len(line) - len(line.lstrip(' '))) - #Insert numbers + # Insert numbers if 'myproject' in line: newline = line.replace('myproject', model.config.get_project_name()) elif '// hls-fpga-machine-learning insert include' in line: @@ -40,22 +37,22 @@ def write_wrapper_test(self, meta, model, mg): newline = line offset = 0 for inputIdx, inp in enumerate(model_inputs): - ##### input should be float - newline += indent + 'float* {inputPortName} = &in[{startIdx}];\n'.format( ### can not be double because it fix by template + # input should be float + newline += indent + 'float* {inputPortName} = &in[{startIdx}];\n'.format( + # can not be double because it fix by template inputPortName=mg.get_io_port_name(inp, True, inputIdx), - startIdx=str(offset) + startIdx=str(offset), ) offset += inp.size() for outputIdx, out in enumerate(model_outputs): - newline += indent + f"float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\n" - + newline += indent + f"float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\n" elif '// hls-fpga-machine-learning insert top-level-function' in line: newline = line - input_ios = [] + input_ios = [] output_ios = [] - bram_ios = [b.name for b in model_brams] + bram_ios = [b.name for b in model_brams] for inpIdx, inp in enumerate(model_inputs): input_ios.append(mg.get_io_port_name(inp, True, inpIdx)) @@ -70,9 +67,9 @@ def write_wrapper_test(self, meta, model, mg): elif '// hls-fpga-machine-learning insert predictions' in line: newline = line - for outIdx, out in enumerate(model_outputs): - #newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' - #### TODO fix this size retrieve + for out in model_outputs: + # newline += indent + f'for(int i = 0; i < {out.size_cpp()}; i++) {{\n' + # TODO fix this size retrieve newline += indent + f'for(int i = 0; i < {out.size()}; i++) {{\n' newline += indent + ' std::cout << pr[i] << " ";\n' newline += indent + '}\n' @@ -88,17 +85,20 @@ def write_wrapper_test(self, meta, model, mg): 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": ### it can be both or file + if tb_stream != "stdout": # it can be both or file for outIdx, out in enumerate(model_outputs): newline += ( - indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' - .format(actualType="float", - cpysize=out.size(), - portName=mg.get_io_port_name(out, False, outIdx), - des="fout", - keepOutput="false")) + indent + + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n'.format( + actualType="float", + cpysize=out.size(), + portName=mg.get_io_port_name(out, False, outIdx), + des="fout", + keepOutput="false", + ) + ) elif ( - '// hls-fpga-machine-learning insert output' in line + '// hls-fpga-machine-learning insert output' in line or '// hls-fpga-machine-learning insert quantized' in line ): @@ -108,12 +108,16 @@ def write_wrapper_test(self, meta, model, mg): if tb_stream != "file": for outIdx, out in enumerate(model_outputs): - newline += (indent + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n' - .format( actualType = "float", - cpysize = out.size(), - portName = mg.get_io_port_name(out, False, outIdx), - des = "std::cout", - keepOutput = keep_output)) + newline += ( + indent + + 'nnet::print_result<{actualType}, {cpysize}>({portName}, {des}, {keepOutput});\n'.format( + actualType="float", + cpysize=out.size(), + portName=mg.get_io_port_name(out, False, outIdx), + des="std::cout", + keepOutput=keep_output, + ) + ) elif '// hls-fpga-machine-learning insert namespace' in line: newline = '' diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index f918f395b0..c878cf3c0c 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -1,22 +1,17 @@ import os -from pathlib import Path -import stat -from shutil import copyfile from .meta import VitisUnifiedWriterMeta -from .meta_gen import VitisUnified_MetaGen as mg -################################################################################ -###### main function ########################################################### -################################################################################ +# main function + class VitisUnified_WrapperGen: @classmethod def gen_io_str(self, mg, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): - inputPtrList = [] - outputPtrList = [] + inputPtrList = [] + outputPtrList = [] for inp_idx, inp in enumerate(inps): inputPtrList.append(f"{indent} {inp_gmem_t}* {mg.get_io_port_name(inp, True, inp_idx)}") @@ -24,8 +19,7 @@ def gen_io_str(self, mg, indent, inp_gmem_t, out_gmem_t, inps, outs, meta=None): for out_idx, out in enumerate(outs): outputPtrList.append(f"{indent} {out_gmem_t}* {mg.get_io_port_name(out, False, out_idx)}") - - line = ", ".join(inputPtrList) + ",\n" + line = ", ".join(inputPtrList) + ",\n" line += ", ".join(outputPtrList) + "\n" return line @@ -36,13 +30,11 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() indent = ' ' - ###################################### - ###### start write myproject_dm.cpp ## - ###################################### + # start write myproject_dm.cpp ## filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp'), 'r') - fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp')) + fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.cpp', 'w') for line in fin.readlines(): @@ -59,26 +51,43 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): line = self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} bundle = gmem_in{inp_idx} depth={str(inp.size())}\n" + line += ( + f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} " + f"bundle = gmem_in{inp_idx} depth={str(inp.size())}\n" + ) for out_idx, out in enumerate(outs): - line += f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} bundle = gmem_out{out_idx} depth={str(out.size())}\n" - elif "// vitis-unified-wrapper-stream-dec" in line: + line += ( + f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(out, False, out_idx)} " + f"bundle = gmem_out{out_idx} depth={str(out.size())}\n" + ) + elif "// vitis-unified-wrapper-stream-dec" in line: for inp_idx, inp in enumerate(inps): line += f"{indent} static hls::stream<{inp.type.name}> {mg.get_local_stream_name(inp, True, inp_idx)};\n" for out_idx, out in enumerate(outs): - line += f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" + line += ( + f"{indent} static hls::stream<{out.type.name}> {mg.get_local_stream_name(out, False, out_idx)};\n" + ) elif "// vitis-unified-wrapper-stream-config" in line: for inp_idx, inp in enumerate(inps): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} depth=STREAM_BUF_IN_SZ\n" + line += ( + f"#pragma HLS STREAM variable={mg.get_local_stream_name(inp, True, inp_idx)} " + f"depth=STREAM_BUF_IN_SZ\n" + ) for out_idx, out in enumerate(outs): - line += f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} depth=STREAM_BUF_OUT_SZ\n" + line += ( + f"#pragma HLS STREAM variable={mg.get_local_stream_name(out, False, out_idx)} " + f"depth=STREAM_BUF_OUT_SZ\n" + ) - elif "// vitis-unified-wrapper-load" in line: + elif "// vitis-unified-wrapper-load" in line: for inp_idx, inp in enumerate(inps): - line += f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, {mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery, {str(inp.size())});\n" - elif "// vitis-unified-wrapper-compute" in line: + line += ( + f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, " + f"{mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery, {str(inp.size())});\n" + ) + elif "// vitis-unified-wrapper-compute" in line: poolList = [] for inp_idx, inp in enumerate(inps): poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") @@ -87,22 +96,23 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): joinedIo = f",\n{indent}{indent}{indent}".join(poolList) line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" - elif "// vitis-unified-wrapper-store" in line: + elif "// vitis-unified-wrapper-store" in line: for out_idx, out in enumerate(outs): - line += f"store_result({mg.get_io_port_name(out, False, out_idx)}, {mg.get_local_stream_name(out, False, out_idx)}, amtQuery, {str(out.size())});\n" + line += ( + f"store_result({mg.get_io_port_name(out, False, out_idx)}, " + f"{mg.get_local_stream_name(out, False, out_idx)}, amtQuery, {str(out.size())});\n" + ) fout.write(line) - fin.close() fout.close() - ###################################### - ###### start write myproject_dm.h ## - ###################################### + # + # start write myproject_dm.h filedir = os.path.dirname(os.path.abspath(__file__)) - fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.h'), 'r') + fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.h')) fout = open(f'{model.config.get_output_dir()}/firmware/myproject_dm.h', 'w') for line in fin.readlines(): @@ -118,4 +128,4 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): fout.write(line) fin.close() - fout.close() \ No newline at end of file + fout.close() diff --git a/hls4ml/writer/vitis_writer.py b/hls4ml/writer/vitis_writer.py index c5038124b1..35b13c2201 100644 --- a/hls4ml/writer/vitis_writer.py +++ b/hls4ml/writer/vitis_writer.py @@ -69,9 +69,9 @@ def write_hls(self, model, is_multigraph=False): Write the HLS project. Calls the steps from VivadoWriter, adapted for Vitis """ if is_multigraph: - super().write_hls(model, is_multigraph = True) + super().write_hls(model, is_multigraph=True) return - super().write_hls(model, is_multigraph = False) + 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_backend/cmpResult.py b/test/pytest/test_backend/cmpResult.py index d5561962d9..b6753240b3 100644 --- a/test/pytest/test_backend/cmpResult.py +++ b/test/pytest/test_backend/cmpResult.py @@ -2,28 +2,23 @@ from pathlib import Path import numpy as np -from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, Concatenate -from tensorflow.keras.models import Model, load_model - -import hls4ml -import hls4ml.model test_root_path = Path(__file__).parent os.environ['XILINX_VITIS'] = "/tools/Xilinx/Vitis/2023.2" os.environ['PATH'] = os.environ['XILINX_VITIS'] + '/bin:' + os.environ['PATH'] + def checkEqual(a, b): equal = np.array_equal(a, b) if equal: - print("Test pass both are equal \U0001F642") + print("Test pass both are equal \U0001f642") else: - print("Test Fail both are not equal \U0001F62C") - + print("Test Fail both are not equal \U0001f62c") bridge_result = np.load(test_root_path / "output_file/outputGenbit.npy") -zcu_result = np.load(test_root_path / "output_file/out_hw.npy") -zcu_flat = zcu_result.reshape(zcu_result.shape[0], -1) +zcu_result = np.load(test_root_path / "output_file/out_hw.npy") +zcu_flat = zcu_result.reshape(zcu_result.shape[0], -1) print(bridge_result.shape) print(zcu_result.shape) diff --git a/test/pytest/test_backend/vitis_unified.py b/test/pytest/test_backend/vitis_unified.py index 745289e345..4651540ce0 100644 --- a/test/pytest/test_backend/vitis_unified.py +++ b/test/pytest/test_backend/vitis_unified.py @@ -1,14 +1,20 @@ +import os from pathlib import Path import numpy as np import pytest -import os +from tensorflow.keras.layers import ( + Concatenate, + Conv2D, + Input, + MaxPooling2D, + UpSampling2D, +) +from tensorflow.keras.models import Model, load_model + import hls4ml import hls4ml.model -from tensorflow.keras.layers import Activation, Dense, GlobalAveragePooling1D, Input, Conv2D, MaxPooling2D, UpSampling2D, Concatenate -from tensorflow.keras.models import Model, load_model - test_root_path = Path(__file__).parent os.environ['XILINX_VITIS'] = "/tools/Xilinx/Vitis/2023.2" @@ -16,7 +22,7 @@ def create_io_file_dir(): - os.makedirs(test_root_path / "input_file" , exist_ok=True) + os.makedirs(test_root_path / "input_file", exist_ok=True) os.makedirs(test_root_path / "output_file", exist_ok=True) @@ -24,18 +30,19 @@ def checkEqual(a, b): equal = np.array_equal(a, b) if equal: - print("Test pass both are equal \U0001F642") + print("Test pass both are equal \U0001f642") else: - print("Test Fail both are not equal \U0001F62C") + print("Test Fail both are not equal \U0001f62c") return equal -def create_simple_testcase(inputShape=(4, 4, 1), fileName = "inputX.npy"): +def create_simple_testcase(inputShape=(4, 4, 1), fileName="inputX.npy"): n_in = np.random.rand(*inputShape).astype(np.float32) - os.makedirs(test_root_path/ "input_file", exist_ok=True) - np.save(test_root_path/ "input_file" / fileName, n_in) + os.makedirs(test_root_path / "input_file", exist_ok=True) + np.save(test_root_path / "input_file" / fileName, n_in) -def create_simple_unet(input_shape=(4, 4, 1), modelName = "simpleSkip.keras"): + +def create_simple_unet(input_shape=(4, 4, 1), modelName="simpleSkip.keras"): inputs = Input(input_shape) # Encoder c1 = Conv2D(2, (3, 3), activation='relu', padding='same')(inputs) @@ -50,39 +57,53 @@ def create_simple_unet(input_shape=(4, 4, 1), modelName = "simpleSkip.keras"): outputs = Conv2D(1, (1, 1), activation='sigmoid')(c2) model = Model(inputs, outputs) model.compile(optimizer='adam', loss='binary_crossentropy') - model.save(test_root_path/ "input_file" / modelName) + model.save(test_root_path / "input_file" / modelName) def gen_prj_dir(backend, io_type, strategy, granularity, prefix): - return str( - test_root_path - / f"hls4mlprj_{prefix}_{backend}_{strategy}_{io_type}_{granularity}" - ) + return str(test_root_path / f"hls4mlprj_{prefix}_{backend}_{strategy}_{io_type}_{granularity}") def create_hls_model(model, config, backend, io_type, strategy, granularity, prefix): output_dir = gen_prj_dir(backend, io_type, strategy, granularity, prefix) - ############### mono model build + # mono model build hls_model = hls4ml.converters.convert_from_keras_model( - model, hls_config=config, output_dir=output_dir, backend=backend, io_type=io_type, - board='zcu102', part='xczu9eg-ffvb1156-2-e', clock_period='10ns', - input_type="float", output_type="float" + model, + hls_config=config, + output_dir=output_dir, + backend=backend, + io_type=io_type, + board='zcu102', + part='xczu9eg-ffvb1156-2-e', + clock_period='10ns', + input_type="float", + output_type="float", ) hls_model.compile() return hls_model + def create_hls_model4_cosim(model, config, backend, io_type, strategy, granularity, input_data_tb, output_data_tb, prefix): output_dir = gen_prj_dir(backend, io_type, strategy, granularity, prefix) - ############### mono model build + # mono model build hls_model = hls4ml.converters.convert_from_keras_model( - model, hls_config=config, output_dir=output_dir, backend=backend, io_type=io_type, - board='zcu102', part='xczu9eg-ffvb1156-2-e', clock_period='10ns', - input_type="float", output_type="float", - input_data_tb = input_data_tb, output_data_tb = output_data_tb + model, + hls_config=config, + output_dir=output_dir, + backend=backend, + io_type=io_type, + board='zcu102', + part='xczu9eg-ffvb1156-2-e', + clock_period='10ns', + input_type="float", + output_type="float", + input_data_tb=input_data_tb, + output_data_tb=output_data_tb, ) hls_model.compile() return hls_model + def predict_hls_model(hls_model, input_data): y_hls4ml = hls_model.predict(input_data) return y_hls4ml @@ -94,67 +115,75 @@ def predict_hls_model(hls_model, input_data): @pytest.mark.parametrize('amt_query', [10]) def test_backend_predict(io_type, strategy, granularity, amt_query): create_io_file_dir() - #### create and load data set - create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName = "inputX.npy") - input_data = np.load(test_root_path/ "input_file" / "inputX.npy") - #### create and load model + # create and load data set + create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputX.npy") + input_data = np.load(test_root_path / "input_file" / "inputX.npy") + # create and load model model_name = "simpleSkip.keras" - create_simple_unet(modelName = model_name) - model = load_model(test_root_path/ "input_file" / model_name) - #### config the keras model + create_simple_unet(modelName=model_name) + model = load_model(test_root_path / "input_file" / model_name) + # config the keras model config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) - #### create hls4ml model + # create hls4ml model vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "bridge") - vitis_model = create_hls_model(model, config, "Vitis", io_type, strategy, granularity, "bridge") + vitis_model = create_hls_model(model, config, "Vitis", io_type, strategy, granularity, "bridge") - #### predict test + # predict test y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) - y_hls4ml = predict_hls_model(vitis_model, input_data) + y_hls4ml = predict_hls_model(vitis_model, input_data) assert checkEqual(y_hls4ml_unified, y_hls4ml), "the result from vitis unified and vitis are not equal!" + @pytest.mark.parametrize('io_type', ['io_stream']) @pytest.mark.parametrize('strategy', ['latency']) @pytest.mark.parametrize('granularity', ['name']) @pytest.mark.parametrize('amt_query', [10]) def test_co_simulation(io_type, strategy, granularity, amt_query): create_io_file_dir() - #### create and load data set + # create and load data set create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputCosim.npy") input_data = np.load(test_root_path / "input_file" / "inputCosim.npy") - #### create and load model + # create and load model model_name = "simpleSkipCosim.keras" create_simple_unet(modelName=model_name) model = load_model(test_root_path / "input_file" / model_name) - #### config the keras model + # config the keras model config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) - #### predict it first + # predict it first vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "precosim") y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) - np.save(test_root_path/ "output_file" / "outputCosim.npy", y_hls4ml_unified) + np.save(test_root_path / "output_file" / "outputCosim.npy", y_hls4ml_unified) - input_data_tb = str(test_root_path / "input_file" / f"inputCosim.npy") - output_data_tb = str(test_root_path / "output_file" / f"outputCosim.npy") + input_data_tb = str(test_root_path / "input_file" / "inputCosim.npy") + output_data_tb = str(test_root_path / "output_file" / "outputCosim.npy") - #### create hls4ml model - vitis_unified_model_cosim = create_hls_model4_cosim(model, config, "VitisUnified", io_type, - strategy, granularity,input_data_tb, output_data_tb, "cosim") - #### do cosim + # create hls4ml model + vitis_unified_model_cosim = create_hls_model4_cosim( + model, config, "VitisUnified", io_type, strategy, granularity, input_data_tb, output_data_tb, "cosim" + ) + # do cosim vitis_unified_model_cosim.compile() vitis_unified_model_cosim.build(synth=True, cosim=True) - bridge_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/tb_output_predictions.dat" - cosim_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/rtl_cosim_results.log" + bridge_result_path = ( + gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/tb_output_predictions.dat" + ) + cosim_result_path = ( + gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/rtl_cosim_results.log" + ) bridge_result = np.loadtxt(bridge_result_path) - cosim_result = np.loadtxt(cosim_result_path) + cosim_result = np.loadtxt(cosim_result_path) assert np.allclose(bridge_result, cosim_result, rtol=0.0, atol=1e-4), "the result from bridge and cosim are not equal!" -#test_co_simulation("io_stream", 'latency', 'name', 10) + +# test_co_simulation("io_stream", 'latency', 'name', 10) + @pytest.mark.parametrize('io_type', ['io_stream']) @pytest.mark.parametrize('strategy', ['latency']) @@ -162,37 +191,37 @@ def test_co_simulation(io_type, strategy, granularity, amt_query): @pytest.mark.parametrize('amt_query', [10]) def test_fifo_depth(io_type, strategy, granularity, amt_query): create_io_file_dir() - #### create and load data set + # create and load data set create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputFifoDepth.npy") input_data = np.load(test_root_path / "input_file" / "inputFifoDepth.npy") - #### create and load model + # create and load model model_name = "simpleSkipFifoDepth.keras" create_simple_unet(modelName=model_name) model = load_model(test_root_path / "input_file" / model_name) - #### config the keras model + # config the keras model config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) - #### predict it first + # predict it first vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "fifodepth") y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) - np.save(test_root_path/ "output_file" / "outputFifoDepth.npy", y_hls4ml_unified) + np.save(test_root_path / "output_file" / "outputFifoDepth.npy", y_hls4ml_unified) - input_data_tb = str(test_root_path / "input_file" / f"inputFifoDepth.npy") - output_data_tb = str(test_root_path / "output_file" / f"outputFifoDepth.npy") + input_data_tb = str(test_root_path / "input_file" / "inputFifoDepth.npy") + output_data_tb = str(test_root_path / "output_file" / "outputFifoDepth.npy") - #### create hls4ml model + # create hls4ml model config['Flows'] = ['vitisunified:fifo_depth_optimization'] - vitis_unified_model_fifo = create_hls_model4_cosim(model, config, "VitisUnified", io_type, - strategy, granularity,input_data_tb, output_data_tb, "fifodepth") - #### do cosim + vitis_unified_model_fifo = create_hls_model4_cosim( + model, config, "VitisUnified", io_type, strategy, granularity, input_data_tb, output_data_tb, "fifodepth" + ) + # do cosim vitis_unified_model_fifo.compile() fifodepth_result_path = gen_prj_dir("VitisUnified", io_type, strategy, granularity, "fifodepth") + "/fifo_depths.json" assert os.path.exists(fifodepth_result_path), "the fifo_depth file is not exist" - -#test_fifo_depth("io_stream", 'latency', 'name', 10) +# test_fifo_depth("io_stream", 'latency', 'name', 10) @pytest.mark.parametrize('io_type', ['io_stream']) @@ -201,22 +230,23 @@ def test_fifo_depth(io_type, strategy, granularity, amt_query): @pytest.mark.parametrize('amt_query', [10000]) def test_gen_unified(io_type, strategy, granularity, amt_query): create_io_file_dir() - #### create and load data set + # create and load data set create_simple_testcase(inputShape=(amt_query, 4, 4, 1), fileName="inputGenbit.npy") input_data = np.load(test_root_path / "input_file" / "inputGenbit.npy") - #### create and load model + # create and load model model_name = "simpleSkipGenBit.keras" create_simple_unet(modelName=model_name) model = load_model(test_root_path / "input_file" / model_name) - #### config the keras model + # config the keras model config = hls4ml.utils.config_from_keras_model(model, granularity=granularity) - #### predict it first + # predict it first vitis_unified_model = create_hls_model(model, config, "VitisUnified", io_type, strategy, granularity, "gen_unified") y_hls4ml_unified = predict_hls_model(vitis_unified_model, input_data) - np.save(test_root_path/ "output_file" / "outputGenbit.npy", y_hls4ml_unified) + np.save(test_root_path / "output_file" / "outputGenbit.npy", y_hls4ml_unified) vitis_unified_model.compile() vitis_unified_model.build(synth=True, bitfile=True) -#test_gen_unified("io_stream", 'latency', 'name', 10000) \ No newline at end of file + +# test_gen_unified("io_stream", 'latency', 'name', 10000) From 48d750064210464e8798e434a1ad2ed8798d1195 Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 2 Sep 2025 20:19:35 +0700 Subject: [PATCH 69/70] fix vitisConfig missign (after refactor) add comment --- .../passes/fifo_depth_optimization.py | 2 +- .../vitis_unified/vitis_unified_backend.py | 3 ++- .../vitis_unified/vitis_unified_config.py | 5 +++++ hls4ml/writer/vitis_unified_writer/__init__.py | 2 +- hls4ml/writer/vitis_unified_writer/build_gen.py | 8 +++++++- .../writer/vitis_unified_writer/driver_gen.py | 8 ++++---- .../vitis_unified_writer/test_bridge_gen.py | 6 +++++- .../vitis_unified_writer/test_cosim_gen.py | 8 +++++++- hls4ml/writer/vitis_unified_writer/wrap_gen.py | 17 +++++++++++++++-- test/pytest/test_backend/vitis_unified.py | 11 +++++++++-- 10 files changed, 56 insertions(+), 14 deletions(-) diff --git a/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py index d8e75862cd..0451270ca1 100644 --- a/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py +++ b/hls4ml/backends/vitis_unified/passes/fifo_depth_optimization.py @@ -66,7 +66,7 @@ def execute_cosim_to_profile_fifos(model): vsynth=False, fifo_opt=True, bitfile=False, - log_to_stdout=True, + log_to_stdout=False, ) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_backend.py b/hls4ml/backends/vitis_unified/vitis_unified_backend.py index 8c5fdad829..8bfed0f88a 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_backend.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_backend.py @@ -90,7 +90,8 @@ def build( # util template (used in csim/cosim/package) util_command = "vitis-run --mode hls --{op} --config {configPath} --work_dir unifiedPrj" - # package command + + # command for each configuration package_cmd = util_command.format(op="package", configPath=hls_config_file) package_cwd = mg.get_vitis_hls_dir(model) diff --git a/hls4ml/backends/vitis_unified/vitis_unified_config.py b/hls4ml/backends/vitis_unified/vitis_unified_config.py index 0b262de502..8f3289931e 100644 --- a/hls4ml/backends/vitis_unified/vitis_unified_config.py +++ b/hls4ml/backends/vitis_unified/vitis_unified_config.py @@ -4,12 +4,17 @@ def __init__(self, config, model_inputs, model_outputs): self.config = config.config self.board = self.config.get('UnifiedConfig', {}).get('Board', 'pynq-z2') + # before first and afterlast layer we have the configuratble buffer + # [platform]<-->[in_steram_bufferSz]<-->[hls]<-->[out_stream_bufferSz]<-->[platform] self.in_steram_bufferSz = self.config["UnifiedConfig"]["in_stream_buf_Size"] self.out_stream_bufferSz = self.config["UnifiedConfig"]["out_stream_buf_Size"] + # the path to the generated platform self.XPFMPath = self.config["UnifiedConfig"]["XPFMPath"] self.driver = self.config['UnifiedConfig']['Driver'] + + # c++ type for input and output of the hls kernel it must be str (float/double) self.input_type = self.config['UnifiedConfig']['InputDtype'] self.output_type = self.config['UnifiedConfig']['OutputDtype'] diff --git a/hls4ml/writer/vitis_unified_writer/__init__.py b/hls4ml/writer/vitis_unified_writer/__init__.py index 790d2d1443..51a0c2fba7 100644 --- a/hls4ml/writer/vitis_unified_writer/__init__.py +++ b/hls4ml/writer/vitis_unified_writer/__init__.py @@ -1,5 +1,6 @@ import os +from hls4ml.backends.vitis_unified.vitis_unified_config import VitisUnifiedConfig from hls4ml.writer.vitis_writer import VitisWriter from .meta import VitisUnifiedWriterMeta @@ -53,7 +54,6 @@ def write_build_script(self, model): self.bg.write_launch_vitis_linker_cfg(self.writer_meta, model, self.mg) def generate_config(self, model): - from hls4ml.backends import VitisUnifiedConfig self.writer_meta.vitis_unified_config = VitisUnifiedConfig( model.config, model.get_input_variables(), model.get_output_variables() diff --git a/hls4ml/writer/vitis_unified_writer/build_gen.py b/hls4ml/writer/vitis_unified_writer/build_gen.py index 71f527cb93..9abbc99f73 100644 --- a/hls4ml/writer/vitis_unified_writer/build_gen.py +++ b/hls4ml/writer/vitis_unified_writer/build_gen.py @@ -31,7 +31,9 @@ def write_bridge_build_script(self, meta: VitisUnifiedWriterMeta, model, mg): build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC) @classmethod - def write_hls_kernel_cfg(self, meta, model, mg, is_csim=False): # is_csim else cosim + def write_hls_kernel_cfg(self, meta, model, mg, is_csim=False): # True is_csim else is cosim+fifo_optimization + # This will gen hls_kernel_config_.cfg file which Vitis_hls unified will use it to config + # the synthesizer filedir = os.path.dirname(os.path.abspath(__file__)) sufix = "csim" if is_csim else "cosim" fin = open(os.path.join(filedir, '../../templates/vitis_unified/hls_kernel_config.cfg')) @@ -66,6 +68,8 @@ def write_hls_kernel_cfg(self, meta, model, mg, is_csim=False): # is_csim else @classmethod def build_unified_project_ske(self, meta, model, mg, workspaceDir=None): + # this will generate the vitis-comp.json file, the file will enable vitis ide gui to see it + # as a project if workspaceDir is None: workspaceDir = mg.get_vitis_unified_working_directory_dir(model) hlsDir = mg.get_vitis_hls_dir(model) @@ -97,6 +101,7 @@ def write_launch_vitis_linker_dir(self, meta, model, mg): @classmethod def write_launch_vitis_linker_launcher(self, meta, model, mg): + # This section generate buildAcc.sh file to combine the platform and the hls kernel together filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildAcc.sh')) fout = open(f"{mg.get_vitis_linker_dir(model)}/buildAcc.sh", 'w') @@ -119,6 +124,7 @@ def write_launch_vitis_linker_launcher(self, meta, model, mg): @classmethod def write_launch_vitis_linker_cfg(self, meta, model, mg): + # this will generate the config file that linker (platform + vitis) filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/workspace/sysProj/buildConfig.cfg')) fout = open(f"{mg.get_vitis_linker_dir(model)}/buildConfig.cfg", 'w') diff --git a/hls4ml/writer/vitis_unified_writer/driver_gen.py b/hls4ml/writer/vitis_unified_writer/driver_gen.py index 3082fdb837..e8e6ef3088 100644 --- a/hls4ml/writer/vitis_unified_writer/driver_gen.py +++ b/hls4ml/writer/vitis_unified_writer/driver_gen.py @@ -29,15 +29,15 @@ def genHexAddrList(startAddr, stride, size, indent): if "REG_ADDR_AMT_QUERY" in line: line = line.replace("VAL", str(hex(startAmtQueryAddr))) - if "#### hls-driver-input-dbg-name" in line: + if "# hls-driver-input-dbg-name" in line: input_names = [f'{indentStr}"{mg.get_io_port_name(inp, True, idx)}"' for idx, inp in enumerate(inps)] line += ",\n".join(input_names) + "\n" - if "#### hls-driver-input-ptr" in line: + if "# hls-driver-input-ptr" in line: line += ",\n".join(genHexAddrList(startInPtrAddr, strideInPtrAddr, len(inps), indentStr)) + "\n" - if "#### hls-driver-output-dbg-name" in line: + if "# hls-driver-output-dbg-name" in line: output_names = [f'{indentStr}"{mg.get_io_port_name(out, False, idx)}"' for idx, out in enumerate(outs)] line += ",\n".join(output_names) + "\n" - if "#### hls-driver-output-ptr" in line: + if "# hls-driver-output-ptr" in line: line += ",\n".join(genHexAddrList(startOutPtrAddr, strideOutPtrAddr, len(outs), indentStr)) + "\n" if "" in line: line = line.replace("", mg.get_top_wrap_func_name(model)) diff --git a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py index 2d131b4b14..999ebe9818 100644 --- a/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_bridge_gen.py @@ -35,7 +35,8 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): newline += f'#include \"firmware/weights/{bram.name}.h\"\n' elif '// hls-fpga-machine-learning insert header' in line: - + # this section will write the function arment composed of input and output of hls kernel + # for both myproject_float and myproject_double dtype = line.split('#', 1)[1].strip() input_ios = [] @@ -54,6 +55,9 @@ def write_bridge(self, meta: VitisUnifiedWriterMeta, model, mg): newline += indent + outputs_str + '\n' elif '// hls-fpga-machine-learning insert wrapper' in line: + + # This section will write the calling function to main kernel + dtype = line.split('#', 1)[1].strip() if dtype == meta.vitis_unified_config.get_input_type(): newline = '' diff --git a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py index d80ad96914..f9f6fe4be5 100644 --- a/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py +++ b/hls4ml/writer/vitis_unified_writer/test_cosim_gen.py @@ -34,6 +34,8 @@ def write_wrapper_test(self, meta, model, mg): newline += f'#include \"firmware/weights/{bram.name}.h\"\n' elif '// hls-fpga-machine-learning insert data' in line: + # This section will convert the input which stored in vector to the float pointer + # the float pointer will point to the start section of for each input for newline = line offset = 0 for inputIdx, inp in enumerate(model_inputs): @@ -44,10 +46,14 @@ def write_wrapper_test(self, meta, model, mg): startIdx=str(offset), ) offset += inp.size() + # This section will declare float arrays used to store input from output layer for outputIdx, out in enumerate(model_outputs): newline += indent + f"float {mg.get_io_port_name(out, False, outputIdx)}[{out.size()}];\n" elif '// hls-fpga-machine-learning insert top-level-function' in line: + + # This function will invoke the _dm.cpp which is the wrapper of the system + newline = line input_ios = [] @@ -68,8 +74,8 @@ def write_wrapper_test(self, meta, model, mg): 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_cpp()}; i++) {{\n' # TODO fix this size retrieve + newline += indent + f'for(int i = 0; i < {out.size()}; i++) {{\n' newline += indent + ' std::cout << pr[i] << " ";\n' newline += indent + '}\n' diff --git a/hls4ml/writer/vitis_unified_writer/wrap_gen.py b/hls4ml/writer/vitis_unified_writer/wrap_gen.py index c878cf3c0c..59b21a49c3 100644 --- a/hls4ml/writer/vitis_unified_writer/wrap_gen.py +++ b/hls4ml/writer/vitis_unified_writer/wrap_gen.py @@ -30,7 +30,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): inp_gmem_t, out_gmem_t, inps, outs = meta.vitis_unified_config.get_corrected_types() indent = ' ' - # start write myproject_dm.cpp ## + # start write myproject_dm.cpp filedir = os.path.dirname(os.path.abspath(__file__)) fin = open(os.path.join(filedir, '../../templates/vitis_unified/myproject_dm.cpp')) @@ -50,6 +50,15 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): elif "// vitis-unified-wrapper-io" in line: line = self.gen_io_str(mg, indent, inp_gmem_t, out_gmem_t, inps, outs) + "\n" elif "// vitis-unified-wrapper-interface" in line: + # This section will generate the pragma to specify interface type + # --> axi master (memory read input) + # --> axi master (memory write output) + # BOTH IS MASTER + # Please note that gmem_in/out depth size must match with the cosim array allocation + # if the cosim allocation is larger than depth, the result will not correct + # if the cosim allocation is lower than depth, the result is correct, + # but the system will throw segment falut error + # the depth size will not impact the resource usage in hls generation for inp_idx, inp in enumerate(inps): line += ( f"#pragma HLS INTERFACE m_axi port={mg.get_io_port_name(inp, True, inp_idx)} " @@ -61,7 +70,8 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): f"bundle = gmem_out{out_idx} depth={str(out.size())}\n" ) elif "// vitis-unified-wrapper-stream-dec" in line: - + # this declare the stream buffer that axi master read will store the input and axi master write + # will retrieve the output for inp_idx, inp in enumerate(inps): line += f"{indent} static hls::stream<{inp.type.name}> {mg.get_local_stream_name(inp, True, inp_idx)};\n" for out_idx, out in enumerate(outs): @@ -82,12 +92,14 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): ) elif "// vitis-unified-wrapper-load" in line: + # this call the load_input function to convert axi_master read to axi stream (buffer) for inp_idx, inp in enumerate(inps): line += ( f"load_input({mg.get_io_port_name(inp, True, inp_idx)}, " f"{mg.get_local_stream_name(inp, True, inp_idx)}, amtQuery, {str(inp.size())});\n" ) elif "// vitis-unified-wrapper-compute" in line: + # poolList = [] for inp_idx, inp in enumerate(inps): poolList.append(f"{mg.get_local_stream_name(inp, True, inp_idx)}") @@ -97,6 +109,7 @@ def write_wrapper(self, meta: VitisUnifiedWriterMeta, model, mg): line += f"{indent} {mg.get_top_model_name(model)}({joinedIo});\n" elif "// vitis-unified-wrapper-store" in line: + # this call the store_result function to convert axi_master read to axi stream (buffer) for out_idx, out in enumerate(outs): line += ( f"store_result({mg.get_io_port_name(out, False, out_idx)}, " diff --git a/test/pytest/test_backend/vitis_unified.py b/test/pytest/test_backend/vitis_unified.py index 4651540ce0..04f445021c 100644 --- a/test/pytest/test_backend/vitis_unified.py +++ b/test/pytest/test_backend/vitis_unified.py @@ -20,6 +20,9 @@ os.environ['XILINX_VITIS'] = "/tools/Xilinx/Vitis/2023.2" os.environ['PATH'] = os.environ['XILINX_VITIS'] + '/bin:' + os.environ['PATH'] +XPFM_PATH = "/tools/Xilinx/Vitis/2023.2/base_platforms/" "xilinx_zcu102_base_202320_1/xilinx_zcu102_base_202320_1.xpfm" +LOG_STD = True + def create_io_file_dir(): os.makedirs(test_root_path / "input_file", exist_ok=True) @@ -78,6 +81,7 @@ def create_hls_model(model, config, backend, io_type, strategy, granularity, pre clock_period='10ns', input_type="float", output_type="float", + xpfmPath=XPFM_PATH, ) hls_model.compile() return hls_model @@ -137,6 +141,9 @@ def test_backend_predict(io_type, strategy, granularity, amt_query): assert checkEqual(y_hls4ml_unified, y_hls4ml), "the result from vitis unified and vitis are not equal!" +# test_backend_predict("io_stream", 'latency', 'name', 10) + + @pytest.mark.parametrize('io_type', ['io_stream']) @pytest.mark.parametrize('strategy', ['latency']) @pytest.mark.parametrize('granularity', ['name']) @@ -167,7 +174,7 @@ def test_co_simulation(io_type, strategy, granularity, amt_query): ) # do cosim vitis_unified_model_cosim.compile() - vitis_unified_model_cosim.build(synth=True, cosim=True) + vitis_unified_model_cosim.build(synth=True, cosim=True, log_to_stdout=LOG_STD) bridge_result_path = ( gen_prj_dir("VitisUnified", io_type, strategy, granularity, "cosim") + "/tb_data/tb_output_predictions.dat" @@ -246,7 +253,7 @@ def test_gen_unified(io_type, strategy, granularity, amt_query): np.save(test_root_path / "output_file" / "outputGenbit.npy", y_hls4ml_unified) vitis_unified_model.compile() - vitis_unified_model.build(synth=True, bitfile=True) + vitis_unified_model.build(synth=True, bitfile=True, log_to_stdout=LOG_STD) # test_gen_unified("io_stream", 'latency', 'name', 10000) From 0feaf32220c98b6de53e9c34f2c8241cedfe45fc Mon Sep 17 00:00:00 2001 From: tanawin Date: Tue, 2 Sep 2025 23:24:39 +0700 Subject: [PATCH 70/70] fix ciricular import again --- hls4ml/backends/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 599d875c64..3bb8aa7c6d 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -3,7 +3,6 @@ from hls4ml.backends.oneapi.oneapi_backend import OneAPIBackend from hls4ml.backends.quartus.quartus_backend import QuartusBackend from hls4ml.backends.symbolic.symbolic_backend import SymbolicExpressionBackend -from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend from hls4ml.backends.vivado.vivado_backend import VivadoBackend from hls4ml.backends.vivado_accelerator.vivado_accelerator_backend import VivadoAcceleratorBackend from hls4ml.backends.vivado_accelerator.vivado_accelerator_config import VivadoAcceleratorConfig # noqa: F401 @@ -12,6 +11,8 @@ from hls4ml.backends.vitis.vitis_backend import VitisBackend # isort: skip +from hls4ml.backends.vitis_unified.vitis_unified_backend import VitisUnifiedBackend # isort: skip + register_backend('Vivado', VivadoBackend) register_backend('VivadoAccelerator', VivadoAcceleratorBackend)