From 80ecb4a976fa6f8dbcc3cc808f1cdc4da306f0f2 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Fri, 13 Feb 2015 07:46:56 +0000 Subject: [PATCH] Renamed key hdl_lib_uses into hdl_lib_uses_synth and added new key hdl_lib_uses_sim for extra test_bench_files library dependencies. --- tools/hdltool_readme.txt | 65 +++++++++++++--------- tools/oneclick/base/hdl_config.py | 74 ++++++++++++++++---------- tools/oneclick/base/modelsim_config.py | 9 ++-- tools/oneclick/base/quartus_config.py | 8 +-- 4 files changed, 95 insertions(+), 61 deletions(-) diff --git a/tools/hdltool_readme.txt b/tools/hdltool_readme.txt index a3411a9922..4050a3be52 100644 --- a/tools/hdltool_readme.txt +++ b/tools/hdltool_readme.txt @@ -336,9 +336,16 @@ d) hdllib.cfg key descriptions - hdl_library_clause_name = The name of the HDL library as it is used in the VHDL LIBRARY clause, e.g. common_lib, dp_lib, unb1_minimal_lib. -- hdl_lib_uses = - List of HDL library names that are used in this HDL library, only the libraries that appear in VHDL LIBRARY clauses - need to be mentioned, all lower level libraries are found automatically. +- hdl_lib_uses_synth = + List of HDL library names that are used in this HDL library for the 'synth_files', only the libraries that appear in + VHDL LIBRARY clauses need to be mentioned, all lower level libraries are found automatically. + +- hdl_lib_uses_sim = + List of HDL library names that are used in this HDL library for the 'test_bench_files', only the libraries that appear in + VHDL LIBRARY clauses need to be mentioned, all lower level libraries are found automatically. + The hdl_lib_uses_synth key and hdl_lib_uses_sim key separate the dependencies due to the synth_files from the extra + dependencies that come from the test bench files. This seperation avoids that libraries that are only needed for the + test bench simulations also get included in the list of libraries for synthesis. - hdl_lib_technology = The IP technology that this library is using or targets, e.g. ip_stratixiv for UniBoard1, ip_arria10 for UniBoard2. For generic HDL libraries use ''. @@ -673,7 +680,16 @@ f) Generate Quartus IP key Conclusion: - Using build_dir_synth is also sufficient/suitable to define the build subdirectory for IP generation. -g) hdltool.cfg per toolset +g) regression test script + - To simulate all self-checking VHDL test benches and report the result. + - To simulate all self-checking Python MM - VHDL test case / test benches and report the result. + The pure HDL tests can be identified by the values of some 'regression_test_hdl' key. The value indicates the HDL + test bench. For Python test cases it is probably easier and more clear to define another key eg. + 'regression_test_py_sim'. The values they may contain the entire command to run the Python test case with the + HDL test bench. Note that the pure VHDL test benches could be perphaps also be regarded as a special case of the + Python MM - VHDL tests, ie. as a test without MM. + +h) hdltool.cfg per toolset (see also i, j, k) . The model_tech_dir key in hdltool.cfg depends on the modelsim version that is defined in the toolset. The model_tech_dir gives the path to the modelsim.ini that needs to be included in the mpf, because without the IEEE and STD libraries are not known anymore after the mpf is loaded. @@ -700,15 +716,6 @@ g) hdltool.cfg per toolset - Is the hdltool.cfg necessary/useful at all? Yes. Keep hdltool.cfg, but define dedicated hdltool_<toolset>.cfg and add --toolset command line option. -h) regression test script - - To simulate all self-checking VHDL test benches and report the result. - - To simulate all self-checking Python MM - VHDL test case / test benches and report the result. - The pure HDL tests can be identified by the values of some 'regression_test_hdl' key. The value indicates the HDL - test bench. For Python test cases it is probably easier and more clear to define another key eg. - 'regression_test_py_sim'. The values they may contain the entire command to run the Python test case with the - HDL test bench. Note that the pure VHDL test benches could be perphaps also be regarded as a special case of the - Python MM - VHDL tests, ie. as a test without MM. - i) multiple libRootDirs for finding hdllib.cfg files Currently hdlib.cfg files are search from one rootDir by find_all_dict_file_paths() in common_dict_file.py. It would be usefule to be able to specify multiple rootDirs for the search path. This allows finding eg. all @@ -726,21 +733,33 @@ k) Support multiple --technology It should be possible to define multiple technologies at the --technology option. As long as Modelsim supports these technolgies (ie the technology libraries are available) then unused technologies are not disturbing and then they also do not cause simulation load errors with the 'modelsim_search_libraries' key. + Probably a better scheme is to add a technology key to the hdltool.cfg and consider the hdltool.cfg as belonging + to a toolset. Each toolset then has a hdltool.cfg that defines which version of Modelsim and Quartus to use, + where to build and which technologies are supported. The toolset name (eg. 'unb1', 'unb2', ...) then is used + as command line option. This scheme also allows having mutliple build trees. l) Location of modelsim_project_files.txt Default the modelsim_project_files.txt is now created in the SVN directory set by 'toolRootDir'/modelsim. Instead the modelsim_project_files.txt should better be created in the build directory 'build_dir_sim'/modelsim/. -m) (FIXED) Issue exit error when a library name occurs double +m) (FIXED - erko) Issue exit error when a library name occurs double When a HDL library directory is copied and the hdllib.cfg is not updated then the library name will be double and cause misalignenment errors in the libraries lists which are difficult for a user to diagnose. The - _init__ in hdl_config.py could check this. + __init__ in hdl_config.py could check this. + +n) Rename keys: + This is easily done using hdllib_config with mode 4. + * Rename modelsim_compile_ip_files into more precise name eg. modelsim_execute or modelsim_pre_execute. + * Rename key test_bench_files into sim_files, but does the hdllib.cfg become more clear to do this rename? -n) Rename modelsim_compile_ip_files into more precise name eg. modelsim_execute or modelsim_pre_execute - o) How to avoid Quartus exit due to IP that is included at configuration, but not used at synthesis + * due to test_bench_files (FIXED - erko) Quartus can exit with error if IP is included in the hdl_lib_uses list of libraries but not actually used in - the design, eg due to a sdc file that is then sourced but that cannot find some IP signals. + the design, eg due to a sdc file that is then sourced but that cannot find some IP signals. Having a seperate + hdl_lib_uses_synth and hdl_lib_uses_sim key solves this issue, by avoiding that libraries that are only needed + for test bench simulation get included in the list for synthesis. + + * due to not-generate a certain IO component at compile time If the error is changed into warning then Quartus continues. Such modification of the sdc file could be automated by using 'sed' to edit the sdc after it was generated by generate_ip.tcl. In some designs we want to be able to temporarily disable the synthesis of an IO component (eg. io_ddr) to reduce @@ -749,13 +768,11 @@ o) How to avoid Quartus exit due to IP that is included at configuration, but no for designs and this could also be applied to IO libraries. Still the question remains how select between using the component declaration only library when it is not used for synthesis and how to include the full library when it is used for synthesis. This could be done if the io_ddr library is only included at the design level, because - then the design that uses the io_ddr has hdl_lib_uses = io_ddr in its hdllib.cfg whereas the design that does not - use io_ddr should in have hdl_lib_uses = io_ddr_empty, where io_ddr_empty is a revision of io_ddr with only the + then the design that uses the io_ddr has hdl_lib_uses_synth = io_ddr in its hdllib.cfg whereas the design that does not + use io_ddr should in have hdl_lib_uses_synth = io_ddr_empty, where io_ddr_empty is a revision of io_ddr with only the entity and an emtpy architecture. - If only the testbench uses some IO IP and the DUT does not (eg like for the reorder library where the tb can use - io_ddr + DDR3 memoery model) then it could be usefull to define an extra hdl_lib_tb_uses key next to the - hdl_lib_uses key. The hdl_lib_tb_uses = io_ddr is then used by Modelsim for simulation but ignored by Quartus for - synthesis. + + 101) More ideas diff --git a/tools/oneclick/base/hdl_config.py b/tools/oneclick/base/hdl_config.py index c766354843..f746e3f782 100644 --- a/tools/oneclick/base/hdl_config.py +++ b/tools/oneclick/base/hdl_config.py @@ -96,31 +96,42 @@ class HdlConfig: duplicate_lib_names = cm.list_duplicates(self.lib_names) if len(duplicate_lib_names)>0: sys.exit('Error : Duplicate HDL library config file found %s' % duplicate_lib_names) - def derive_all_use_libs(self, lib_name): + def derive_all_use_libs(self, build_type, lib_name): """Derive a list of all HDL libraries that the specified HDL lib_name library depends on. + The build_type can be: + 'sim' uses both the 'hdl_lib_uses_synth' and the 'hdl_lib_uses_sim' key in the lib_dict, + 'synth' uses only the 'hdl_lib_uses_synth' key in the lib_dict + Note: . Only the generic HDL libraries and the technology specific libraries that match self.technologyNames are used. - . 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 library. This derive_all_use_libs() will recursively find all deeper + . The hdl_lib_uses_<build type> key only needs to contain all libraries that are declared at the VHDL LIBRARY + clauses of the source files in this library. This derive_all_use_libs() will recursively find all deeper level libraries as well. """ if lib_name in self.lib_names: all_use_libs = [lib_name] lib_dict = self.libs.dicts[self.lib_names.index(lib_name)] # use recursion to include all used libs - if 'hdl_lib_uses' in lib_dict: - use_libs = lib_dict['hdl_lib_uses'].split() + if 'hdl_lib_uses_synth' in lib_dict: + use_libs = lib_dict['hdl_lib_uses_synth'].split() + if build_type=='sim': + if 'hdl_lib_uses_sim' in lib_dict: + use_libs += lib_dict['hdl_lib_uses_sim'].split() + try: + use_libs for use_lib in use_libs: if use_lib in self.lib_names: all_use_libs.append(use_lib) - all_use_libs += self.derive_all_use_libs(use_lib) + all_use_libs += self.derive_all_use_libs(build_type, use_lib) + except NameError: + pass # remove all duplicates from the list return cm.unique(all_use_libs) else: sys.exit('Error : Unknown HDL library name') - def derive_lib_order(self, lib_names=None): + def derive_lib_order(self, build_type, lib_names=None): """Derive the dependency order for all HDL libraries in the fully specified list of lib_names. Note: @@ -133,16 +144,22 @@ class HdlConfig: lib_order = list(lib_names) for lib_dict in cm.listify(lib_dicts): lib_name = lib_dict['hdl_lib_name'] - if 'hdl_lib_uses' in lib_dict: - use_libs = lib_dict['hdl_lib_uses'].split() + if 'hdl_lib_uses_synth' in lib_dict: + use_libs = lib_dict['hdl_lib_uses_synth'].split() + if build_type=='sim': + if 'hdl_lib_uses_sim' in lib_dict: + use_libs += lib_dict['hdl_lib_uses_sim'].split() + try: for use_lib in use_libs: if use_lib in self.lib_names: if lib_order.index(use_lib) > lib_order.index(lib_name): lib_order.remove(use_lib) lib_order.insert(lib_order.index(lib_name), use_lib) # move used lib to just before this lib + except NameError: + pass # use recursion to keep on reordering the lib_order until it is stable if lib_names != lib_order: - lib_order = self.derive_lib_order(lib_order) + lib_order = self.derive_lib_order(build_type, lib_order) return lib_order @@ -175,7 +192,7 @@ class HdlConfig: build_dirs.append(os.path.join(build_dir, build_subdir, lib_name)) # central build cdirectory return cm.unlistify(build_dirs) - def create_lib_order_files(self, lib_names=None): + 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. @@ -185,8 +202,8 @@ class HdlConfig: lib_dicts = self.libs.get_dicts('hdl_lib_name', lib_names) for lib_dict in cm.listify(lib_dicts): lib_name = lib_dict['hdl_lib_name'] - use_libs = self.derive_all_use_libs(lib_name) - lib_order = self.derive_lib_order(use_libs) + use_libs = self.derive_all_use_libs(build_type, lib_name) + lib_order = self.derive_lib_order(build_type, use_libs) file_name = lib_name + '_lib_order.txt' file_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict) cm.mkdir(file_path) @@ -291,7 +308,8 @@ if __name__ == '__main__': print '' print 'lib_names = ', hdl.lib_names - print 'derive_lib_order : ', hdl.derive_lib_order() + print 'derive_lib_order for sim : ', hdl.derive_lib_order('sim') + print 'derive_lib_order for synth : ', hdl.derive_lib_order('synth') print '' print 'get_lib_build_dirs for simulation:' @@ -300,17 +318,17 @@ if __name__ == '__main__': print '' if libRootDir=='RADIOHDL': - #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('tech_memory')) - #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('numonyx_m25p128')) - #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('ip_stratixiv')) - #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('tech_flash')) - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('epcs')) - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('unb1_minimal')) + #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'tech_memory')) + #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'numonyx_m25p128')) + #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'ip_stratixiv')) + #print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'tech_flash')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'epcs')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'unb1_minimal')) if libRootDir=='UNB': - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('dp')) - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('uth')) - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('unb_common')) - print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('unb_minimal')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'dp')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'uth')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'unb_common')) + print 'derive_lib_order = ', hdl.derive_lib_order(hdl.derive_all_use_libs('sim', 'unb_minimal')) if mode==1: key = 'build_dir_synth' @@ -332,9 +350,9 @@ if __name__ == '__main__': hdl.libs.insert_key_in_dict_file_at_line_number(p, insert_key, insert_value, insertLineNr) if mode==3: - insert_key = 'quartus_vhdl_files' + insert_key = 'hdl_lib_uses_sim' insert_value = '\n' - insert_beforeKey = 'quartus_qip_files' + insert_beforeKey = 'hdl_lib_technology' # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories libRootDir = 'RADIOHDL' hdl = HdlConfig(libRootDir=os.environ[libRootDir], toolRootDir=os.path.expandvars('$RADIOHDL/tools'), libFileName='hdllib.cfg', toolFileName='hdltool.cfg', technologyNames=[]) @@ -342,8 +360,8 @@ if __name__ == '__main__': hdl.libs.insert_key_in_dict_file_before_another_key(p, insert_key, insert_value, insert_beforeKey) if mode==4: - old_key = 'synth_copy_files' - new_key = 'quartus_copy_files' + old_key = 'hdl_lib_uses' + new_key = 'hdl_lib_uses_synth' # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories libRootDir = 'RADIOHDL' hdl = HdlConfig(libRootDir=os.environ[libRootDir], toolRootDir=os.path.expandvars('$RADIOHDL/tools'), libFileName='hdllib.cfg', toolFileName='hdltool.cfg', technologyNames=[]) diff --git a/tools/oneclick/base/modelsim_config.py b/tools/oneclick/base/modelsim_config.py index 8eceba714e..244165f7db 100755 --- a/tools/oneclick/base/modelsim_config.py +++ b/tools/oneclick/base/modelsim_config.py @@ -68,7 +68,6 @@ class ModelsimConfig(hdl_config.HdlConfig): and then reading them in TCL makes the commands.do much simpler. """ hdl_config.HdlConfig.__init__(self, libRootDir, toolRootDir, libFileName, toolFileName, technologyNames) - # Modelsim def read_compile_order_from_mpf(self, mpfPathName): """Utility to read the compile order of the project files from an existing <mpfPathName>.mpf.""" @@ -149,7 +148,7 @@ class ModelsimConfig(hdl_config.HdlConfig): for tech_dict in self.removed_dicts: fp.write('%s = work\n' % tech_dict['hdl_library_clause_name']) # . all used libs for this lib_name - use_lib_names = self.derive_all_use_libs(lib_name) + use_lib_names = self.derive_all_use_libs('sim', lib_name) use_lib_dicts = self.libs.get_dicts('hdl_lib_name', use_lib_names) use_lib_build_sim_dirs = self.get_lib_build_dirs('sim', lib_dicts=use_lib_dicts) use_lib_clause_names = self.libs.get_key_values('hdl_library_clause_name', use_lib_dicts) @@ -335,7 +334,7 @@ if __name__ == '__main__': print ' ', p print '' - print 'Derive library compile order = ', msim.derive_lib_order() + print 'Derive library compile order = ', msim.derive_lib_order('sim') print '' print 'get_lib_build_dirs for simulation:' @@ -343,8 +342,8 @@ if __name__ == '__main__': print ' ', sim_dir print '' - print 'Create library compile order files.' - msim.create_lib_order_files() + print 'Create library compile order files for simulation.' + msim.create_lib_order_files('sim') print '' print 'Create library compile ip files.' diff --git a/tools/oneclick/base/quartus_config.py b/tools/oneclick/base/quartus_config.py index eb95c6001a..246a206aef 100755 --- a/tools/oneclick/base/quartus_config.py +++ b/tools/oneclick/base/quartus_config.py @@ -205,7 +205,7 @@ class QuartusConfig(hdl_config.HdlConfig): fp.write('\n') fp.write('# all used HDL library qip files\n') - use_lib_names = self.derive_all_use_libs(lib_name) + use_lib_names = self.derive_all_use_libs('synth', lib_name) use_lib_dicts = self.libs.get_dicts('hdl_lib_name', use_lib_names) for lib_dict in cm.listify(use_lib_dicts): qip_path = self.get_lib_build_dirs('synth', lib_dicts=lib_dict) @@ -246,13 +246,13 @@ if __name__ == '__main__': print '' print 'HDL libraries with a top level entity for synthesis that are found in $%s:' % libRootDir - print ' %-20s' % 'HDL library', ': Top level entity' + print ' %-30s' % 'HDL library', ': Top level entity' syn_dicts = qsyn.libs.get_dicts(key='synth_top_level_entity') for d in cm.listify(syn_dicts): if d['synth_top_level_entity']=='': - print ' %-20s' % d['hdl_lib_name'], ':', d['hdl_lib_name'] + print ' %-30s' % d['hdl_lib_name'], ':', d['hdl_lib_name'] else: - print ' %-20s' % d['hdl_lib_name'], ':', d['synth_top_level_entity'] + print ' %-30s' % d['hdl_lib_name'], ':', d['synth_top_level_entity'] print '' print 'Create Quartus IP library qip files for all HDL libraries in $%s.' % libRootDir -- GitLab