From 14b150bcf5e17f2b3e0be871eff387f60ed8bf71 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Tue, 19 Apr 2016 05:59:39 +0000 Subject: [PATCH] Added fileSections argument to specifiy target specific section headers in the config dictionary file. --- tools/oneclick/base/common_dict_file.py | 71 ++++++++++++++++--------- tools/oneclick/base/modelsim_config.py | 12 +++-- tools/oneclick/base/quartus_config.py | 11 +++- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/tools/oneclick/base/common_dict_file.py b/tools/oneclick/base/common_dict_file.py index 05c4c10a43..35efeb9c23 100644 --- a/tools/oneclick/base/common_dict_file.py +++ b/tools/oneclick/base/common_dict_file.py @@ -25,17 +25,29 @@ pairs. These key - value pairs are read from the file and kept in a single dictionary of keys and values. - The format of the dictionary file is similar to that of an ini file but - without the sections. For ini files Python has the ConfigParser package. - Effectively the dictionary file only contains one section. It is not - obvious how to deal with sections if only one dictionary needs to be - stored flat. Defining a single section, is misleading because it suggests - that more sections are supported. Alternatively prepending a dummy - section when the file is read is also a bit awkward. In fact the parsing - by read_dict_file() is relatively simple and the other methods would also - be needed if the ConfigParser would be used. Therefore the Python - ConfigParser package for ini files is not used. - + The format of the dictionary file is similar to that of an ini file. For ini + files Python has the ConfigParser package, but that is not used here because + the ini file specification is not very strict. The parsing can be done in + a single method read_dict_file() that gives more freedom for interprating + the ini file. + + Like an ini file the dictionary can contain one or more sections. The first + section is common, has no header and always included. The specific sections + have a header that is marked by [section header]. The square brackets '[' + and ']' are used to identify the section header. If the 'section header' is + included in the object argument fileSections list then the keys of that + section will be included in the dictionary. + + 'fileSections' = None --> ignore fileSections to include all sections in + the dict. + 'fileSections' = [] --> empty list to include only the common first + section in the dict. + 'fileSections' = ['section header' ...] --> + dedicated list of one or more section header + strings to include these specific sections, + and also the common first section, in the + dict. + The key and value string in the dictionary file are separated by '='. Hence the '=' character can not be used in keys. The '=' can be used in values, because subsequent '=' on the same line are part of the value. @@ -93,7 +105,7 @@ import collections class CommonDictFile: - def __init__(self, rootDir, fileName='dict.txt'): + def __init__(self, rootDir, fileName='dict.txt', fileSections=None): """Store the dictionaries from all fileName files in rootDir.""" self.CDF_COMMENT = '#' self.CDF_SEPARATOR = '=' @@ -105,6 +117,7 @@ class CommonDictFile: self.filePathNames = [] # list of all directory paths + fileName of the available dictionary files for path in self.filePaths: self.filePathNames.append(os.path.join(path, self.fileName)) + self.fileSections = fileSections # specific dictionary file sections to include in the dict self.dicts = self.read_all_dict_files() # list of dictionaries that are read from the available dictionary files self.nof_dicts = len(self.dicts) # number of dictionaries = number of dictorary files @@ -146,26 +159,36 @@ class CommonDictFile: read_dicts.append(self.read_dict_file(fp)) return read_dicts - def read_dict_file(self, filePathName=None, valueSeparator=' '): + def read_dict_file(self, filePathName=None): """Read the dictionary information the filePathName file.""" if filePathName==None: filePathName=self.filePathNames[0] file_dict = collections.OrderedDict() + section_headers = [] with open(filePathName, 'r') as fp: - lineNr=0 + include_section = True # default include all sections key = '' value = '' for line in fp: - if line.find(self.CDF_COMMENT)==-1: # strip lines with comment - key_end = line.find(self.CDF_SEPARATOR) # find key - if key_end>=0: - key = line[0:key_end].strip() # new key - value = line[key_end+1:].strip() # new value + if line.find(self.CDF_COMMENT)==-1: # Strip lines with comment + section_begin= line.find('[') # Search for [section] header in this line + section_end = line.find(']') + if section_begin>=0 and section_end>section_begin: + section_header = line[section_begin+1:section_end].strip() # new section header + section_headers.append(section_header) + if self.fileSections!=None: + if section_header not in self.fileSections: + include_section = False # skip this section else: - value += valueSeparator # replace newline by valueSeparator - value += line.strip() # append value - if key!='': - file_dict[key] = value.strip() # update key in dict - lineNr += 1 + key_end = line.find(self.CDF_SEPARATOR) # Search for key in this line + if key_end>=0: + key = line[0:key_end].strip() # new key + value = line[key_end+1:].strip() # new value + else: + value += ' ' # replace newline by space to separate values + value += line.strip() # append value + if include_section==True and key!='': + file_dict[key] = value.strip() # Update dict with key and values + file_dict['section_headers'] = section_headers # Add the section headers as a key-value pair to the dict return file_dict def write_dict_file(self, dicts, filePathNames, keySeparator=None): diff --git a/tools/oneclick/base/modelsim_config.py b/tools/oneclick/base/modelsim_config.py index c703121544..0aa945dee8 100755 --- a/tools/oneclick/base/modelsim_config.py +++ b/tools/oneclick/base/modelsim_config.py @@ -21,6 +21,9 @@ ############################################################################### """HDL configuration for building Modelsim simulation targets. + + Usage: + > python $RADIOHDL/tools/oneclick/base/modelsim_config.py -t unb1 """ import common as cm @@ -35,6 +38,8 @@ class ModelsimConfig(hdl_config.HdlConfig): def __init__(self, toolRootDir, libFileName='hdllib.cfg', toolFileName='hdltool_<toolset>.cfg'): """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 hdltool_<toolset>.cfg file is searched for. - libFileName : Default HDL library configuration file name @@ -72,7 +77,8 @@ class ModelsimConfig(hdl_config.HdlConfig): 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. """ - hdl_config.HdlConfig.__init__(self, toolRootDir, libFileName, toolFileName) + libFileSections=['modelsim_project_file'] + hdl_config.HdlConfig.__init__(self, toolRootDir, libFileName, libFileSections, toolFileName) def read_compile_order_from_mpf(self, mpfPathName): """Utility to read the compile order of the project files from an existing <mpfPathName>.mpf.""" @@ -144,7 +150,7 @@ class ModelsimConfig(hdl_config.HdlConfig): # Write [Library] section for all used libraries fp.write('[Library]\n') # . map used vendor technology libs to their target directory - for technologyName in cm.listify(self.technologyNames): + for technologyName in self.technologyNames: tech_dict = self.read_hdl_libraries_technology_file(technologyName) for lib_clause, lib_work in tech_dict.iteritems(): fp.write('%s = %s\n' % (lib_clause, lib_work)) @@ -326,7 +332,6 @@ if __name__ == '__main__': msim = ModelsimConfig(toolRootDir=os.path.expandvars('$RADIOHDL/tools'), libFileName='hdllib.cfg', toolFileName=toolFileName) if arg_verbosity>=2: - print arg_verbosity print '#' print '# ModelsimConfig:' print '#' @@ -340,7 +345,6 @@ if __name__ == '__main__': print 'Derive library compile order = ', msim.derive_lib_order('sim') if arg_verbosity>=2: - print arg_verbosity print '' print 'get_lib_build_dirs for simulation:' for sim_dir in msim.get_lib_build_dirs('sim'): diff --git a/tools/oneclick/base/quartus_config.py b/tools/oneclick/base/quartus_config.py index 1a976800a7..9a46ad5332 100755 --- a/tools/oneclick/base/quartus_config.py +++ b/tools/oneclick/base/quartus_config.py @@ -21,6 +21,9 @@ ############################################################################### """HDL configuration for building Quartus synthesis targets. + + Usage: + > python $RADIOHDL/tools/oneclick/base/quartus_config.py -t unb1 """ import common as cm @@ -35,6 +38,8 @@ class QuartusConfig(hdl_config.HdlConfig): def __init__(self, toolRootDir, libFileName='hdllib.cfg', toolFileName='hdltool_<toolset>.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 hdltool_<toolset>.cfg file is searched for. - libFileName : Default HDL library configuration file name @@ -57,7 +62,9 @@ class QuartusConfig(hdl_config.HdlConfig): - <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. """ - hdl_config.HdlConfig.__init__(self, toolRootDir, libFileName, toolFileName) + libFileSections=['quartus_project_file'] + libFileSections=None + hdl_config.HdlConfig.__init__(self, toolRootDir, libFileName, libFileSections, toolFileName) 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 @@ -226,7 +233,7 @@ if __name__ == '__main__': # Parse command line arguments toolsetSelect = ['unb1', 'unb2', 'unb2a'] - argparser = argparse.ArgumentParser(description='Create Modelsim mpf files for all hdllib.cfg') + argparser = argparse.ArgumentParser(description='Create Quartus project files for hdllib.cfg') argparser.add_argument('-t','--toolset', help='choose toolset %s (default: %s)' % (toolsetSelect,toolsetSelect[0]), default=toolsetSelect[0], required=False) argparser.add_argument('-v','--verbosity', help='verbosity >= 0 for more info', type=int, default=0, required=False) args = vars(argparser.parse_args()) -- GitLab