def find_tool(name, hints=None, sys_path_hint=True): # set defaults if hints is None: hints = [] # add system path as the last "hint" if desired (default behavior) if sys_path_hint: hints.append(lambda: None) # first check the system path for the tool tool_path = shutil.which(name) # if the tool isn't found in the system path, then try out the hints in order if tool_path is None: for hint in hints: try: if callable(hint): tool_path = shutil.which(name, path=hint()) else: tool_path = shutil.which(name, path=hint) except: continue if tool_path is not None: break if tool_path is not None: return get_full_path(tool_path) else: raise KeyError(f'Tool:{name} could not be found')
def __init__(self, input=None, build_root=None, simulator_name=None, synthesizer_name=None, viewer_name=None, preprocess_only=None, op_mode=None, active_target=None): # Parse command line arguments self.args = None self._parse_args() # Initialize attributes self.float_type = False # Defines which data type is used for functional models; default is fixed-point self._plugin_args = { } # Namespace object including all options set for generators # Overwrite input location in case it was provided when instantiation the Analysis class if input is not None: self.args.input = input # expand path of input and output directories relative to analysis.py self.args.input = get_full_path(self.args.input) # update args according to user specified values when instantiating analysis class self.args.simulator_name = simulator_name if simulator_name is not None else self.args.simulator_name self.args.synthesizer_name = synthesizer_name if synthesizer_name is not None else self.args.synthesizer_name self.args.viewer_name = viewer_name if viewer_name is not None else self.args.viewer_name self.args.preprocess_only = preprocess_only if preprocess_only is not None else self.args.preprocess_only self.args.active_target = active_target if active_target is not None else self.args.active_target # Load config file self.cfgfile_path = os.path.join(self.args.input, 'prj.yaml') if os.path.isfile(self.cfgfile_path): try: self.cfg_file = yaml.safe_load(open(self.cfgfile_path, "r")) except yaml.YAMLError as exc: raise Exception(exc) else: self.cfg_file = None print( f"Warning: no config file was found for the project, expected path is: {self.cfgfile_path}" ) # Initialize Targets self.act_fpga_target = 'fpga' self.fpga_targets = [self.act_fpga_target] try: for custom_target in self.cfg_file[ ConfigSections.FPGA_TARGET].keys(): if custom_target not in self.fpga_targets: self.fpga_targets.append(custom_target) except: pass self.act_cpu_target = 'sim' self.cpu_targets = [self.act_cpu_target] try: for custom_target in self.cfg_file[ ConfigSections.CPU_TARGET].keys(): if custom_target not in self.cpu_targets: self.cpu_targets.append(custom_target) except: pass # Initialize dict for tracking, which targets are already setup. self._setup_finished = {} for target in self.cpu_targets + self.fpga_targets: self._setup_finished[target] = False self.project_sources_finalized = False # Initialize project config self._prj_cfg = EmuConfig(root=self.args.input, cfg_file=self.cfg_file, active_target=self.args.active_target, build_root=build_root) # Initialize Plugins self._plugins = [] for plugin in self._prj_cfg.cfg.plugins: try: i = import_module(f"{plugin}.plugin") inst = i.CustomPlugin(prj_cfg=self._prj_cfg, cfg_file=self.cfg_file, prj_root=self.args.input) self._plugins.append(inst) setattr(self, inst._name, inst) except: raise KeyError( f"Could not process plugin:{plugin} properly! Check spelling" ) #Set active target self.set_target(self.args.active_target) # Initialize filesets, those can later be modified via the add_sources function self._setup_filesets() # Check which mode is used to run, in case of commandline mode, besides setting up the class, also argument will be processed and executed if op_mode in ['commandline']: print(f"Running in commandline mode.") ############################################################### # Process command line arguments for plugins ############################################################### for plugin in self._plugins: # Parse command line arguments and execute all actions for each plugin plugin._parse_args() args = plugin._return_args() for arg in args.__dict__: plugin.set_option( name=arg, value=args.__dict__[arg] ) # Set options for the generator according to commandline arguments self._plugin_args[arg] = args.__dict__[arg] # Set float type to true, in case floating-point data types are used during simulation. # This is needed when converting result files. if 'float' in self._plugin_args.keys(): self.float_type = self._plugin_args['float'] ############################################################### # Set options from to command line arguments ############################################################### self._prj_cfg.cfg.preprocess_only = self.args.preprocess_only ############################################################### # Execute actions according to command line arguments ############################################################### # generate source code, e.g. functional models via msdsl if self.args.models: self.gen_sources() # generate bitstream if self.args.build: self.set_target(self.act_fpga_target) self.build() # run FPGA if desired if self.args.emulate: self.set_target(self.act_fpga_target) self.emulate() # launch FPGA if desired if self.args.launch: self.set_target(self.act_fpga_target) self.launch() # run simulation if desired if self.args.sim or self.args.preprocess_only: self.set_target(self.act_cpu_target) self.simulate(unit=self.args.unit, id=self.args.id) # view results if desired if self.args.view and (self.args.sim or self.args.preprocess_only): self.set_target(self.act_cpu_target) self.view() if self.args.view and self.args.emulate: self.set_target(self.act_fpga_target) self.view()