From 17541c4125bf11641b6eff6b5a1fc69f808e0725 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 14 Jul 2024 15:19:39 -0700 Subject: [PATCH 1/4] 1st draft of the Vitis Unified HLS scripts --- system_vitis_unified_hls.mk | 122 ++++++++++++++++++++++++++++++++++++ vitis/hls/build.py | 41 ++++++++++++ vitis/hls/create_proj.py | 63 +++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 system_vitis_unified_hls.mk create mode 100644 vitis/hls/build.py create mode 100644 vitis/hls/create_proj.py diff --git a/system_vitis_unified_hls.mk b/system_vitis_unified_hls.mk new file mode 100644 index 0000000..9f468a4 --- /dev/null +++ b/system_vitis_unified_hls.mk @@ -0,0 +1,122 @@ +############################################################################## +## This file is part of 'SLAC Firmware Standard Library'. +## It is subject to the license terms in the LICENSE.txt file found in the +## top-level directory of this distribution and at: +## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +## No part of 'SLAC Firmware Standard Library', including this file, +## may be copied, modified, propagated, or distributed except according to +## the terms contained in the LICENSE.txt file. +############################################################################## + +# Detect project name +ifndef PROJECT +export PROJECT = $(notdir $(PWD)) +endif + +# Detect project path +ifndef PROJ_DIR +export PROJ_DIR = $(abspath $(PWD)) +endif + +# Project Build Directory +ifndef OUT_DIR +export OUT_DIR = $(abspath $(TOP_DIR)/build/$(PROJECT)) +endif + +# Synthesis Variables +export VIVADO_VERSION = $(shell vivado -version | grep -Po "v(\d+\.)+\d+" | cut -c2-) +export RUCKUS_DIR = $(TOP_DIR)/submodules/ruckus +export SOURCE_DEPEND = $(OUT_DIR)/$(PROJECT)_sources.txt + +# Source Files +ifndef SRC_FILE +export SRC_FILE = $(PROJ_DIR)/sources.tcl +endif + +# Specifies the export configurations +ifndef EXPORT_VENDOR +export EXPORT_VENDOR = SLAC +endif +ifndef EXPORT_VERSION +export EXPORT_VERSION = 1.0 +endif + +# Update legacy "PRJ_VERSION" variable +export PRJ_VERSION = v$(EXPORT_VERSION) + +# Specifies if we need to modify the ip/component.xml to support "all" FPGA family types +ifndef ALL_XIL_FAMILY +export ALL_XIL_FAMILY = 0 +endif + +include $(TOP_DIR)/submodules/ruckus/system_shared.mk + +.PHONY : all +all: target + +############################################################### +#### Printout Env. Variables ################################## +############################################################### +.PHONY : test +test: + @echo VIVADO_VERSION: $(VIVADO_VERSION) + @echo PROJECT: $(PROJECT) + @echo PROJ_DIR: $(PROJ_DIR) + @echo TOP_DIR: $(TOP_DIR) + @echo OUT_DIR: $(OUT_DIR) + @echo RUCKUS_DIR: $(RUCKUS_DIR) + @echo BUILD_STRING: $${BUILD_STRING} + @echo GIT_HASH_LONG: $(GIT_HASH_LONG) + @echo GIT_HASH_SHORT: $(GIT_HASH_SHORT) + +############################################################### +#### Build Location ########################################### +############################################################### +.PHONY : proj +proj: + $(call ACTION_HEADER,"Vitis HLS Create Project") + @test -d $(TOP_DIR)/build/ || { \ + echo ""; \ + echo "Build directory missing!"; \ + echo "You must create a build directory at the top level."; \ + echo ""; \ + echo "This directory can either be a normal directory:"; \ + echo " mkdir $(TOP_DIR)/build"; \ + echo ""; \ + echo "Or by creating a symbolic link to a directory on another disk:"; \ + echo " ln -s /tmp/build $(TOP_DIR)/build"; \ + echo ""; false; } + @test -d $(OUT_DIR) || mkdir $(OUT_DIR) + @test -d $(PROJ_DIR)/ip || mkdir $(PROJ_DIR)/ip + @cd $(OUT_DIR); vitis -s $(RUCKUS_DIR)/vitis/hls/create_proj.py + +############################################################### +#### Vitis HLS Batch Build Mode ############################### +############################################################### +.PHONY : build +build : proj + $(call ACTION_HEADER,"Vitis HLS Build") + @cd $(OUT_DIR); vitis -s $(RUCKUS_DIR)/vitis/hls/build.py + +############################################################### +#### Vitis HLS Interactive #################################### +############################################################### +.PHONY : interactive +interactive : proj + $(call ACTION_HEADER,"Vitis HLS Interactive") + @cd $(OUT_DIR); vitis -i + +############################################################### +#### Vitis HLS Gui ############################################ +############################################################### +.PHONY : gui +gui : proj + $(call ACTION_HEADER,"Vitis Unified IDE") + @cd $(OUT_DIR); vitis -w $(OUT_DIR) + +############################################################### +#### Clean #################################################### +############################################################### +.PHONY : clean +clean: + rm -rf $(OUT_DIR) diff --git a/vitis/hls/build.py b/vitis/hls/build.py new file mode 100644 index 0000000..4d381de --- /dev/null +++ b/vitis/hls/build.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +############################################################################## +## This file is part of 'SLAC Firmware Standard Library'. +## It is subject to the license terms in the LICENSE.txt file found in the +## top-level directory of this distribution and at: +## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +## No part of 'SLAC Firmware Standard Library', including this file, +## may be copied, modified, propagated, or distributed except according to +## the terms contained in the LICENSE.txt file. +############################################################################## + +import vitis +import os + +# Project variables +workspace = os.getenv("OUT_DIR") +comp_name = os.getenv("PROJECT") + +# Create a client object +client = vitis.create_client() + +# Set workspace +client.set_workspace(workspace) + +# Set the component +hls_test_comp = client.get_component(comp_name) + +# Run c-simulation on the component +hls_test_comp.run('C_SIMULATION') + +# Run synthesis on the component +hls_test_comp.run('SYNTHESIS') + +# Run co-simulation on the component +hls_test_comp.run('CO_SIMULATION') + +# Run package on the component +hls_test_comp.run('PACKAGE') + +# Close the client connection and terminate the vitis server +vitis.dispose() diff --git a/vitis/hls/create_proj.py b/vitis/hls/create_proj.py new file mode 100644 index 0000000..81aaee6 --- /dev/null +++ b/vitis/hls/create_proj.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +############################################################################## +## This file is part of 'SLAC Firmware Standard Library'. +## It is subject to the license terms in the LICENSE.txt file found in the +## top-level directory of this distribution and at: +## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +## No part of 'SLAC Firmware Standard Library', including this file, +## may be copied, modified, propagated, or distributed except according to +## the terms contained in the LICENSE.txt file. +############################################################################## + +import vitis +import os +import shutil + +# Project variables +workspace = os.getenv("OUT_DIR") +comp_name = os.getenv("PROJECT") +cfg_file = f'{os.getenv("PROJ_DIR")}/hls_config.cfg' +cfg_copy = os.path.join(workspace, os.path.basename(cfg_file)) + +# Verify that the configuration file exists +if not os.path.exists(cfg_file): + raise FileNotFoundError(f"The configuration file {cfg_file} does not exist.") + +# Check if the previous cfg_file copy exists +if not os.path.exists(cfg_copy): + diffCheck = 1 # Force project creation +else: + diffCheck = os.system(f'diff {cfg_file} {cfg_copy} >/dev/null 2>&1') + +# Check for any changes in cfg_file +if diffCheck > 0: + + # Create a client object + client = vitis.create_client() + + # Delete the workspace if already exists. + if (os.path.isdir(workspace)): + shutil.rmtree(workspace) + print( f'Deleted workspace {workspace}' ) + + # Set workspace + client.set_workspace(workspace) + + # Get config file object + script_dir = os.path.dirname(os.path.abspath(__file__)) + cfg_path = os.path.join(script_dir, 'test_srcs/hls_config.cfg') + + # Create hls component with existing cfg file + hls_test_comp = client.create_hls_component( + name = comp_name, + cfg_file = cfg_file, + ) + + # Print component information + hls_test_comp.report() + + # Close the client connection and terminate the vitis server + vitis.dispose() + + # Copy the cfg_file to the workspace directory + shutil.copy(cfg_file, cfg_copy) From b6fc053d0b4d42abd20d047a8e5b574db457b59f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 14 Jul 2024 16:45:54 -0700 Subject: [PATCH 2/4] code clean up --- system_vitis_unified_hls.mk | 7 +++--- vitis/hls/build.py | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/system_vitis_unified_hls.mk b/system_vitis_unified_hls.mk index 9f468a4..ad1fb13 100644 --- a/system_vitis_unified_hls.mk +++ b/system_vitis_unified_hls.mk @@ -20,13 +20,12 @@ endif # Project Build Directory ifndef OUT_DIR -export OUT_DIR = $(abspath $(TOP_DIR)/build/$(PROJECT)) +export OUT_DIR = $(abspath $(TOP_DIR)/build/$(PROJECT))_workspace endif -# Synthesis Variables +# Build System Variables export VIVADO_VERSION = $(shell vivado -version | grep -Po "v(\d+\.)+\d+" | cut -c2-) export RUCKUS_DIR = $(TOP_DIR)/submodules/ruckus -export SOURCE_DEPEND = $(OUT_DIR)/$(PROJECT)_sources.txt # Source Files ifndef SRC_FILE @@ -46,7 +45,7 @@ export PRJ_VERSION = v$(EXPORT_VERSION) # Specifies if we need to modify the ip/component.xml to support "all" FPGA family types ifndef ALL_XIL_FAMILY -export ALL_XIL_FAMILY = 0 +export ALL_XIL_FAMILY = 1 endif include $(TOP_DIR)/submodules/ruckus/system_shared.mk diff --git a/vitis/hls/build.py b/vitis/hls/build.py index 4d381de..d66945c 100644 --- a/vitis/hls/build.py +++ b/vitis/hls/build.py @@ -11,10 +11,14 @@ import vitis import os +import shutil +import zipfile # Project variables workspace = os.getenv("OUT_DIR") comp_name = os.getenv("PROJECT") +proj_zip = f'{workspace}/{comp_name}/{comp_name}/{comp_name}.zip' +build_zip = f'{os.getenv("PROJ_DIR")}/ip/{comp_name}.zip' # Create a client object client = vitis.create_client() @@ -39,3 +43,48 @@ # Close the client connection and terminate the vitis server vitis.dispose() + +# Check if ALL_XIL_FAMILY is enabled +if int(os.getenv("ALL_XIL_FAMILY")) > 0: + + # Over the .ZIP file and decompress it + ip_path = f'{workspace}/ip' + os.system( f'rm -rf {ip_path}' ) + os.system( f'mkdir {ip_path}' ) + os.system( f'unzip {proj_zip} -d {ip_path}' ) + + # Read and modify component.xml + component_path = f'{ip_path}/component.xml' + temp_path = f'{ip_path}/component.temp' + with open(component_path, 'r') as infile, open(temp_path, 'w') as outfile: + xil_family = """ +artix7 +kintex7 +virtex7 +zynq +kintexu +virtexu +kintexuplus +virtexuplus +virtexuplusHBM +zynquplus +zynquplusRFSOC +versal +""" + for line in infile: + if 'xilinx:family' in line: + outfile.write(xil_family) + else: + outfile.write(line) + + # Replace the original component.xml with the modified one + shutil.move(temp_path, component_path) + + # Compress the modify IP directory to the target's image directory + os.system( f'bash -c "cd {ip_path}; zip -r {build_zip} *"' ) + +else: + # Copy the .ZIP file to the local ip/ directory + shutil.copy(proj_zip, build_zip) + +print( f'\n\n\nHLS output file: {build_zip}' ) From a8fabb2569937a4333f4482548ceadbf87ae6adb Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 14 Jul 2024 17:41:01 -0700 Subject: [PATCH 3/4] code clean up --- system_vitis_unified_hls.mk | 26 ++------------------------ vitis/hls/create_proj.py | 23 ++--------------------- 2 files changed, 4 insertions(+), 45 deletions(-) diff --git a/system_vitis_unified_hls.mk b/system_vitis_unified_hls.mk index ad1fb13..2d9f318 100644 --- a/system_vitis_unified_hls.mk +++ b/system_vitis_unified_hls.mk @@ -9,39 +9,17 @@ ############################################################################## # Detect project name -ifndef PROJECT export PROJECT = $(notdir $(PWD)) -endif # Detect project path -ifndef PROJ_DIR export PROJ_DIR = $(abspath $(PWD)) -endif # Project Build Directory -ifndef OUT_DIR export OUT_DIR = $(abspath $(TOP_DIR)/build/$(PROJECT))_workspace -endif # Build System Variables -export VIVADO_VERSION = $(shell vivado -version | grep -Po "v(\d+\.)+\d+" | cut -c2-) -export RUCKUS_DIR = $(TOP_DIR)/submodules/ruckus - -# Source Files -ifndef SRC_FILE -export SRC_FILE = $(PROJ_DIR)/sources.tcl -endif - -# Specifies the export configurations -ifndef EXPORT_VENDOR -export EXPORT_VENDOR = SLAC -endif -ifndef EXPORT_VERSION -export EXPORT_VERSION = 1.0 -endif - -# Update legacy "PRJ_VERSION" variable -export PRJ_VERSION = v$(EXPORT_VERSION) +export VIVADO_VERSION = $(shell vivado -version | grep -Po "v(\d+\.)+\d+" | cut -c2-) +export RUCKUS_DIR = $(TOP_DIR)/submodules/ruckus # Specifies if we need to modify the ip/component.xml to support "all" FPGA family types ifndef ALL_XIL_FAMILY diff --git a/vitis/hls/create_proj.py b/vitis/hls/create_proj.py index 81aaee6..fad38c0 100644 --- a/vitis/hls/create_proj.py +++ b/vitis/hls/create_proj.py @@ -17,36 +17,20 @@ workspace = os.getenv("OUT_DIR") comp_name = os.getenv("PROJECT") cfg_file = f'{os.getenv("PROJ_DIR")}/hls_config.cfg' -cfg_copy = os.path.join(workspace, os.path.basename(cfg_file)) # Verify that the configuration file exists if not os.path.exists(cfg_file): raise FileNotFoundError(f"The configuration file {cfg_file} does not exist.") -# Check if the previous cfg_file copy exists -if not os.path.exists(cfg_copy): - diffCheck = 1 # Force project creation -else: - diffCheck = os.system(f'diff {cfg_file} {cfg_copy} >/dev/null 2>&1') - -# Check for any changes in cfg_file -if diffCheck > 0: +# Check if component directory does not exist yet +if not (os.path.isdir( f'{workspace}/{comp_name}' )): # Create a client object client = vitis.create_client() - # Delete the workspace if already exists. - if (os.path.isdir(workspace)): - shutil.rmtree(workspace) - print( f'Deleted workspace {workspace}' ) - # Set workspace client.set_workspace(workspace) - # Get config file object - script_dir = os.path.dirname(os.path.abspath(__file__)) - cfg_path = os.path.join(script_dir, 'test_srcs/hls_config.cfg') - # Create hls component with existing cfg file hls_test_comp = client.create_hls_component( name = comp_name, @@ -58,6 +42,3 @@ # Close the client connection and terminate the vitis server vitis.dispose() - - # Copy the cfg_file to the workspace directory - shutil.copy(cfg_file, cfg_copy) From 6b203b6c69f7063a512da75d3157507ae04df409 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 15 Jul 2024 22:04:55 -0700 Subject: [PATCH 4/4] updating workspace location --- system_vitis_unified_hls.mk | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/system_vitis_unified_hls.mk b/system_vitis_unified_hls.mk index 2d9f318..12e35ed 100644 --- a/system_vitis_unified_hls.mk +++ b/system_vitis_unified_hls.mk @@ -14,8 +14,8 @@ export PROJECT = $(notdir $(PWD)) # Detect project path export PROJ_DIR = $(abspath $(PWD)) -# Project Build Directory -export OUT_DIR = $(abspath $(TOP_DIR)/build/$(PROJECT))_workspace +# Project Build Directory ("workspace") +export OUT_DIR = $(PROJ_DIR)/build # Build System Variables export VIVADO_VERSION = $(shell vivado -version | grep -Po "v(\d+\.)+\d+" | cut -c2-) @@ -52,17 +52,6 @@ test: .PHONY : proj proj: $(call ACTION_HEADER,"Vitis HLS Create Project") - @test -d $(TOP_DIR)/build/ || { \ - echo ""; \ - echo "Build directory missing!"; \ - echo "You must create a build directory at the top level."; \ - echo ""; \ - echo "This directory can either be a normal directory:"; \ - echo " mkdir $(TOP_DIR)/build"; \ - echo ""; \ - echo "Or by creating a symbolic link to a directory on another disk:"; \ - echo " ln -s /tmp/build $(TOP_DIR)/build"; \ - echo ""; false; } @test -d $(OUT_DIR) || mkdir $(OUT_DIR) @test -d $(PROJ_DIR)/ip || mkdir $(PROJ_DIR)/ip @cd $(OUT_DIR); vitis -s $(RUCKUS_DIR)/vitis/hls/create_proj.py