diff --git a/src/finn/builder/build_dataflow_config.py b/src/finn/builder/build_dataflow_config.py index e4fed05731..bb472fcbf9 100644 --- a/src/finn/builder/build_dataflow_config.py +++ b/src/finn/builder/build_dataflow_config.py @@ -33,7 +33,10 @@ from enum import Enum from typing import Any, List, Optional -from finn.transformation.fpgadataflow.vitis_build import VitisOptStrategy +from finn.transformation.fpgadataflow.vitis_build import ( + VitisOptStrategy, + VivadoImplStrategy, +) from finn.util.basic import alveo_default_platform, alveo_part_map, pynq_part_map @@ -84,6 +87,15 @@ class VitisOptStrategyCfg(str, Enum): BUILD_SPEED = "quick" +class VivadoImplStrategyCfg(str, Enum): + "Values applicable to VitisBuild Vivado implementation strategy" + + ALL = "ALL" + DEFAULT = "'Vivado Implementation Defaults'" + PERFORMANCE_BALANCESLR = "Performance_BalanceSLRs" + PERFORMANCE_HIGHUTILSLR = "Performance_HighUtilSLRs" + + class LargeFIFOMemStyle(str, Enum): """Type of memory resource to use for large FIFOs.""" @@ -305,6 +317,10 @@ class DataflowBuildConfig: #: Only relevant when `shell_flow_type = ShellFlowType.VITIS_ALVEO` vitis_opt_strategy: Optional[VitisOptStrategyCfg] = VitisOptStrategyCfg.DEFAULT + #: Vivado implementation strategy + #: Only relevant when `shell_flow_type = ShellFlowType.VITIS_ALVEO` + vivado_impl_strategy: Optional[VivadoImplStrategy] = VivadoImplStrategy.DEFAULT + #: Whether intermediate ONNX files will be saved during the build process. #: These can be useful for debugging if the build fails. save_intermediate_models: Optional[bool] = True @@ -399,6 +415,16 @@ def _resolve_vitis_opt_strategy(self): } return name_to_strategy[self.vitis_opt_strategy] + def _resolve_vivado_impl_strategy(self): + # convert human-readable enum to value expected by v++ + name_to_strategy = { + VivadoImplStrategyCfg.ALL: VivadoImplStrategy.ALL, + VivadoImplStrategyCfg.DEFAULT: VivadoImplStrategy.DEFAULT, + VivadoImplStrategyCfg.PERFORMANCE_BALANCESLR: VivadoImplStrategy.PERFORMANCE_BALANCESLR, + VivadoImplStrategyCfg.PERFORMANCE_HIGHUTILSLR: VivadoImplStrategy.PERFORMANCE_HIGHUTILSLR, # noqa + } + return name_to_strategy[self.vivado_impl_strategy] + def _resolve_vitis_platform(self): if self.vitis_platform is not None: return self.vitis_platform diff --git a/src/finn/builder/build_dataflow_steps.py b/src/finn/builder/build_dataflow_steps.py index 54ba7e4ea1..504e6bcee6 100644 --- a/src/finn/builder/build_dataflow_steps.py +++ b/src/finn/builder/build_dataflow_steps.py @@ -788,6 +788,7 @@ def step_synthesize_bitfile(model: ModelWrapper, cfg: DataflowBuildConfig): cfg.synth_clk_period_ns, cfg._resolve_vitis_platform(), strategy=cfg._resolve_vitis_opt_strategy(), + impl_strategy=cfg._resolve_vivado_impl_strategy(), enable_debug=cfg.enable_hw_debug, floorplan_file=cfg.vitis_floorplan_file, partition_model_dir=partition_model_dir, diff --git a/src/finn/transformation/fpgadataflow/vitis_build.py b/src/finn/transformation/fpgadataflow/vitis_build.py index 2fc0b2f3bb..d6fc0fe06d 100644 --- a/src/finn/transformation/fpgadataflow/vitis_build.py +++ b/src/finn/transformation/fpgadataflow/vitis_build.py @@ -73,6 +73,15 @@ class VitisOptStrategy(Enum): BUILD_SPEED = "quick" +class VivadoImplStrategy(str, Enum): + "Values applicable to VitisBuild Vivado implementation strategy" + + ALL = "ALL" + DEFAULT = "'Vivado Implementation Defaults'" + PERFORMANCE_BALANCESLR = "Performance_BalanceSLRs" + PERFORMANCE_HIGHUTILSLR = "Performance_HighUtilSLRs" + + class CreateVitisXO(Transformation): """Create a Vitis object file from a stitched FINN ip. @@ -173,12 +182,14 @@ def __init__( f_mhz=200, strategy=VitisOptStrategy.PERFORMANCE, enable_debug=False, + impl_strategy=VivadoImplStrategy.DEFAULT, ): super().__init__() self.platform = platform self.f_mhz = f_mhz self.strategy = strategy self.enable_debug = enable_debug + self.impl_strategy = impl_strategy def apply(self, model): _check_vitis_envvars() @@ -304,16 +315,18 @@ def apply(self, model): f.write( "v++ -t hw --platform %s --link %s" " --kernel_frequency %d --config config.txt --optimize %s" - " --save-temps -R2 %s\n" + " --save-temps -R2 %s --vivado.impl.strategies %s\n" % ( self.platform, " ".join(object_files), self.f_mhz, self.strategy.value, " ".join(debug_commands), + self.impl_strategy.value, ) ) f.write("cd {}\n".format(working_dir)) + bash_command = ["bash", script] process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE) process_compile.communicate() @@ -355,6 +368,7 @@ class VitisBuild(Transformation): Must be parse-able by the ApplyConfig transform. :parameter enable_link: enable linking kernels (.xo files), otherwise just synthesize them independently. + :parameter impl_strategy: Vivado implementation strategy """ def __init__( @@ -367,6 +381,7 @@ def __init__( floorplan_file=None, enable_link=True, partition_model_dir=None, + impl_strategy=VivadoImplStrategy.DEFAULT, ): super().__init__() self.fpga_part = fpga_part @@ -377,6 +392,7 @@ def __init__( self.floorplan_file = floorplan_file self.enable_link = enable_link self.partition_model_dir = partition_model_dir + self.impl_strategy = impl_strategy def apply(self, model): _check_vitis_envvars() @@ -422,6 +438,7 @@ def apply(self, model): round(1000 / self.period_ns), strategy=self.strategy, enable_debug=self.enable_debug, + impl_strategy=self.impl_strategy, ) ) # set platform attribute for correct remote execution