diff --git a/config/hdl_tool_quartus.cfg b/config/hdl_tool_quartus.cfg index 8ae6d88dd0d439601da1a65e0d32e05ee3cd0359..d1a8b00ae64ba2f9c91d1b3c29a30d768c9861ec 100644 --- a/config/hdl_tool_quartus.cfg +++ b/config/hdl_tool_quartus.cfg @@ -24,7 +24,7 @@ qsys_paths = [ip generation] ip_tools = qmegawiz qsys-generate quartus_sh qmegawiz_default_options = -silent -qsys_generate_default_options = --synthesis=VHDL --simulation=VHDL --allow-mixed-language-simulation +qsys-generate_default_options = --synthesis=VHDL --simulation=VHDL --allow-mixed-language-simulation quartus_sh_default_options = [user settings] diff --git a/core/check_config b/core/check_config index 5ded6fd99224d108b667cf99745f5c6c5387ce14..db52990a35079cf8606b9ed58c70edb7f3137b52 100755 --- a/core/check_config +++ b/core/check_config @@ -28,6 +28,7 @@ from argparse import ArgumentParser from hdl_configfile import HdlBuildset, HdlTool from configfile import ConfigFileException + def _do_basic_key_checking(cfgfile, indent=""): # Check that all key references are solved print("{}Checking references...".format(indent), end=' ') @@ -48,19 +49,29 @@ def _do_basic_key_checking(cfgfile, indent=""): else: print("\n{}ERROR: The following required keys don't have a value: {}".format(indent, empty_keys)) + +def expand_all_vars(dir_name): + _dirname = dir_name + while '$' in _dirname: + # print(_dirname) + _dirname = expandvars(_dirname) + return _dirname + + def _check_quartus_configfile(cfgfile, tool_types): # check required dirs - for required_dir in [ "quartus_rootdir", "quartus_rootdir_override", "niosdir" ]: + for required_dir in ["quartus_rootdir", "quartus_rootdir_override", "niosdir"]: print(" Checking {}...".format(required_dir), end=' ') - if isdir(expandvars(cfgfile[required_dir])): + + if isdir(expand_all_vars(cfgfile[required_dir])): print("OK") else: print("\n ERROR: path {} does not exist!".format(cfgfile[required_dir])) # check _paths variables - required_paths = [ "{}_paths".format(tool) for tool in tool_types ] - for path_key in [ key for key in list(cfgfile.content.keys()) if key.endswith("_paths") ]: - paths = [ expandvars(pathname) for pathname in cfgfile[path_key].replace("\t"," ").split(" ") if pathname != "" ] + required_paths = ["{}_paths".format(tool) for tool in tool_types] + for path_key in [key for key in list(cfgfile.content.keys()) if key.endswith("_paths")]: + paths = [expand_all_vars(pathname) for pathname in cfgfile[path_key].replace("\t", " ").split(" ") if pathname != ""] print(" Checking {}...".format(path_key)) if not paths: print(" no paths defined.") @@ -76,28 +87,34 @@ def _check_quartus_configfile(cfgfile, tool_types): # check IP generation print(" Checking ip generation...") - ip_tools = [ tool for tool in cfgfile.ip_tools.replace("\t"," ").split(" ") if tool != '' ] + ip_tools = [tool for tool in cfgfile.ip_tools.replace("\t", " ").split(" ") if tool != ''] for ip_tool in ip_tools: opt_key = "{}_default_options".format(ip_tool) - if not opt_key in list(cfgfile.content.keys()): + if opt_key not in list(cfgfile.content.keys()): print(" {}: key is MISSING!".format(opt_key)) else: print(" {}: OK".format(opt_key)) - + # check environment variables - for envvar_key in [ key for key in list(cfgfile.content.keys()) if key.endswith("_environment_variables") ]: - items = [ item for item in cfgfile[envvar_key].replace("\t"," ").split(" ") if item != "" ] + for envvar_key in [key for key in list(cfgfile.content.keys()) if key.endswith("_environment_variables")]: + items = [item for item in cfgfile[envvar_key].replace("\t", " ").split(" ") if item != ""] print(" Checking {}...".format(envvar_key)) if not items: print(" no variables defined.") else: - if len(items)%2 == 0: + if len(items) % 2 == 0: print(" number of values is correct") else: print(" expected even number of values (not {})".format(len(items))) if __name__ == '__main__': + + keys = ['QUARTUS_DIR', 'ALTERA_DIR', 'MENTOR_DIR', 'MODELSIM_ALTERA_LIBS_DIR'] + for key in keys: + if key not in os.environ: + print("{} not in os.environ".format(key)) + # setup parser and parse the arguments. argparser = ArgumentParser(description='Check to content of your hdl_buildset file and the corresponding hdl_tool file.') argparser.add_argument('buildset', help="Filename like 'hdl_buildset_<buildset>.cfg'") @@ -112,8 +129,8 @@ if __name__ == '__main__': # check if lib_root_dirs exist print("Checking defined library directories...", end=' ') - lib_dirs = [ expandvars(libdir) for libdir in buildset_info.lib_root_dirs.replace("\t"," ").split(" ") - if libdir != '' ] + lib_dirs = [expand_all_vars(libdir) for libdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ") + if libdir != ''] wrong_dirs = [] for libdir in lib_dirs: if not isdir(libdir): @@ -124,14 +141,14 @@ if __name__ == '__main__': print("\nERROR: The following library rootdir do not exist: ", wrong_dirs) # Check tools - subtoolnames = [ subtool for subtool in buildset_info.block_design_names.replace("\t"," ").split(" ") if subtool != '' ] - toolnames = [ buildset_info.synth_tool_name, buildset_info.sim_tool_name ] + subtoolnames = [subtool for subtool in buildset_info.block_design_names.replace("\t", " ").split(" ") if subtool != ''] + toolnames = [buildset_info.synth_tool_name, buildset_info.sim_tool_name] for toolname in toolnames: print("Checking tool {}...".format(toolname), end=' ') - if not toolname in buildset_info.section_headers: + if toolname not in buildset_info.section_headers: print("\n Warning: No sectionheader found.", end=' ') tool_dir = "{}_dir".format(toolname) - if not tool_dir in list(buildset_info.content.keys()): + if tool_dir not in list(buildset_info.content.keys()): print("\n ERROR: Key {} is missing.".format(tool_dir), end=' ') else: os.environ[tool_dir.upper()] = buildset_info[tool_dir] @@ -148,5 +165,3 @@ if __name__ == '__main__': if toolname == "quartus": _check_quartus_configfile(tool_info, toolnames+subtoolnames) - - diff --git a/core/common_radiohdl.py b/core/common_radiohdl.py index da37f6ba1b88999dd54f6878b7bd748a20a7cc14..e45099ca38b00b6eb9a79c6bc8033250b915f744 100644 --- a/core/common_radiohdl.py +++ b/core/common_radiohdl.py @@ -25,10 +25,11 @@ def unlistify(obj): # The isinstance() built-in function is recommended over the type() # built-in function for testing the type of an object if isinstance(obj, list): - if len(obj)==1: + if len(obj) == 1: return obj[0] return obj + def remove_from_list_string(list_str, item_str, sep=' '): """Treat the string list_str as a list of items that are separated by sep and then remove the specified item_str string from the list and return the list as a @@ -39,6 +40,7 @@ def remove_from_list_string(list_str, item_str, sep=' '): _list_str.remove(item_str) return sep.join(_list_str) + def unique(in_list): """ Extract unique list elements (without changing the order like set() does) @@ -50,6 +52,7 @@ def unique(in_list): result.append(item) return result + def method_name(caller_depth=0): """ Returns the name of the caller method. @@ -57,6 +60,7 @@ def method_name(caller_depth=0): # Note: inspect.stack()[0][3] would return the name of this method. return inspect.stack()[caller_depth+1][3] + def mkdir(path): """Recursively create leave directory and intermediate directories if they do not already exist.""" expand_path = os.path.expandvars(path) # support using environment variables in the file path @@ -64,6 +68,7 @@ def mkdir(path): if not os.path.exists(expand_path): os.makedirs(expand_path) + def expand_file_path_name(fpn, dir_path=''): """ Expand environment variables in fpn to get file_path_name. - if it is an absolute path return file_path_name else diff --git a/core/config_variable.py b/core/config_variable.py index 52f2e75c49a2ea91fe00f22882a96afdb15960a0..d2170cefc750656191246f530d4f646e6e2cb64f 100755 --- a/core/config_variable.py +++ b/core/config_variable.py @@ -31,7 +31,7 @@ if __name__ == '__main__': # setup parser and parse the arguments. argparser = ArgumentParser(description='Options and arguments for showing hdl_config keys values') argparser.add_argument('configfile', help="Filename like 'hdl_buildset_<boardtype>.cfg'") - argparser.add_argument('keyname', help="Name of the key to show the value of.") + argparser.add_argument('keyname', help="Name of the key to show the value of.") args = argparser.parse_args() # resolve full name of configfile and force it to be explicit absolute or relative. diff --git a/core/configfile.py b/core/configfile.py index 4721f5fb94a16eff27096c324cddc4c9c5283e17..5a5266bf1f9dfe46015ff949724e04d4b22a275a 100644 --- a/core/configfile.py +++ b/core/configfile.py @@ -91,7 +91,7 @@ import os.path import re from collections import OrderedDict -__all__ = ['CFG_COMMENT_CHAR', 'CFG_ASSIGNMENT_CHAR', 'ConfigFileException', 'ConfigFile' ] +__all__ = ['CFG_COMMENT_CHAR', 'CFG_ASSIGNMENT_CHAR', 'ConfigFileException', 'ConfigFile'] CFG_COMMENT_CHAR = '#' CFG_ASSIGNMENT_CHAR = '=' @@ -110,8 +110,8 @@ class ConfigFile(object): :required_keys Optional. May contain a list of all keys that must exist in the configfile. If one or more of those keys is missing in the configfile an exception is raised. """ - _CONFIGFILE_ATTRIBUTES = [ '_own_attr_', 'filename', 'location', 'sections', 'required_keys', - '__content__', 'section_headers', 'unresolved_refs', 'warnings' ] + _CONFIGFILE_ATTRIBUTES = ['_own_attr_', 'filename', 'location', 'sections', 'required_keys', + '__content__', 'section_headers', 'unresolved_refs', 'warnings'] def __init__(self, filename, sections=None, required_keys=[]): """ @@ -120,7 +120,7 @@ class ConfigFile(object): """ full_filename = os.path.expanduser(os.path.expandvars(filename)) if not os.path.isfile(full_filename): - raise ConfigFileException ("configfile '%s' not found" % full_filename) + raise ConfigFileException("configfile '%s' not found" % full_filename) # Crucial: define dict for storing our (simulated) attributes self.__dict__['_own_attr_'] = {} @@ -139,10 +139,9 @@ class ConfigFile(object): # Check if all required keys are available for required_key in self.required_keys: - if not required_key in self.__content__: + if required_key not in self.__content__: raise ConfigFileException("configfile '%s' missing key '%s'" % (filename, required_key)) - def __getattr__(self, name): """ Catch read-access to attributes to fetch values from the content dictionary. @@ -154,10 +153,12 @@ class ConfigFile(object): if name in self.__dict__['_own_attr_']['__content__']: return self.__dict__['_own_attr_']['__content__'][name] + print('%s object has no attribute %s' % (str(self.__class__.__name__), str(name))) + if not hasattr(self, name): raise AttributeError("%r object has no attribute %r" % (self.__class__.__name__, name)) - return getattr(self, name) + return getattr(self, name) def __setattr__(self, name, value): """ @@ -181,11 +182,11 @@ class ConfigFile(object): "Also allow access to the information as item." self.__setattr__(key, value) - def _add_kv_pair(self, key, value, include_in_section): """ Internal function for adding a key-value pair in a neat way. """ + # print("add_kv_pair: key={}, value={}\n".format(key, value)) if not include_in_section: return if key.find(' ') > 0: @@ -212,24 +213,24 @@ class ConfigFile(object): ln = line.split(CFG_COMMENT_CHAR, 1)[0] # Strip comment from line if len(ln) == 0: continue - section_begin= ln.find('[') # Search for [section] header in this line - section_end = ln.find(']') + section_begin = ln.find('[') # Search for [section] header in this line + section_end = ln.find(']') # section MUST start at first character of the line - if section_begin==0 and section_end>0: - self._add_kv_pair(key, value, include_section) # complete action on current key + if section_begin == 0 and section_end > 0: + self._add_kv_pair(key, value, include_section) # complete action on current key key = '' value = '' # administrate new section section_header = ln[1:section_end].strip() # new section header self.section_headers.append(section_header) include_section = True # default include this new section - if self.sections!=None: + if self.sections is not None: if section_header not in self.sections: include_section = False # skip this section else: key_end = ln.find(CFG_ASSIGNMENT_CHAR) # Search for key in this line - if key_end>0: - self._add_kv_pair(key, value, include_section) # complete action on current key + if key_end > 0: + self._add_kv_pair(key, value, include_section) # complete action on current key key = ln[0:key_end].strip() # start with new key value = ln[key_end+1:].strip() # and new value else: @@ -240,14 +241,14 @@ class ConfigFile(object): self.warnings += "Warning: value without a key: file '{}/{}', line {} ({})"\ .format(self.location, self.filename, linenr, value) value = '' - self._add_kv_pair(key, value, include_section) # complete action on current key + self._add_kv_pair(key, value, include_section) # complete action on current key if self.warnings != '': raise ConfigFileException(self.warnings) - @property def content(self): + # print(self.__content__) "The content of the configfile as ordered dictionary." return self.__content__ @@ -256,7 +257,6 @@ class ConfigFile(object): "Returns uniq ID (string) to identify this particular file. Fullfilename is used." return "{}/{}".format(self.location, self.filename) - def resolve_key_references(self): """ Replaces in all values the references to keys (<key>) with the value of that key. @@ -277,7 +277,6 @@ class ConfigFile(object): self.unresolved_refs.append("<{}>".format(reference)) return len(self.unresolved_refs) == 0 - def get_value(self, key, must_exist=False): """ Get the value of a key. If the key does not exist and that is allowed 'None' is returned, in case the @@ -290,4 +289,3 @@ class ConfigFile(object): raise ConfigFileException("Key '%s' does not exist in configfile %s/%s." % (key, self.location, self.filename)) return None - diff --git a/core/configtree.py b/core/configtree.py index 576c1d5127281e80fd6eaa06c8d72b81a9e20ae9..d0654d87feadbbc3499b65b5ec996a5d7ad5ac66 100644 --- a/core/configtree.py +++ b/core/configtree.py @@ -27,6 +27,7 @@ import re from common_radiohdl import listify from configfile import ConfigFile, ConfigFileException + class ConfigTree(object): def __init__(self, rootdirs, filename, sections=None): @@ -59,8 +60,8 @@ class ConfigTree(object): cfgfile = self._factory_constructor("{}/{}".format(root, some_filename)) # check for duplicates if cfgfile.ID in list(self._configfiles.keys()): - raise ConfigFileException("File with id '%s' found twice (at '%s' and '%s')" % - (cfgfile.ID, self._configfiles[cfgfile.ID].location, cfgfile.location)) + raise ConfigFileException("File with id '%s' found twice (at '%s' and '%s')" + % (cfgfile.ID, self._configfiles[cfgfile.ID].location, cfgfile.location)) self._configfiles[cfgfile.ID] = cfgfile def _factory_constructor(self, full_filename): @@ -81,7 +82,6 @@ class ConfigTree(object): for cfgfileID in files_to_remove: self._configfiles.pop(cfgfileID) - def limit_tree_to(self, files_to_keep): """ Limit the configfile collection in our admin to the ones given in the files_to_keep argument. @@ -99,7 +99,7 @@ class ConfigTree(object): :return List of values :raises ConfigFileException """ - if configfiles == None: + if configfiles is None: configfiles = self._configfiles result = [] @@ -107,8 +107,6 @@ class ConfigTree(object): result.append(cfgfile.get_value(key, must_exist)) return result - - def get_configfiles(self, key, values=None, user_configfiles=None): """ Get a list with all configfiles that contain the key with a value specified in values. @@ -120,6 +118,6 @@ class ConfigTree(object): result = [] for cfgfile in file_list: if cfgfile not in result and key in cfgfile.content: - if values == None or cfgfile.content[key] in values: + if values is None or cfgfile.content[key] in values: result.append(cfgfile) return result diff --git a/core/export_config_variables.py b/core/export_config_variables.py index 979fb48b97737ce8efd106bc82ca34e25558bcd4..2cc1f879239e4812fe7baad4479ba16507991d8e 100755 --- a/core/export_config_variables.py +++ b/core/export_config_variables.py @@ -31,14 +31,14 @@ if __name__ == '__main__': # setup parser and parse the arguments. argparser = ArgumentParser(description="Options and arguments for constructing an 'export' command for shell based on the content of a hdltool config file.") argparser.add_argument('configfile', help="Filename like 'hdl_buildset_<boardtype>.cfg'") - argparser.add_argument('keynames', help="Name(s) of the key(s) to show the value of. Use comma to seperate multiple keys.") + argparser.add_argument('keynames', help="Name(s) of the key(s) to show the value of. Use comma to seperate multiple keys.") argparser.add_argument('--varnames', help="Name(s) of the environment variable(s) the keys are mapped to. Default the keynames in capitals are used as environment variable names.") argparser.add_argument('--is-group', help="The keynames refer to groups of environment variables that must be set.", action="store_true") argparser.add_argument('--optional', help="The keynames are optional. When them do not exist not error is generated", action="store_true") args = argparser.parse_args() - + # resolve full name of configfile and force it to be explicit absolute or relative. full_configfile_name = expandvars(args.configfile) if full_configfile_name[0] != '/': @@ -62,21 +62,21 @@ if __name__ == '__main__': # finally construct an export command for the key value pairs. for idx, key in enumerate(keys): - print("export {}='{}'\n".format(env_vars[idx], + print("export {}='{}'\n".format(env_vars[idx], os.path.expandvars(cfg_info.get_value(key, must_exist=not(args.optional))))) sys.exit(0) # Each key contains key-value pairs that must be exported in stead of a value if args.varnames: argparser.error("The option --varnames can not be used in combination with the option --is-group.") - - #print("args.keynames=%s" % str(args.keynames)) + + # print("args.keynames=%s" % str(args.keynames)) keys = args.keynames.split(',') for key in keys: kv_pairs = cfg_info.get_value(key, must_exist=not(args.optional)) # currently 'by definition' the value we got has the format: <key> <value> [<key> <value> [...]] # check we have an even number of items - #print("KV_pairs={}".format(kv_pairs)) + # print("KV_pairs={}".format(kv_pairs)) if kv_pairs is None: continue items = kv_pairs.split() diff --git a/core/export_hdllib_variables.py b/core/export_hdllib_variables.py index 5eab184af7eb00b94610e913ea2a712ed7f999c6..059ee4181564aea9ab9d9b4420b185ee2d8fae62 100755 --- a/core/export_hdllib_variables.py +++ b/core/export_hdllib_variables.py @@ -32,8 +32,8 @@ if __name__ == '__main__': # setup parser and parse the arguments. argparser = ArgumentParser(description='Options and arguments for exporting hdllib keys values') argparser.add_argument('buildset', help="Filename like 'hdl_buildset_<boardtype>.cfg'") - argparser.add_argument('libname', help="Name of the library to search in.") - argparser.add_argument('keys', help="Name of variable(s) to export.") + argparser.add_argument('libname', help="Name of the library to search in.") + argparser.add_argument('keys', help="Name of variable(s) to export.") args = argparser.parse_args() # read the buildset file @@ -42,11 +42,12 @@ if __name__ == '__main__': buildset_info.resolve_key_references() # find out where the hdllibs files are and read them in - root_dirs = [ expandvars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t"," ").split(" ") - if rootdir != '' ] + root_dirs = [expandvars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ") + if rootdir != ''] lib_tree = HdlLibTree(rootdirs=root_dirs, filename="hdllib.cfg") for key in args.keys.split(','): - print("export {}='{}'\n".format(key.lower(), - os.path.expandvars(lib_tree.configfiles[args.libname].get_value(key=key, must_exist=True)))) + print("export {}='{}'\n".format( + key.lower(), + os.path.expandvars(lib_tree.configfiles[args.libname].get_value(key=key, must_exist=True)))) diff --git a/core/generate_ip_libs b/core/generate_ip_libs index 590aa4a1b14aac6073ce7e7b622a018cb2f25a31..5f5ccba0baf9bcac1a6aa6e264490a49307d9413 100755 --- a/core/generate_ip_libs +++ b/core/generate_ip_libs @@ -24,12 +24,13 @@ import sys import os -from os.path import expandvars, dirname, basename -from subprocess import call, STDOUT +from os.path import expandvars, dirname, basename +from subprocess import call, STDOUT from common_radiohdl import listify, mkdir -from argparse import ArgumentParser -from hdl_configfile import HdlBuildset, HdlTool -from hdl_configtree import HdlLibTree +from argparse import ArgumentParser +from hdl_configfile import HdlBuildset, HdlTool +from hdl_configtree import HdlLibTree + def run_qmegawiz(buildset, outputdir, hdllib, vhdl_files, options): """ @@ -42,17 +43,17 @@ def run_qmegawiz(buildset, outputdir, hdllib, vhdl_files, options): error_code = 0 for vhdl_file in vhdl_files: - script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset + script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset script += 'cd %s\n' % outputdir script += 'cp %s/%s .\n' % (hdllib.location, vhdl_file) script += 'set -o pipefail\n' # echo line without 'Info:' to make sure grep it's exit code is 0 script += '(echo " " ; qmegawiz %s %s %s 2>&1) | grep -iv Info:\n' \ - % (options, extra_options, vhdl_file) + % (options, extra_options, vhdl_file) script += 'exit_code=$?\n' script += 'rm %s\n' % vhdl_file script += 'exit $exit_code\n' - #execute script + # execute script print("compiling {} ... ".format(vhdl_file)) return_code = call(script, stdout=None, stderr=STDOUT, shell=True) # qmegawiz is very sloppy with it's exitcodes. We assume 0 is OK although this not always the case. :-( @@ -61,7 +62,7 @@ def run_qmegawiz(buildset, outputdir, hdllib, vhdl_files, options): else: print("*** Error during generation, exitcode={}\n".format(return_code)) error_code |= return_code - return error_code + return error_code def run_qsys(buildset, outputdir, hdllib, vhdl_files, options): @@ -75,12 +76,12 @@ def run_qsys(buildset, outputdir, hdllib, vhdl_files, options): error_code = 0 for vhdl_file in vhdl_files: - script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset + script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset script += 'cd %s\n' % hdllib.location script += 'set -o pipefail\n' # echo line without 'Info:' to make sure grep it's exit code is 0 script += '(echo " " ; qsys-generate %s %s --output-directory=%s %s 2>&1) | grep -iv Info:\n' \ - % (options, extra_options, outputdir, vhdl_file) + % (options, extra_options, outputdir, vhdl_file) script += 'exit_code=$?\n' script += 'exit $exit_code\n' # execute script @@ -92,8 +93,8 @@ def run_qsys(buildset, outputdir, hdllib, vhdl_files, options): print("*** Error during generation, exitcode={}\n".format(return_code)) error_code |= return_code return error_code - - + + def run_quartus_sh(buildset, outputdir, hdllib, tcl_files, options): """ Run quartus_sh for the configuration in the given hdllib. @@ -105,12 +106,12 @@ def run_quartus_sh(buildset, outputdir, hdllib, tcl_files, options): error_code = 0 for tcl_file in tcl_files: - script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset + script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset script += 'cd %s/%s\n' % (outputdir, hdllib.quartus_sh_ip_srcdir) script += 'set -o pipefail\n' # echo line without 'Info:' to make sure grep it's exit code is 0 script += '(echo " " ; quartus_sh %s %s -t %s 2>&1) | grep -iv Info:\n' \ - % (options, extra_options, tcl_file) + % (options, extra_options, tcl_file) script += 'exit_code=$?\n' script += 'exit $exit_code\n' # execute script @@ -122,8 +123,16 @@ def run_quartus_sh(buildset, outputdir, hdllib, tcl_files, options): print("*** Error during generation, exitcode={}\n".format(return_code)) error_code |= return_code return error_code - - + + +def expand_all_vars(dir_name): + _dirname = dir_name + while '$' in _dirname: + # print(_dirname) + _dirname = expandvars(_dirname) + return _dirname + + if __name__ == '__main__': # setup parser and parse the arguments. argparser = ArgumentParser(description='Generate the IP libraries for all technologies of the given buildset') @@ -140,8 +149,8 @@ if __name__ == '__main__': buildset_info.resolve_key_references() # read in all hdllib configfiles - root_dirs = [ expandvars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t"," ").split(" ") - if rootdir != '' ] + root_dirs = [expand_all_vars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ") + if rootdir != ''] lib_tree = HdlLibTree(rootdirs=root_dirs, filename="hdllib.cfg", sections="generate_ip_libs") # read in the tool environment settings @@ -149,7 +158,8 @@ if __name__ == '__main__': print('tool_config_file={}'.format(tool_config_file)) tool_info = HdlTool(tool_config_file) tool_info.resolve_key_references() - ip_tools = [ tool for tool in tool_info.ip_tools.replace("\t"," ").split(" ") if tool != '' ] + ip_tools = [tool for tool in tool_info.ip_tools.replace("\t", " ").split(" ") + if tool != ''] files_with_errors = [] for technology in listify(buildset_info.technology_names): @@ -160,7 +170,7 @@ if __name__ == '__main__': tool_options = tool_info['{}_default_options'.format(ip_tool)] ip_tool_key = "{}_ip_files".format(ip_tool) # for all hdllib.cfg files found - for ip_lib_name in sorted(lib_tree.configfiles.keys())[::-1]: #TODO reverse order issue! + for ip_lib_name in sorted(lib_tree.configfiles.keys())[::-1]: # TODO reverse order issue! ip_lib_info = lib_tree.configfiles[ip_lib_name] # if technology matches and there are files defined for the current tool if ip_lib_info.hdl_lib_technology == technology and ip_tool_key in ip_lib_info.content: @@ -168,16 +178,16 @@ if __name__ == '__main__': print("==> Processing {} with {}".format(ip_lib_info.ID, ip_tool)) outputdir = os.path.join(os.getenv('HDL_BUILD_DIR'), '{}/{}'.format(args.buildset, ip_tool)) mkdir(outputdir) - vhdl_files = [ name for name in ip_lib_info[ip_tool_key].replace("\t"," ").split(" ") \ - if name != '' ] + vhdl_files = [name for name in ip_lib_info[ip_tool_key].replace("\t", " ").split(" ") + if name != ''] if ip_tool == 'qmegawiz': - err_code = run_qmegawiz (args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options) + err_code = run_qmegawiz(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options) elif ip_tool == 'qsys-generate': - err_code = run_qsys (args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options) + err_code = run_qsys(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options) elif ip_tool == 'quartus_sh': err_code = run_quartus_sh(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options) else: - raise NameError("Hdllib file in %s contains a unknown tool (%s) for generating IP." % + raise NameError("Hdllib file in %s contains a unknown tool (%s) for generating IP." % (ip_lib_info.ID, ip_tool)) if err_code: files_with_errors.append(ip_lib_info.ID) @@ -187,4 +197,3 @@ if __name__ == '__main__': print(" ", files_with_errors) else: print("+++++ No errors during compilation! +++++\n") - diff --git a/core/hdl_configfile.py b/core/hdl_configfile.py index f6294d31c4683a1c57550f70902fd0cda3944061..0535ff31ad8bc900bdd0cfc6304990a6f4ddabea 100644 --- a/core/hdl_configfile.py +++ b/core/hdl_configfile.py @@ -23,7 +23,7 @@ from configfile import ConfigFile -__all__ = [ 'HdlTool', 'HdlBuildset', 'HdlLib'] +__all__ = ['HdlTool', 'HdlBuildset', 'HdlLib'] class HdlTool(ConfigFile): @@ -44,9 +44,9 @@ class HdlBuildset(ConfigFile): """ Class the represents the content of a hdl_buildset_<buildset>.cfg configuration file. """ - _HDLBUILDSET_ATTRIBUTES = [ 'buildset_name', 'technology_names', 'family_names', 'block_design_names', + _HDLBUILDSET_ATTRIBUTES = ['buildset_name', 'technology_names', 'family_names', 'block_design_names', 'lib_root_dirs', 'sim_tool_name', 'sim_tool_version', - 'synth_tool_name', 'synth_tool_version' ] + 'synth_tool_name', 'synth_tool_version'] def __init__(self, filename, sections=None): """ @@ -65,9 +65,9 @@ class HdlLib(ConfigFile): """ Class the represents the content of a hdllib.cfg configuration file. """ - _HDLLIB_ATTRIBUTES = [ 'hdl_lib_name', 'hdl_library_clause_name', 'hdl_lib_uses_synth', - 'hdl_lib_uses_sim', 'hdl_lib_technology', 'synth_files', - 'test_bench_files' ] + _HDLLIB_ATTRIBUTES = ['hdl_lib_name', 'hdl_library_clause_name', 'hdl_lib_uses_synth', + 'hdl_lib_uses_sim', 'hdl_lib_technology', 'synth_files', + 'test_bench_files'] def __init__(self, filename, sections=None): """ @@ -80,6 +80,3 @@ class HdlLib(ConfigFile): def ID(self): "Returns uniq ID (string) to identify this particular file." return self.hdl_lib_name - - - diff --git a/core/hdl_configtree.py b/core/hdl_configtree.py index 8ace60dec551e1dd7e5a6997e44da520a55a3c7c..dfc19444de43af028a4114383137dae33ffba855 100644 --- a/core/hdl_configtree.py +++ b/core/hdl_configtree.py @@ -24,7 +24,7 @@ from hdl_configfile import HdlTool, HdlBuildset, HdlLib from configtree import ConfigTree -__all__ = [ 'HdlToolTree', 'HdlBuildsetTree', 'HdlLibTree'] +__all__ = ['HdlToolTree', 'HdlBuildsetTree', 'HdlLibTree'] class HdlToolTree(ConfigTree): @@ -73,6 +73,3 @@ class HdlLibTree(ConfigTree): def _factory_constructor(self, full_filename): "Function for returning the readin configfile." return HdlLib(full_filename) - - - diff --git a/core/hdl_libraries_wizard.py b/core/hdl_libraries_wizard.py index 8032e7b892b8f68d56e3e7805ba8c511c018449e..558e6c01fd9d8d972b09f803a07469757dda2cf4 100644 --- a/core/hdl_libraries_wizard.py +++ b/core/hdl_libraries_wizard.py @@ -48,83 +48,87 @@ """ import sys -from os import listdir -from os.path import expandvars, isabs, join, isfile +from os import listdir +from os.path import expandvars, isabs, join, isfile import shutil from distutils.dir_util import copy_tree -from argparse import ArgumentParser +from argparse import ArgumentParser import collections import common_radiohdl as cm -from configfile import ConfigFile -from hdl_configfile import HdlBuildset -from hdl_configtree import HdlLibTree +from configfile import ConfigFile +from hdl_configfile import HdlBuildset +from hdl_configtree import HdlLibTree + +__all__ = ['HdlLibrariesWizard'] -__all__ = [ 'HdlLibrariesWizard' ] class HdlLibrariesWizard: def __init__(self, toolRootDir, toolFileName, libFileName='hdllib.cfg', libFileSections=None): """Get tool dictionary info from toolRootDir and all HDL library dictionary info for it - + - self.tool.dicts = single dictionary that contains the tool info (only one tool dict in dicts list) - self.libs.dicts = list of dictionaries that contains the info of the HDL libraries. - + The libRootDir parameter is defined in the hdl_buildset_<buildset>.cfg file and is the root directory from where the hdllib.cfg files are searched for. - + - self.lib_names = the library names of self.libs.dicts In parallel to the self.libs.dicts list of dictionaries a list of self.lib_names is created to be able to identify a HDL library dict also by its library name. Iherefore it is important that the indexing of parallel lists remains intact at all times. - + - self.technologyNames = the technologyNames parameter is defined in the hdl_buildset_<buildset>.cfg file. All generic HDL libraries and these technology specific libraries are kept. If self.technologyNames is: [] : Keep all HDL libraries that were found. ['ip_stratixiv', 'ip_arria10'] : The HDL libraries with a hdl_lib_technology that is not '' or does not match one of the technologies in technologyNames are removed from the list of HDL library dictionaries. - + - self.removed_libs = contains the HDL library dicts that have been removed from self.libs.dicts, because they are for a technology that is not within technologyNames. - + Keep lists of all unavailable library names that were found at the hdl_lib_uses_synth, hdl_lib_uses_ip, hdl_lib_uses_sim and hdl_lib_include_ip keys in the self.libs.dicts: - + - self.unavailable_use_libs = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs - self.unavailable_include_ip_libs - + Unavailable used libraries can be missing for a valid reason when they are not required (e.g. IP for another technology). Being able to ignore missing libraries does require that the entities from these libraries are instantiated as components in the VHDL. The difference between a removed library and an unavailable library is that for a removed library the HDL config information is still known, whereas for an unavailable library it is not. Therefore the library clause names for referred but unavailable HDL libraries are disclosed at the 'hdl_lib_disclose_library_clause_names' keys of the libraries that use them and kept in a dictionary: - + - self.disclosed_library_clause_names - + """ - print("HdlLibrariesWizard(toolRootDir=%s, toolFileName=%s, libFileName=%s, libFileSections=%s)" % \ - (toolRootDir, toolFileName, libFileName, libFileSections)) + print("HdlLibrariesWizard(toolRootDir=%s, toolFileName=%s, libFileName=%s, libFileSections=%s)" + % (toolRootDir, toolFileName, libFileName, libFileSections)) self.toolRootDir = toolRootDir # TODO almost obsolete - + # read the buildset file. This file contains major information about paths, technologies, and so on full_buildsetfile_name = "%s/%s" % (toolRootDir, toolFileName) buildset_info = HdlBuildset(full_buildsetfile_name) buildset_info.resolve_key_references() self.buildset = buildset_info.content - + # HDL library config files - self.libRootDirs = [ expandvars(rootdir) for rootdir in self.buildset['lib_root_dirs'].replace("\t"," ").split(" ") - if rootdir != '' ] - self.libs = HdlLibTree(rootdirs = self.libRootDirs, - filename = libFileName, - sections = libFileSections) # library dict files - if len(self.libs.configfiles) == 0: + self.libRootDirs = [expandvars(rootdir) for rootdir in self.buildset['lib_root_dirs'].replace("\t", " ").split(" ") + if rootdir != ''] + self.libs = HdlLibTree(rootdirs=self.libRootDirs, + filename=libFileName, + sections=libFileSections) # library dict files + if len(self.libs.configfiles) == 0: sys.exit('Error : No HDL library config files found') print("Found %d hdllib files:" % len(self.libs.configfiles)) - + # Substitute key words occurring in hdllib.cfg files with their value. self.substitute_key_words() - + + self.familyNames = self.buildset['family_names'].split() + print("### self.familyNames = ", self.familyNames) + # Keep the generic HDL libraries and remove those that do not match the specified IP technologies self.technologyNames = self.buildset['technology_names'].split() print("### self.technologyNames = ", self.technologyNames) @@ -133,14 +137,14 @@ class HdlLibrariesWizard: techname = self.libs.configfiles[cfglib_name]['hdl_lib_technology'] if (techname != '' and techname not in self.technologyNames): # keep the removed libs we need the content of those libs later. - self.removed_libs[cfglib_name]=self.libs.configfiles[cfglib_name] + self.removed_libs[cfglib_name] = self.libs.configfiles[cfglib_name] self.libs.remove_files_from_tree(list(self.removed_libs.keys())) print(len(self.removed_libs), "REMOVED LIBS:", sorted(self.removed_libs)) - + # Keep list of used HDL library names self.lib_names = list(self.libs.configfiles.keys()) print(len(self.lib_names), "KEPT LIBS:", sorted(self.lib_names)) - + # No need to check for duplicates since HdlLibTree did that already. # create dictionary of library names with library clause names that are disclosed at the 'hdl_lib_disclose_library_clause_names' keys. @@ -177,25 +181,25 @@ class HdlLibrariesWizard: include_ip_libs = lib.get_value('hdl_lib_include_ip').split() for use_name in use_synth_libs: if (use_name not in self.lib_names) and (use_name not in self.removed_libs): - lib['hdl_lib_uses_synth']=cm.remove_from_list_string(lib['hdl_lib_uses_synth'], use_name) + lib['hdl_lib_uses_synth'] = cm.remove_from_list_string(lib['hdl_lib_uses_synth'], use_name) self.unavailable_use_synth_libs.append(use_name) if use_name not in list(self.disclosed_library_clause_names.keys()): sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_synth' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name)) for use_name in use_ip_libs: if (use_name not in self.lib_names) and (use_name not in self.removed_libs): - lib['hdl_lib_uses_ip']=cm.remove_from_list_string(lib['hdl_lib_uses_ip'], use_name) + lib['hdl_lib_uses_ip'] = cm.remove_from_list_string(lib['hdl_lib_uses_ip'], use_name) self.unavailable_use_ip_libs.append(use_name) if use_name not in list(self.disclosed_library_clause_names.keys()): sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_ip' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name)) for use_name in use_sim_libs: if (use_name not in self.lib_names) and (use_name not in self.removed_libs): - lib['hdl_lib_uses_sim']=cm.remove_from_list_string(lib['hdl_lib_uses_sim'], use_name) + lib['hdl_lib_uses_sim'] = cm.remove_from_list_string(lib['hdl_lib_uses_sim'], use_name) self.unavailable_use_sim_libs.append(use_name) if use_name not in list(self.disclosed_library_clause_names.keys()): sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_sim' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name)) for use_name in include_ip_libs: if (use_name not in self.lib_names) and (use_name not in self.removed_libs): - lib['hdl_lib_include_ip']=cm.remove_from_list_string(lib['hdl_lib_include_ip'], use_name) + lib['hdl_lib_include_ip'] = cm.remove_from_list_string(lib['hdl_lib_include_ip'], use_name) self.unavailable_include_ip_libs.append(use_name) if use_name not in list(self.disclosed_library_clause_names.keys()): sys.exit("Error : Unavailable library %s at 'hdl_lib_include_ip' key in library %s is not disclosed at any 'hdl_lib_disclose_library_clause_names' key" % (use_name, lib_name)) @@ -206,7 +210,7 @@ class HdlLibrariesWizard: self.unavailable_include_ip_libs = cm.unique(self.unavailable_include_ip_libs) # list of include_ip_use_libs self.unavailable_use_libs = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs self.unavailable_use_libs = cm.unique(self.unavailable_use_libs) # aggregate list of use_*_libs - + # The Key value pairs defined in hdltool<buildset>.cfg can be used in hdllib.cfg files. See hdllib.cfg of technology library def substitute_key_words(self): for lib in list(self.libs.configfiles.values()): @@ -214,31 +218,31 @@ class HdlLibrariesWizard: for tool_key, tool_value in list(self.buildset.items()): tool_key_string = '<%s>' % tool_key if tool_key_string in lib_value: - lib[lib_key] = lib_value.replace(tool_key_string,tool_value) + lib[lib_key] = lib_value.replace(tool_key_string, tool_value) def check_library_names(self, check_lib_names, lib_names=None): """Check that HDL library names exists within the list of library names, if not then exit with Error message. The list of library names can be specified via the argument lib_names, or it defaults to the list of self.lib_names of HDL libraries that were found in the toolRootDir for the libFileName of this object. """ - if lib_names==None: lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names for check_lib_name in cm.listify(check_lib_names): if check_lib_name not in cm.listify(lib_names): sys.exit('Error : Unknown HDL library name %s found with %s' % (check_lib_name, cm.method_name())) - def get_used_libs(self, build_type, lib_dict, arg_include_ip_libs=[]): """Get the list of used HDL libraries from the lib_dict that this library directly depends on, so only at this HDL library hierachy level. - + Which libraries are actually used depends on the build_type. The build_type can be: '' uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict 'sim' uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict 'synth' uses all libraries from 'hdl_lib_uses_synth' in the lib_dict and from 'hdl_lib_uses_ip' it only uses the IP libraries that are mentioned in the local 'hdl_lib_include_ip' key or in the global arg_include_ip_libs - + The 'hdl_lib_uses_*' keys all appear locally in the same hdllib.cfg file. The 'hdl_lib_include_ip' key appears at this level or at a higher level (design) library hdllib.cfg file to select which of all available 'hdl_lib_uses_ip' IP libraries will actually be - used in the design. The 'hdl_lib_include_ip' cannot appear in a lower level hdllib.cfg, because a lower level HDL library cannot + used in the design. The 'hdl_lib_include_ip' cannot appear in a lower level hdllib.cfg, because a lower level HDL library cannot depend on a higher level HDL library. Therefore the IP libraries that need to be included from 'hdl_lib_uses_ip' will be known in include_ip_libs. """ @@ -255,15 +259,15 @@ class HdlLibrariesWizard: use_sim_libs += lib_dict['hdl_lib_uses_sim'].split() if 'hdl_lib_include_ip' in lib_dict.content: include_ip_libs = lib_dict['hdl_lib_include_ip'].split() - + # Append include_ip_libs from this level to the global list of arg_include_ip_libs include_ip_libs = list(arg_include_ip_libs) + include_ip_libs - + # Get the actually use_libs for lib_dict use_libs = use_synth_libs + use_ip_libs + use_sim_libs # default include all IP, so ignore include_ip_libs - if build_type=='sim': + if build_type == 'sim': use_libs = use_synth_libs + use_ip_libs + use_sim_libs # for simulation included all IP, so ignore include_ip_libs - if build_type=='synth': + if build_type == 'synth': use_libs = use_synth_libs # For synthesis only keep the local use_ip_libs if it is mentioned in the global include_ip_libs. Vice versa also only # include the global include_ip_libs if they appear in a local use_ip_libs, to avoid that an IP library that is mentioned @@ -283,22 +287,21 @@ class HdlLibrariesWizard: for use_name in list(include_ip_libs): if use_name in self.removed_libs: include_ip_libs.remove(use_name) - + return use_libs, include_ip_libs - - + def derive_all_use_libs(self, build_type, lib_name, arg_include_ip_libs=[]): """Recursively derive a complete list of all HDL libraries that the specified HDL lib_name library depends on, so from this HDL library down the entire hierachy. - + The hdl_lib_uses_* key only needs to contain all libraries that are declared at the VHDL LIBRARY clauses of the source files in this VHDL library. This derive_all_use_libs() will recursively find all deeper level VHDL libraries as well. - + The arg_include_ip_libs selects the IP library to keep from 'hdl_lib_uses_ip'. The include_ip_libs is passed on through the recursion hierarchy via arg_include_ip_libs to ensure that the from the top level library down all multiple choice IP libraries in 'hdl_lib_uses_ip' that need to be included are indeed included. The multiple choice IP libraries in 'hdl_lib_uses_ip' that are not in include_ip_libs are excluded. - + Note: . Only the generic HDL libraries and the technology specific libraries that match self.technologyNames are used, because the other technology libraries have been removed from self.libs.dicts already at __init__() and from the @@ -312,7 +315,7 @@ class HdlLibrariesWizard: all_use_libs = [lib_name] lib_dict = self.libs.configfiles[lib_name] use_libs, include_ip_libs = self.get_used_libs(build_type, lib_dict, include_ip_libs) - + for use_lib in use_libs: if use_lib not in all_use_libs: all_use_libs.append(use_lib) @@ -322,15 +325,14 @@ class HdlLibrariesWizard: return cm.unique(all_use_libs) else: sys.exit('Error : Unknown HDL library name %s in %s()' % (lib_name, cm.method_name())) - - + def derive_lib_order(self, build_type, lib_name, lib_names=None): """Derive the dependency order for all HDL libraries in lib_names that HDL library lib_name depends on. """ - if lib_names==None: + if lib_names is None: # At first entry derive the list of all HDL libraries that lib_name depends on lib_names = self.derive_all_use_libs(build_type, lib_name) - + # Derive the order of all HDL libraries that lib_name depends on, start with the order of lib_names lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names) # use list() to take local copy to avoid modifying list order of self.lib_names which matches self.libs.dicts list order @@ -347,44 +349,41 @@ class HdlLibrariesWizard: if lib_names != lib_order: lib_order = self.derive_lib_order(build_type, lib_name, lib_order) return lib_order - def get_lib_dicts_from_lib_names(self, lib_names=None): """Get list the HDL libraries lib_dicts from list of HDL libraries lib_names and preseve the library order. """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names # Cannot use: - #lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names) + # lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names) # because then the order of self.libs.dicts is used lib_dicts = [] for lib_name in cm.listify(lib_names): lib_dicts.append(self.libs.configfiles[lib_name]) return lib_dicts - def get_lib_names_from_lib_dicts(self, lib_dicts=None): """Get list the HDL libraries lib_names from list of HDL libraries lib_dicts and preseve the library order. """ lib_names = self.libs.get_key_values('hdl_lib_name', lib_dicts) return lib_names - def get_tool_build_dir(self, build_type): """Get the central tool build directory. - + The build_type can be: 'sim' uses the 'sim_tool_name' key in the self.buildset 'synth' uses the 'synth_tool_name' key in the self.buildset When another name is used that name is used directly as toolname in the construction of the path. - + The function returns a tuple with the following four components: - the absolute path to the central main build directory - the buildset_name key value as subdirectory - the toolname as subdirectory (derived from *_tool_name or the given value of 'build_type') - project_deeper_subdir. See explanation below. - + The project file will be located in the build dir or at some levels deeper in the build dir. These optional extra subdirectory levels allow for relative file reference from project file location. This is useful to be able to keep memory initialisation files in the library build @@ -417,15 +416,14 @@ class HdlLibrariesWizard: project_deeper_subdir = 'p/' * int(self.buildset[project_dir_depth_key]) return build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir - def get_lib_build_dirs(self, build_type, lib_dicts=None): """Get the subdirectories within the central tool build directory for all HDL libraries in the specified list of lib_dicts. - + The build_type can be: 'sim' uses the 'sim_tool_name' key in the self.buildset 'synth' uses the 'synth_tool_name' key in the self.buildset - + The build dir key value must be an absolute directory path. The lib build dir consists of - the absolute path to the central main build directory - the buildset_name key value as subdirectory @@ -433,7 +431,7 @@ class HdlLibrariesWizard: - the library name as library subdirectory - zero or more extra subdirectory levels to allow for relative file reference from project file location """ - if lib_dicts==None: + if lib_dicts is None: lib_dicts = list(self.libs.configfiles.values()) build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type) build_dirs = [] @@ -441,16 +439,15 @@ class HdlLibrariesWizard: lib_name = lib_dict['hdl_lib_name'] build_dirs.append(join(build_maindir, build_buildset_dir, build_tooldir, lib_name, project_deeper_subdir)) # central build main directory with subdirectory per library return cm.unlistify(build_dirs) - def create_lib_order_files(self, build_type, lib_names=None): """Create the compile order file '<lib_name>_lib_order.txt' for all HDL libraries in the specified list of lib_names. - + The file is stored in the sim build directory of the HDL library. The file is read by commands.do in Modelsim to avoid having to derive the library compile order in TCL. """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) for lib_dict in lib_dicts: @@ -479,19 +476,19 @@ class HdlLibrariesWizard: build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type) subdir_path = join(build_maindir, build_buildset_dir, subdir_name) cm.mkdir(subdir_path) - + def create_sub_directory_in_build_tool_dir(self, build_type, subdir_name): """Create <subdir_name>/ in the central <build_main>/<build_buildset_dir>/<build_tooldir>/ directory. """ build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type) subdir_path = join(build_maindir, build_buildset_dir, build_tooldir, subdir_name) cm.mkdir(subdir_path) - + def create_sub_directory_in_build_lib_dir(self, build_type, subdir_name, lib_names=None): """Create <subdir_name>/ in project local build directory <lib_name>/ for all HDL libraries in the specified list of lib_names. """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names) for lib_dict in lib_dicts: lib_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict) @@ -509,12 +506,12 @@ class HdlLibrariesWizard: where the hdllib.cfg is stored - The destinations need to be specified with absolute path or relative to HDL library build directory where the project file (e.g. mpf, qpf) gets stored - + Arguments: - lib_names : zero or more HDL libraries """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) tool_name_key = build_type + '_tool_name' @@ -547,32 +544,32 @@ class HdlLibrariesWizard: if __name__ == '__main__': # Parse command line arguments - buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(expandvars('$RADIOHDL_CONFIG')) - if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) + buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(expandvars('$RADIOHDL_CONFIG')) + if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) argparser = ArgumentParser(description='Hdl_config shows several selections of all of your hdllib.cfg files.') argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect)) argparser.add_argument('--toplib', default=None, required=False, help='top library to show more information about.') args = argparser.parse_args() - + # check arguments if args.buildset not in buildsetSelect: print('buildset %s is not supported' % args.buildset) print("Supported buildset are:", buildsetSelect) sys.exit(1) args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg' - + # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories - hdl = HdlLibrariesWizard(toolRootDir = expandvars('${RADIOHDL_CONFIG}'), - toolFileName = args.buildsetFile, - libFileName = 'hdllib.cfg') - + hdl = HdlLibrariesWizard(toolRootDir=expandvars('${RADIOHDL_CONFIG}'), + toolFileName=args.buildsetFile, + libFileName='hdllib.cfg') + print('#') print('# HdlLibrariesWizard:') print('#') for libname in list(hdl.libs.configfiles.keys()): print("\n", libname) libinfo = hdl.libs.configfiles[libname] - for k,v in libinfo.content.items(): + for k, v in libinfo.content.items(): print(k, '=', v) print('') @@ -588,7 +585,7 @@ if __name__ == '__main__': print('') print('Library section headers :') - for libname,libinfo in hdl.libs.configfiles.items(): + for libname, libinfo in hdl.libs.configfiles.items(): print(' %-52s : %s' % (libname, libinfo['section_headers'])) print('') @@ -620,10 +617,10 @@ if __name__ == '__main__': if args.toplib: for build_type in ['sim', 'synth']: print('') - print('derive_all_use_libs for %s of %s = \n' % (build_type, args.toplib), \ - hdl.derive_all_use_libs(build_type, args.toplib)) + print('derive_all_use_libs for %s of %s = \n' + % (build_type, args.toplib), hdl.derive_all_use_libs(build_type, args.toplib)) print('') - print('derive_lib_order for %s of %s = \n' % (build_type, args.toplib), \ - hdl.derive_lib_order(build_type, args.toplib)) + print('derive_lib_order for %s of %s = \n' + % (build_type, args.toplib), hdl.derive_lib_order(build_type, args.toplib)) diff --git a/core/hdl_raw_access.py b/core/hdl_raw_access.py index 90fb80574512331cbe7e61054edec68bfe8651fa..f12daf3d81ef0eff28d969a54a6a9a1eeb96c8cc 100644 --- a/core/hdl_raw_access.py +++ b/core/hdl_raw_access.py @@ -26,7 +26,7 @@ import os.path from configfile import * from configtree import ConfigTree -__all__ = [ 'RawConfigFile', 'RawConfigTree' ] +__all__ = ['RawConfigFile', 'RawConfigTree'] """ File that implements the configfile <-> configtree concept but this time with the @@ -34,6 +34,7 @@ intention to modify the keys and/or values in those configfiles. So the content the configfiels is kept as raw as possible. """ + class RawConfigFile(object): """ Class that holds the raw content of a configfile. To simplify the manipulation of the @@ -46,7 +47,7 @@ class RawConfigFile(object): """ full_filename = os.path.expanduser(os.path.expandvars(filename)) if not os.path.isfile(full_filename): - raise ConfigFileException ("configfile '%s' not found" % full_filename) + raise ConfigFileException("configfile '%s' not found" % full_filename) self.filename = full_filename self.content = open(self.filename, 'r').readlines() @@ -66,7 +67,6 @@ class RawConfigFile(object): if verbose: print(self.filename) - def change_value(self, key, new_value, verbose): """ Change the value of the given key. The old value may be empty, be on one or multiple lines. @@ -89,27 +89,24 @@ class RawConfigFile(object): # sectionheader|other key|empty line or are at the end of the file linenr += 1 while linenr < len(self.content): - if not re.match(r"(\[[a-zA-Z0-9_]+\]|[a-zA-Z0-9_]+[ \t]*{}|^[ \t]*$)".format(CFG_ASSIGNMENT_CHAR), - self.content[linenr]): - self.content.pop(linenr) - else: - break + if not re.match(r"(\[[a-zA-Z0-9_]+\]|[a-zA-Z0-9_]+[ \t]*{}|^[ \t]*$)".format(CFG_ASSIGNMENT_CHAR), self.content[linenr]): + self.content.pop(linenr) + else: + break self._save_content(verbose) break - def append_key_value(self, key, value, verbose): """ Append the given key and value to the end of the configfile. \n characters can be used both in the key and the value to start at a new line. """ - self.content.append("{} {} {}\n".format(key.replace("\\n","\n"), + self.content.append("{} {} {}\n".format(key.replace("\\n", "\n"), CFG_ASSIGNMENT_CHAR, - value.replace("\\n","\n"))) + value.replace("\\n", "\n"))) self._save_content(verbose) - def rename_key(self, old_key, new_key, verbose): """ Change the name of a key. @@ -129,7 +126,7 @@ class RawConfigFile(object): self._save_content(verbose) break - def remove_key(self, key,verbose): + def remove_key(self, key, verbose): """ Remove a key and value pair from the dictfile. """ @@ -153,15 +150,14 @@ class RawConfigFile(object): # not searching for the key anymore, we now have to find the and of the value. # to support removing old multiline values we have to skip lines until we find a # sectionheader|other key or are at the end of the file - if not end_of_value_mask.match(self.content[linenr]): - continue - last_line = linenr - break + if not end_of_value_mask.match(self.content[linenr]): + continue + last_line = linenr + break del self.content[first_line:last_line] self._save_content(verbose) - def insert_key_at_linenr(self, new_key, new_value, linenumber, verbose): """ Insert a new key = value pair in the configfile at linenumber. The first line has number 1. @@ -174,7 +170,6 @@ class RawConfigFile(object): self.content.insert(linenumber-1, new_line) self._save_content(verbose) - def insert_key_value_before_key(self, new_key, new_value, before_key, verbose): """ Insert a new key = value pair in the configfile just before another key.. @@ -204,6 +199,3 @@ class RawConfigTree(ConfigTree): def _factory_constructor(self, full_filename): "Function for returning the readin configfile." return RawConfigFile(full_filename) - - - diff --git a/core/modelsim_config b/core/modelsim_config index b6e431074cf1318adcd1d06b83f625b2b96f11fe..4d61e7cff5f45e2cd32a13d6399155398fee1a25 100755 --- a/core/modelsim_config +++ b/core/modelsim_config @@ -28,49 +28,50 @@ import sys import os.path -from os import listdir -from argparse import ArgumentParser +from os import listdir +from argparse import ArgumentParser import common_radiohdl as cm import hdl_libraries_wizard from configfile import ConfigFile + class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): def __init__(self, toolRootDir, buildsetFile, libFileName): """Get Modelsim tool info from toolRootDir and all HDL library info from libRootDir. - + This class uses the default keys and the keys from the libFileSections in the libFileName config file. - + Arguments: - toolRootDir : Root directory from where the hdl_buildset_<buildset>.cfg file is searched for. - buildsetFile : Default HDL tools configuration file name - libFileName : Default HDL library configuration file name - + The libRootDir is defined in the hdl_buildset_<buildset>.cfg file and is the root directory from where the hdllib.cfg files are searched for. - + Files: - hdl_buildset_<buildset>.cfg : HDL tool configuration dictionary file. One central file per buildset. - + - hdllib.cfg : HDL library configuration dictionary file. One file for each HDL library. - + - modelsim_project_files.txt The modelsim_project_files.txt file is a dictionary file with the list the Modelsim project files for all HDL libraries that were found in the libRootDir. The keys are the library names and the values are the paths to the corresponding modelsim project files. The modelsim_project_files.txt file is created by create_modelsim_project_files_file() and is read by the TCL commands.do file in Modelsim. Creating the file in Python and then reading this in TCL makes the commands.do much simpler. - + - <lib_name>.mpf : Modelsim project file for a certain HDL library based on the hdllib.cfg. The file is created by create_modelsim_project_file(). - + - <lib_name>_lib_order.txt The <lib_name>_lib_order.txt file contains the library compile order for a certain HDL library. The files are created by create_lib_order_files() in the same build directory as where the Modelsim project file is stored. The <lib_name>_lib_order.txt files are read by the TCL commands.do file in Modelsim. Creating the files in Python and then reading them in TCL makes the commands.do much simpler. """ - libFileSections=['modelsim_project_file'] + libFileSections = ['modelsim_project_file'] hdl_libraries_wizard.HdlLibrariesWizard.__init__(self, toolRootDir, buildsetFile, libFileName, libFileSections) def read_compile_order_from_mpf(self, mpfPathName): @@ -81,9 +82,9 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): with open(mpfPathName, 'r') as fp: for line in fp: words = line.split() - if len(words)>0: + if words: key = words[0] - if key.find('Project_File_')>=0 and key.find('Project_File_P_')==-1: + if key.find('Project_File_') >= 0 and key.find('Project_File_P_') == -1: project_file_indices.append(key[len('Project_File_'):]) project_file_names.append(words[2]) # read <mpfPathName>.mpf again to find compile order for the project files @@ -91,26 +92,26 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): with open(mpfPathName, 'r') as fp: for line in fp: words = line.split() - if len(words)>0: + if words: key = words[0] - if key.find('Project_File_P_')>=0: + if key.find('Project_File_P_') >= 0: project_file_index = project_file_indices.index(key[len('Project_File_P_'):]) project_file_name = project_file_names[project_file_index] k = words.index('compile_order') - k = int(words[k+1]) - compile_order[k]=project_file_name + k = int(words[k + 1]) + compile_order[k] = project_file_name return compile_order def read_hdl_libraries_technology_file(self, technologyName, filePath=None): """Read the list of technology HDL libraries from a file. - + Arguments: - technologyName : refers to the hdl_libraries_<technologyName>.txt file - filePath : path to hdl_libraries_<technologyName>.txt, when None then the file is read in the default toolRootDir """ - fileName = 'hdl_libraries_' + technologyName + '.txt' # use fixed file name format - if filePath==None: + fileName = 'hdl_libraries_ip_' + technologyName + '.txt' # use fixed file name format + if filePath is None: toolDir = os.path.expandvars('$HDL_BUILD_DIR') toolSubDir = self.buildset['buildset_name'] fileNamePath = os.path.join(toolDir, toolSubDir, fileName) # default file path @@ -118,18 +119,17 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): fileNamePath = os.path.join(filePath, fileName) # specified file path tech_dict = ConfigFile(fileNamePath).content return tech_dict - - + def create_modelsim_lib_compile_ip_files(self, lib_names=None): """ Create the '<lib_name>_lib_compile_ip.txt' file for all HDL libraries in the specified list of lib_names. The file is stored in the sim build directory of the HDL library. The file is read by commands.do in Modelsim to know which IP needs to be compiled before the library is compiled. """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names - count = 0 + count = 0 lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) for lib_dict in lib_dicts: if 'modelsim_compile_ip_files' in lib_dict.content: @@ -147,7 +147,6 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): efpn = os.path.expandvars(fpn) fp.write('%s ' % efpn) print("Created {} compile-ip files".format(count)) - def simulation_configuration(self, list_mode=False): """Prepare settings for simulation configuration. @@ -156,7 +155,7 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): """ # project_sim_p_defaults project_sim_p_defaults = 'Generics {} timing default -std_output {} -nopsl 0 +notimingchecks 0 selected_du {} -hazards 0 -sdf {} ok 1 -0in 0 -nosva 0 +pulse_r {} -absentisempty 0 -multisource_delay {} +pulse_e {} vopt_env 1 -coverage 0 -sdfnoerror 0 +plusarg {} -vital2.2b 0 -t default -memprof 0 is_vopt_flow 0 -noglitch 0 -nofileshare 0 -wlf {} -assertdebug 0 +no_pulse_msg 0 -0in_options {} -assertfile {} -sdfnowarn 0 -Lf {} -std_input {}' - + # project_sim_p_search_libraries if list_mode: project_sim_p_search_libraries = self.buildset['modelsim_search_libraries'].split() @@ -168,7 +167,7 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): project_sim_p_search_libraries += sl project_sim_p_search_libraries += ' ' project_sim_p_search_libraries += '}' - + # project_sim_p_otherargs # Note: # E.g. the vsim-8684 load warning does not occur when the simulation is loaded via double click, but it @@ -182,21 +181,20 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): project_sim_p_otherargs = otherargs.split() else: project_sim_p_otherargs = 'OtherArgs {' + otherargs + '}' - + # project_sim_p_optimization project_sim_p_optimization = 'is_vopt_opt_used 2' # = when 'Enable optimization' is not selected in GUI project_sim_p_optimization = 'is_vopt_opt_used 1 voptargs {OtherVoptArgs {} timing default VoptOutFile {} -vopt_keep_delta 0 -0in 0 -fvopt {} VoptOptimize:method 1 -vopt_00 2 +vopt_notimingcheck 0 -Lfvopt {} VoptOptimize:list .vopt_opt.nb.canvas.notebook.cs.page1.cs.g.spec.listbox -Lvopt {} +vopt_acc {} VoptOptimize .vopt_opt.nb.canvas.notebook.cs.page1.cs -vopt_hazards 0 VoptOptimize:Buttons .vopt_opt.nb.canvas.notebook.cs.page1.cs.g.spec.bf 0InOptionsWgt .vopt_opt.nb.canvas.notebook.cs.page3.cs.zf.ze -0in_options {}}' # = when 'Enable optimization' is selected in GUI for full visibility - - return project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization + return project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization def create_modelsim_project_file(self, lib_names=None): """ Create the Modelsim project file for all technology libraries and RTL HDL libraries. - + Arguments: - lib_names : one or more HDL libraries - + Library mapping: - Technology libraries that are available, but not used are mapped to work. - Unavailable libraries are also mapped to work. The default library clause name is <lib_name> @@ -206,8 +204,8 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): VHDL for the unavailable HDL library. unavailable library names occur when e.g. a technology IP library is not available in the toolRootDir because it is not needed, or it may indicate a spelling error. """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) print("SELF.BUILDSET=", self.buildset) @@ -223,8 +221,13 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): fp.write('[Library]\n') # . map used vendor technology libs to their target directory - for technologyName in self.technologyNames: - tech_dict = self.read_hdl_libraries_technology_file(technologyName) + # for technologyName in self.technologyNames: + # tech_dict = self.read_hdl_libraries_technology_file(technologyName) + # for lib_clause, lib_work in tech_dict.items(): + # fp.write('%s = %s\n' % (lib_clause, lib_work)) + + for familyName in self.familyNames: + tech_dict = self.read_hdl_libraries_technology_file(familyName) for lib_clause, lib_work in tech_dict.items(): fp.write('%s = %s\n' % (lib_clause, lib_work)) @@ -256,13 +259,13 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): # . others modelsim default libs model_tech_dir = os.path.expandvars(self.buildset['modelsim_dir']) fp.write('others = %s\n' % os.path.join(model_tech_dir, 'modelsim.ini')) - + # Write [Project] section for all used libraries fp.write('[Project]\n') fp.write('Project_Version = 6\n') # must be >= 6 to fit all fp.write('Project_DefaultLib = work\n') fp.write('Project_SortMethod = unused\n') - + # - project files synth_files = lib_dict['synth_files'].split() test_bench_files = lib_dict['test_bench_files'].split() @@ -284,55 +287,58 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): offset = 0 nof_synth_files = len(synth_files) - if nof_synth_files>0: + if nof_synth_files > 0: project_folders.append('synth_files') - for i in range(nof_synth_files): + for i in range(nof_synth_files): # Add file type specific settings file_ext = synth_files[i].split('.')[-1] - if file_ext=='vhd' or file_ext=='vhdl': + if file_ext == 'vhd' or file_ext == 'vhdl': project_file_p_defaults_file_specific = project_file_p_defaults_vhdl - elif file_ext=='v': - project_file_p_defaults_file_specific = project_file_p_defaults_verilog + elif file_ext == 'v': + project_file_p_defaults_file_specific = project_file_p_defaults_verilog else: - print('\nERROR - Undefined file extension in synth_files:', lib_name, synth_files[i]) - sys.exit() + print('\nERROR - Undefined file extension in synth_files:', lib_name, synth_files[i]) + sys.exit() - fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific)) + fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % ( + offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific)) offset = nof_synth_files nof_test_bench_files = len(test_bench_files) - if nof_test_bench_files>0: + if nof_test_bench_files > 0: project_folders.append('test_bench_files') for i in range(nof_test_bench_files): # Add file type specific settings file_ext = test_bench_files[i].split('.')[-1] - if file_ext=='vhd' or file_ext=='vho' or file_ext=='vhdl': + if file_ext == 'vhd' or file_ext == 'vho' or file_ext == 'vhdl': project_file_p_defaults_file_specific = project_file_p_defaults_vhdl - elif file_ext=='v': + elif file_ext == 'v': project_file_p_defaults_file_specific = project_file_p_defaults_verilog else: print('\nERROR - Undefined file extension in test_bench_files:', lib_name, test_bench_files[i]) sys.exit() - fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific)) + fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % ( + offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific)) offset += nof_test_bench_files if 'modelsim_compile_ip_files' in lib_dict.content: nof_compile_ip_files = len(compile_ip_files) - if nof_compile_ip_files>0: + if nof_compile_ip_files > 0: project_folders.append('compile_ip_files') for i in range(nof_compile_ip_files): - fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (offset+i, project_folders[-1], offset+i, project_file_p_defaults_tcl)) + fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % ( + offset + i, project_folders[-1], offset + i, project_file_p_defaults_tcl)) offset += nof_compile_ip_files - + # - project folders fp.write('Project_Folder_Count = %d\n' % len(project_folders)) for i, fd in enumerate(project_folders): fp.write('Project_Folder_%d = %s\n' % (i, fd)) fp.write('Project_Folder_P_%d = folder {Top Level}\n' % i) - + # - simulation configurations fp.write('Project_Sim_Count = %d\n' % len(test_bench_files)) project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization = self.simulation_configuration() @@ -343,8 +349,9 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): for i, fn in enumerate(test_bench_files): fName = os.path.basename(fn) tbName = os.path.splitext(fName)[0] - fp.write('Project_Sim_P_%d = folder {Top Level} additional_dus work.%s %s %s %s %s\n' % (i, tbName, project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization)) - + fp.write('Project_Sim_P_%d = folder {Top Level} additional_dus work.%s %s %s %s %s\n' % ( + i, tbName, project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization)) + # Write [vsim] section fp.write('[vsim]\n') fp.write('RunLength = 0 ps\n') @@ -352,22 +359,22 @@ class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard): fp.write('IterationLimit = 5000\n') # According to 'verror 3601' the default is 5000, typically 100 is enough, but e.g. the ip_stratixiv_phy_xaui_0 requires more. fp.write('DefaultRadix = decimal\n') print("Created {} project files".format(len(lib_dicts))) - + def create_modelsim_project_files_file(self, lib_names=None): """Create file with list of the Modelsim project files for all HDL libraries. - + Arguments: - lib_names : one or more HDL libraries """ fileName = 'modelsim_project_files.txt' # use fixed file name build_maindir, build_buildsetdir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir('sim') - fileNamePath=os.path.join(build_maindir, build_buildsetdir, build_tooldir, fileName) # and use too build dir for file path - if lib_names==None: - lib_names=self.lib_names + fileNamePath = os.path.join(build_maindir, build_buildsetdir, build_tooldir, fileName) # and use too build dir for file path + if lib_names is None: + lib_names = self.lib_names with open(fileNamePath, 'w') as fp: lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) mpf_paths = self.get_lib_build_dirs('sim', lib_dicts=lib_dicts) - for lib_name, mpf_path in zip(cm.listify(lib_names),cm.listify(mpf_paths)): + for lib_name, mpf_path in zip(cm.listify(lib_names), cm.listify(mpf_paths)): fp.write('%s = %s\n' % (lib_name, mpf_path)) print("Created project file {}".format(fileNamePath)) @@ -381,30 +388,30 @@ if __name__ == '__main__': # independent so these may be put in alphabetical order. The compile order is read from the <lib_name>.mpf and saved in the # hdllib.cfg. The hdllib.cfg still does need some manual editing to set the proper key and paths. mode = 0 - - buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(os.path.expandvars('$RADIOHDL_CONFIG')) - if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) + + buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(os.path.expandvars('$RADIOHDL_CONFIG')) + if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) # Parse command line arguments argparser = ArgumentParser(description='Modelsim creates/updates all your modelsim environment(s).') - argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect)) - argparser.add_argument('-v','--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info') + argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect)) + argparser.add_argument('-v', '--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info') args = argparser.parse_args() - + # check arguments if args.buildset not in buildsetSelect: print('buildset %s is not supported' % args.buildset) print("Supported buildset are:", buildsetSelect) sys.exit(1) args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg' - + # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories - msim = ModelsimConfig(toolRootDir = os.path.expandvars('$RADIOHDL_CONFIG'), - buildsetFile = args.buildsetFile, - libFileName = 'hdllib.cfg') - - if mode==0: + msim = ModelsimConfig(toolRootDir=os.path.expandvars('$RADIOHDL_CONFIG'), + buildsetFile=args.buildsetFile, + libFileName='hdllib.cfg') + + if mode == 0: # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories - if args.verbosity>=2: + if args.verbosity >= 2: print('#') print('# ModelsimConfig:') print('#') @@ -412,8 +419,8 @@ if __name__ == '__main__': print('HDL library paths that are found in %s:' % msim.libRootDirs) for lib in sorted(msim.libs.configfiles.values()): print(' ', lib.location) - - if args.verbosity>=2: + + if args.verbosity >= 2: print('') print('Build directories for simulation:') for sim_dir in msim.get_lib_build_dirs('sim'): @@ -422,37 +429,38 @@ if __name__ == '__main__': print('') print('Create library compile order files for simulation...') msim.create_lib_order_files('sim') - sys.exit(0) - + # sys.exit(0) + print('') print('Create library compile ip files...') msim.create_modelsim_lib_compile_ip_files() - + print('') print('Create modelsim projects list file...') msim.create_modelsim_project_files_file() - + print('') print('Create sub directory in project dir for all HDL libraries that are found in %s...' % msim.libRootDirs) msim.create_sub_directory_in_build_lib_dir('sim', 'mmfiles') # should match c_mmf_local_dir_path in mm_file_pkg.vhd - + print('') print('Copy directories and files from HDL library source tree to project dir for all HDL libraries that are found in %s...' % msim.libRootDirs) msim.copy_files('sim') - + print('') print('Create Modelsim Project Files for technology %s and all HDL libraries in %s...' % (msim.technologyNames, msim.libRootDirs)) msim.create_modelsim_project_file() - - if mode==1: - #for lib_name in ['ado','ap','bf','bist','blp','bp','cdo','cim','cir','cp','cr','dc','eth','fmf','i2c','lvds','pfs','pft2','rcuh','ri','rsp','rsr','rsu','sens','serdes','si','st','tbbi','tdsh']: + # sys.exit(0) + + if mode == 1: + # for lib_name in ['ado','ap','bf','bist','blp','bp','cdo','cim','cir','cp','cr','dc','eth','fmf','i2c','lvds','pfs','pft2','rcuh','ri','rsp','rsr','rsu','sens','serdes','si','st','tbbi','tdsh']: for lib_name in ['tst']: # Read compile order from existing <lib_name>.mpf # First manually create rudimentary hdllib.cfg file for the library with lib name and clause filled in. Then run this script to get # the ordered list of src and tb files. Then manualy edit the hdllib.cfg to put the files at the synth or sim key. - #mpfPathName = os.path.expandvars('$UNB/Firmware/designs/%s/build/synth/quartus/sopc_%s_sim/%s.mpf' % (lib_name, lib_name, lib_name)) - #mpfPathName = os.path.expandvars('$UNB/Firmware/modules/Lofar/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name)) - #mpfPathName = os.path.expandvars('$UNB/Firmware/modules/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name)) + # mpfPathName = os.path.expandvars('$UNB/Firmware/designs/%s/build/synth/quartus/sopc_%s_sim/%s.mpf' % (lib_name, lib_name, lib_name)) + # mpfPathName = os.path.expandvars('$UNB/Firmware/modules/Lofar/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name)) + # mpfPathName = os.path.expandvars('$UNB/Firmware/modules/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name)) mpfPathName = os.path.expandvars('$RSP/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name)) compile_order = msim.read_compile_order_from_mpf(mpfPathName) # Append the compile_order list to the lib_name dictionary hdllib.cfg file @@ -462,4 +470,3 @@ if __name__ == '__main__': print('') print('Save modelsim compile order for', lib_name, 'in HDL library config file', filePathName) msim.libs.append_key_to_dict_file(filePathName, 'files', compile_order) - diff --git a/core/modify_configfiles b/core/modify_configfiles index f7de87283a6eddcc78cd813a4140bc79ac616c9f..d7b7cc9f7b7f2966670ce2c20cc2241e3acca0c0 100755 --- a/core/modify_configfiles +++ b/core/modify_configfiles @@ -36,6 +36,7 @@ from hdl_raw_access import RawConfigTree # the remaining elememts (if any) are the arguments to ask the user # All arguments are stored in a kwargs structure and passed to the functions that is called. + def get_menu_choice(menu, title): """ Iterate over the menu dict, show the menu choices and ask for input till valid input is received. @@ -53,6 +54,7 @@ def get_menu_choice(menu, title): input_ok = True return menu[choice] + def execute_menu_line(line_spec, verbose): """ Given a menu line specification it asks the user for the specified arguments, stores the values in a @@ -65,14 +67,14 @@ def execute_menu_line(line_spec, verbose): if nr_args == 0: return line_spec[1]() # Iterate over the remaining items and get values for them - kwargs = { "verbose": verbose } + kwargs = {"verbose": verbose} for spec_idx in range(2, len(line_spec)): answer = input(line_spec[spec_idx].capitalize().replace("_", " ") + ": ") kwargs[line_spec[spec_idx]] = answer line_spec[1](**kwargs) -### Implementation of the menu commands +# ## Implementation of the menu commands # Note: cleaner would to implement this with the Strategy pattern but we want to keep the code # to be readable for everyone. ;-) def change_value_of_key(**kwargs): @@ -83,6 +85,7 @@ def change_value_of_key(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].change_value(key, new_value, verbose) + def append_key_value(**kwargs): key = kwargs.pop("new_key") new_value = kwargs.pop("new_value") @@ -91,6 +94,7 @@ def append_key_value(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].append_key_value(key, new_value, verbose) + def insert_key_at_linenr(**kwargs): new_key = kwargs.pop("new_key") new_value = kwargs.pop("new_value") @@ -100,6 +104,7 @@ def insert_key_at_linenr(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].insert_key_at_linenr(new_key, new_value, linenumber, verbose) + def insert_key_value_before_key(**kwargs): new_key = kwargs.pop("new_key") new_value = kwargs.pop("new_value") @@ -109,6 +114,7 @@ def insert_key_value_before_key(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].insert_key_value_before_key(new_key, new_value, before_key, verbose) + def rename_key(**kwargs): old_key = kwargs.pop("old_key") new_key = kwargs.pop("new_key") @@ -117,6 +123,7 @@ def rename_key(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].rename_key(old_key, new_key, verbose) + def remove_key(**kwargs): key = kwargs.pop("key") verbose = kwargs.pop("verbose") @@ -124,6 +131,7 @@ def remove_key(**kwargs): for filename in sorted(tree.configfiles.keys()): tree.configfiles[filename].remove_key(key, verbose) + def end_menu(): global running running = False @@ -133,7 +141,7 @@ if __name__ == '__main__': # setup parser and parse the arguments. argparser = ArgumentParser(description='Options and arguments for modifying collections of configfiles.') argparser.add_argument('filename', help="Filename like 'hdl_buildset_<boardtype>.cfg'") - argparser.add_argument('rootdir', help="Top directory to start the search for configfiles.") + argparser.add_argument('rootdir', help="Top directory to start the search for configfiles.") argparser.add_argument('-v', '--verbose', help="Show more information on what happens.", action="store_true") args = argparser.parse_args() @@ -142,17 +150,17 @@ if __name__ == '__main__': if args.verbose: for filename in sorted(tree.configfiles.keys()): print(filename) - + # define the menu including actions # choice choice description function to call arguments to ask for - menu = {'1': [ "Change value", change_value_of_key, "key", "new_value"], - '2': [ "Append key", append_key_value, "new_key", "new_value"], - '3': [ "Insert key at linenr", insert_key_at_linenr, "new_key", "new_value", "linenumber"], - '4': [ "Insert key before other key", insert_key_value_before_key, "new_key", "new_value", "before_key"], - '5': [ "Rename key", rename_key, "old_key", "new_key"], - '6': [ "Remove key", remove_key, "key"], - 'q': [ "Exit", end_menu ] - } + menu = {'1': ["Change value", change_value_of_key, "key", "new_value"], + '2': ["Append key", append_key_value, "new_key", "new_value"], + '3': ["Insert key at linenr", insert_key_at_linenr, "new_key", "new_value", "linenumber"], + '4': ["Insert key before other key", insert_key_value_before_key, "new_key", "new_value", "before_key"], + '5': ["Rename key", rename_key, "old_key", "new_key"], + '6': ["Remove key", remove_key, "key"], + 'q': ["Exit", end_menu] + } running = True while running: diff --git a/core/quartus_config b/core/quartus_config index 9ced319b5761ff738e72efa94f72cdd99106c610..a0ee50b66b3664cbd454ec1a23a4a890dc9a07dd 100755 --- a/core/quartus_config +++ b/core/quartus_config @@ -33,54 +33,55 @@ from argparse import ArgumentParser import common_radiohdl as cm import hdl_libraries_wizard + class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): def __init__(self, toolRootDir, toolFileName, libFileName='hdllib.cfg'): """Get Quartus tool info from toolRootDir and all HDL library info from libRootDir. - + This class uses the default keys and the keys from the libFileSections in the libFileName config file. - + Arguments: - toolRootDir : Root directory from where the hdl_buildset_<buildset>.cfg file is searched for. - toolFileName : Default HDL tools configuration file name - libFileName : Default HDL library configuration file name - + The libRootDir is defined in the hdl_buildset_<buildset>.cfg file and is the root directory from where the hdllib.cfg files are searched for. - + The technologyNames parameter is defined in the hdl_buildset_<buildset>.cfg file. All generic HDL libraries and these technology specific libraries are kept. - + Files: - hdl_buildset_<buildset>.cfg : HDL tool configuration dictionary file. One central file per buildset. - + - hdllib.cfg : HDL library configuration dictionary file. One file for each HDL library. - + - <lib_name>.qpf : Quartus project file (QPF) for a certain HDL library based on the hdllib.cfg. The file is created by create_quartus_project_file(). - + - <lib_name>.qsf : Quartus settings file (QSF) for a certain HDL library based on the hdllib.cfg. The file is created by create_quartus_settings_file(). There is one QSF per Quartus synthesis project. """ print("QuartusConfig(toolRootDir=%s, toolFileName=%s, libFileName=%s)" % (toolRootDir, toolFileName, libFileName)) - libFileSections=['quartus_project_file'] + libFileSections = ['quartus_project_file'] hdl_libraries_wizard.HdlLibrariesWizard.__init__(self, toolRootDir, toolFileName, libFileName, libFileSections) def create_quartus_ip_lib_file(self, lib_names=None): """Create the Quartus IP file <hdl_lib_name>_lib.qip for all HDL libraries. The <hdl_lib_name>.qip file contains the list of files that are given by the synth_files key and the quartus_*_file keys. - + Note: . Use post fix '_lib' in QIP file name *_lib.qip to avoid potential conflict with *.qip that may come with the IP. . The HDL library *_lib.qip files contain all files that are listed by the synth_files key. Hence when these qip files are included then the Quartus project will analyse all files even if there entity is not instantiated in the design. This is fine, it is unnecessary to parse the hierarchy of the synth_top_level_entity VHDL file to find and include only the source files that are actually used. - + Arguments: - lib_names : one or more HDL libraries """ - if lib_names==None: - lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names) for lib_dict in lib_dicts: @@ -98,16 +99,16 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): filePathName = cm.expand_file_path_name(fn, lib_dict.location) file_ext = fn.split('.')[-1] - if file_ext=='vhd' or file_ext=='vhdl': - file_type = 'VHDL_FILE' - elif file_ext=='v': - file_type = 'VERILOG_FILE' + if file_ext == 'vhd' or file_ext == 'vhdl': + file_type = 'VHDL_FILE' + elif file_ext == 'v': + file_type = 'VERILOG_FILE' else: - print('\nERROR - Undefined file extension in synth_files:', fn) - sys.exit() + print('\nERROR - Undefined file extension in synth_files:', fn) + sys.exit() fp.write('set_global_assignment -name %s %s -library %s\n' % (file_type, filePathName, lib_name + '_lib')) - + if lib_dict.get_value('quartus_vhdl_files'): fp.write('\n') fp.write('# quartus_vhdl_files\n') @@ -116,16 +117,16 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): filePathName = cm.expand_file_path_name(fn, lib_dict.location) file_ext = fn.split('.')[-1] - if file_ext=='vhd' or file_ext=='vhdl': - file_type = 'VHDL_FILE' - elif file_ext=='v': - file_type = 'VERILOG_FILE' + if file_ext == 'vhd' or file_ext == 'vhdl': + file_type = 'VHDL_FILE' + elif file_ext == 'v': + file_type = 'VERILOG_FILE' else: - print('\nERROR - Undefined file extension in quartus_vhdl_files:', fn) - sys.exit() + print('\nERROR - Undefined file extension in quartus_vhdl_files:', fn) + sys.exit() fp.write('set_global_assignment -name VHDL_FILE %s -library %s\n' % (filePathName, lib_name + '_lib')) - + if lib_dict.get_value('quartus_qip_files'): fp.write('\n') fp.write('# quartus_qip_files\n') @@ -141,7 +142,7 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): for fn in quartus_tcl_files: filePathName = cm.expand_file_path_name(fn, lib_dict.location) fp.write('set_global_assignment -name SOURCE_TCL_SCRIPT_FILE %s\n' % filePathName) - + if lib_dict.get_value('quartus_sdc_files'): fp.write('\n') fp.write('# quartus_sdc_files\n') @@ -150,24 +151,24 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): filePathName = cm.expand_file_path_name(fn, lib_dict.location) fp.write('set_global_assignment -name SDC_FILE %s\n' % filePathName) print("Created {} .qip files".format(len(lib_dicts))) - - + def create_quartus_project_file(self, lib_names=None): """Create the Quartus project file (QPF) for all HDL libraries that have a toplevel entity key synth_top_level_entity. - + Note: . Default if the synth_top_level_entity key is defined but left empty then the top level entity has the same name as the lib_name in hdl_lib_name. Otherwise synth_top_level_entity can specify another top level entity name in the library. Each HDL library can only have one Quartus project file - . The project revision has the same name as the lib_name and will result in a <lib_name>.sof FPGA image file. - . For each additional revision a subdirectory can be used. - This subdirectory can be named 'revisions/' and lists a number of revisions as subdirectories. Each revision will have a separate hdllib.cfg file and a - .vhd file with the toplevel entity. The toplevel .vhd file specifies the <g_design_name> for the revision in the generics. - + . The project revision has the same name as the lib_name and will result in a <lib_name>.sof FPGA image file. + . For each additional revision a subdirectory can be used. + This subdirectory can be named 'revisions/' and lists a number of revisions as subdirectories. Each revision will have a separate hdllib.cfg file and a + .vhd file with the toplevel entity. The toplevel .vhd file specifies the <g_design_name> for the revision in the generics. + Arguments: - lib_names : one or more HDL libraries """ - if lib_names==None: lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) syn_dicts = self.libs.get_configfiles(key='synth_top_level_entity', values=None, user_configfiles=lib_dicts) for syn_dict in syn_dicts: @@ -180,25 +181,25 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): with open(qpfPathName, 'w') as fp: fp.write('PROJECT_REVISION = "%s"\n' % lib_name) print("Created {} .qpf files".format(len(syn_dicts))) - def create_quartus_settings_file(self, lib_names=None): """Create the Quartus settings file (QSF) for all HDL libraries that have a toplevel entity key synth_top_level_entity. - + Note: . No support for revisions, so only one qsf per qpf - + Arguments: - lib_names : one or more HDL libraries """ - if lib_names==None: lib_names=self.lib_names + if lib_names is None: + lib_names = self.lib_names lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names) syn_dicts = self.libs.get_configfiles(key='synth_top_level_entity', values=None, user_configfiles=lib_dicts) for syn_dict in syn_dicts: # Open qsf for each HDL library that has a synth_top_level_entity lib_name = syn_dict['hdl_lib_name'] top_level_entity = syn_dict['synth_top_level_entity'] - if top_level_entity=='': + if top_level_entity == '': top_level_entity = lib_name qsf_path = self.get_lib_build_dirs('synth', lib_dicts=syn_dict) cm.mkdir(qsf_path) @@ -220,7 +221,7 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): fp.write('\n') fp.write('# All used HDL library *_lib.qip files in order with top level last\n') use_lib_order = self.derive_lib_order('synth', lib_name) - #use_lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=use_lib_order) # uses original libs.dicts order, but + # use_lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=use_lib_order) # uses original libs.dicts order, but use_lib_dicts = self.get_lib_dicts_from_lib_names(lib_names=use_lib_order) # must preserve use_lib_order order to ensure that top level design qip with sdc file is include last in qsf for lib_dict in cm.listify(use_lib_dicts): qip_path = self.get_lib_build_dirs('synth', lib_dicts=lib_dict) @@ -228,15 +229,15 @@ class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard): qipPathName = cm.expand_file_path_name(qip_name, qip_path) fp.write('set_global_assignment -name QIP_FILE %s\n' % qipPathName) print("Created {} .qsf files".format(len(syn_dicts))) - + if __name__ == '__main__': # Parse command line arguments buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(os.getenv('RADIOHDL_CONFIG')) - if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) + if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")]) argparser = ArgumentParser(description='Quartus_config creates/updates all your quartus projectfiles.') - argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect)) - argparser.add_argument('-v','--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info') + argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect)) + argparser.add_argument('-v', '--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info') args = argparser.parse_args() # check arguments @@ -247,11 +248,11 @@ if __name__ == '__main__': args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg' # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories - qsyn = QuartusConfig(toolRootDir = os.getenv('RADIOHDL_CONFIG'), - toolFileName= args.buildsetFile, - libFileName = 'hdllib.cfg') - - if args.verbosity>=2: + qsyn = QuartusConfig(toolRootDir=os.getenv('RADIOHDL_CONFIG'), + toolFileName=args.buildsetFile, + libFileName='hdllib.cfg') + + if args.verbosity >= 2: print('#') print('# QuartusConfig:') print('#') @@ -260,30 +261,33 @@ if __name__ == '__main__': for p in sorted(qsyn.libs.configfiles.values()): print(' ', p.location) - if args.verbosity>=1: + if args.verbosity >= 1: print('') print('HDL libraries with a top level entity for synthesis that are found in $%s:' % qsyn.libRootDirs) print(' %-40s' % 'HDL library', ': Top level entity') syn_dicts = qsyn.libs.get_configfiles(key='synth_top_level_entity') for d in syn_dicts: - if d['synth_top_level_entity']=='': + if d['synth_top_level_entity'] == '': print(' %-40s' % d['hdl_lib_name'], ':', d['hdl_lib_name']) else: print(' %-40s' % d['hdl_lib_name'], ':', d['synth_top_level_entity']) - - + print('') - print('Create Quartus IP library qip files for all HDL libraries in $%s.' % qsyn.libRootDirs) + print('Create Quartus IP library qip files for all HDL libraries in $%s.' + % qsyn.libRootDirs) qsyn.create_quartus_ip_lib_file() - + print('') - print('Copy Quartus directories and files from HDL library source tree to build_dir for all HDL libraries that are found in $%s.' % qsyn.libRootDirs) + print('Copy Quartus directories and files from HDL library source tree to build_dir for all HDL libraries that are found in $%s.' + % qsyn.libRootDirs) qsyn.copy_files('synth') - + print('') - print('Create Quartus project files (QPF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.' % (qsyn.technologyNames, qsyn.libRootDirs)) + print('Create Quartus project files (QPF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.' + % (qsyn.technologyNames, qsyn.libRootDirs)) qsyn.create_quartus_project_file() - + print('') - print('Create Quartus settings files (QSF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.' % (qsyn.technologyNames, qsyn.libRootDirs)) + print('Create Quartus settings files (QSF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.' + % (qsyn.technologyNames, qsyn.libRootDirs)) qsyn.create_quartus_settings_file() diff --git a/core/test/t_hdl_configfile.py b/core/test/t_hdl_configfile.py index b96e9d46fcd8677afc86146d8b8639f046f20295..d4f87f2f2b56e775cda7f413cb3185af002e8600 100644 --- a/core/test/t_hdl_configfile.py +++ b/core/test/t_hdl_configfile.py @@ -2,6 +2,7 @@ import unittest from configfile import * from hdl_configfile import * + class Test_construction(unittest.TestCase): "Class to the various ways of construction" @@ -40,18 +41,17 @@ class Test_key_value_spacing(unittest.TestCase): self.assertEqual(cfg.tricky_key_2, "tricky_value_2") self.assertEqual(cfg.tricky_key_3, "") self.assertEqual(cfg.section_headers, ['"my_section"']) - self.assertEqual(cfg.warning_key_1, - "Be aware that multiline values can be tricky: this also belongs to previous key 'warning_key_1'") + self.assertEqual(cfg.warning_key_1, "Be aware that multiline values can be tricky: this also belongs to previous key 'warning_key_1'") # also test attribute access versus item access self.assertEqual(cfg.multi_key_2, cfg['multi_key_2']) print(cfg.content) def test_sections(self): cfg = ConfigFile("./cdf_dir/correct_files/section_test.txt") - self.assertEqual(cfg.global_key_1, "global_1"), - self.assertEqual(cfg.global_key_2, '[ "aap", "noot", "mies" ]'), - self.assertEqual(cfg.just_some_key_1, "section2 value1"), - self.assertEqual(cfg.just_some_key_2, "section2 value2"), + self.assertEqual(cfg.global_key_1, "global_1"), + self.assertEqual(cfg.global_key_2, '[ "aap", "noot", "mies" ]'), + self.assertEqual(cfg.just_some_key_1, "section2 value1"), + self.assertEqual(cfg.just_some_key_2, "section2 value2"), self.assertEqual(cfg.section_headers, ['section_1', 'section_2']) def test_dangling_value(self): @@ -86,7 +86,7 @@ class Test_reference_key_substitution(unittest.TestCase): self.assertEqual(cfg.mutual_key_1, "<mutual_key_2>") self.assertEqual(cfg.mutual_key_2, "<mutual_key_1>") self.assertEqual(cfg.loop_key_1, "<loop_key_1>") - + cfg.resolve_key_references() self.assertEqual(cfg.early_ref_key1, "before multiple words in the value is defined") @@ -142,6 +142,6 @@ class Test_hdllib_file(unittest.TestCase): def test_read_wrong_hdllib_file(self): self.assertRaises(ConfigFileException, HdlLib, "./cdf_dir/hdllib_files/hdllib_wrong.cfg") + if __name__ == '__main__': unittest.main(verbosity=2) - diff --git a/core/test/t_hdl_configtree.py b/core/test/t_hdl_configtree.py index a1b59af5a179ae7eae4bece6303aac669b3c531f..fdb936a9a1d754e7a7947d619312ca9dd784a121 100644 --- a/core/test/t_hdl_configtree.py +++ b/core/test/t_hdl_configtree.py @@ -2,6 +2,7 @@ import unittest from configtree import * from hdl_configtree import * + class Test_construction(unittest.TestCase): "Class to the various ways of construction" @@ -28,8 +29,8 @@ class Test_tree_behaviour(unittest.TestCase): "that holds its relative path in the tree" tree = ConfigTree("./cdf_dir/tree/cfgfile", "dict.txt") for cfg in list(tree.configfiles.values()): - #print cfg.ID, cfg.content - expected_value = cfg.ID.replace("./cdf_dir/tree/cfgfile" , "top_dir").replace("/dict.txt", "") + # print cfg.ID, cfg.content + expected_value = cfg.ID.replace("./cdf_dir/tree/cfgfile", "top_dir").replace("/dict.txt", "") self.assertEqual(expected_value, cfg.key_1) def test_hdllib_tree(self): @@ -37,22 +38,22 @@ class Test_tree_behaviour(unittest.TestCase): tree = HdlLibTree("./cdf_dir/tree/hdllib", "test_hdllib.cfg") self.assertEqual(len(tree.configfiles), 2) util = tree.configfiles['util'] - self.assertEqual(util.hdl_library_clause_name, 'util_lib') - self.assertEqual(util.synth_files, 'src/vhdl/util_logic.vhd src/vhdl/util_heater_pkg.vhd src/vhdl/util_heater.vhd') - technology = tree.configfiles['technology'] - self.assertEqual(technology.hdl_library_clause_name, 'technology_lib') - self.assertEqual(technology.synth_files, 'technology_pkg.vhd $HDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd') + self.assertEqual(util.hdl_library_clause_name, 'util_lib') + self.assertEqual(util.synth_files, 'src/vhdl/util_logic.vhd src/vhdl/util_heater_pkg.vhd src/vhdl/util_heater.vhd') + technology = tree.configfiles['technology'] + self.assertEqual(technology.hdl_library_clause_name, 'technology_lib') + self.assertEqual(technology.synth_files, 'technology_pkg.vhd $HDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd') def test_hdlbuildset_tree(self): "Test if we can read in a tree with hdlbuildset files." tree = HdlBuildsetTree("./cdf_dir/tree/hdlbuildset", "hdl_buildset_*.cfg") self.assertEqual(len(tree.configfiles), 2) rsp = tree.configfiles['rsp'] - self.assertEqual(rsp.technology_names, 'ip_virtex4') - self.assertEqual(rsp.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') - unb1 = tree.configfiles['unb1'] - self.assertEqual(unb1.technology_names, 'ip_stratixiv') - self.assertEqual(unb1.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') + self.assertEqual(rsp.technology_names, 'ip_virtex4') + self.assertEqual(rsp.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') + unb1 = tree.configfiles['unb1'] + self.assertEqual(unb1.technology_names, 'ip_stratixiv') + self.assertEqual(unb1.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') def test_hdltool_tree(self): "Test if we can read in a tree with hdltool files." @@ -63,6 +64,7 @@ class Test_tree_behaviour(unittest.TestCase): quartus = tree.configfiles['./cdf_dir/tree/hdltool/hdl_tool_quartus.cfg'] self.assertEqual(quartus.quartus_rootdir, "${QUARTUS_DIR}/quartus") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/quartus/set_quartus b/quartus/set_quartus index e7ec11c482bf12454859e037dcce1d335338f424..a43596507f8f47359221f774acf534c8706e5d09 100755 --- a/quartus/set_quartus +++ b/quartus/set_quartus @@ -71,7 +71,7 @@ do done # TODO: move to hdl_tool_quartus.cfg : user_environment_variables ??? -export RADIOHDL_GIT_REVISION=`cd $RADIOHDL_GEAR; git describe; cd - | grep V` +#export RADIOHDL_GIT_REVISION=`cd $RADIOHDL_GEAR; git describe; cd - | grep V` export UNB_COMPILE_STAMPS=1 unset buildset_config_file quartus_config_file bd_name verbose