def _create_load_function(self, config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = "\n ".join( ('set vunit_generic_%s {%s}' % (name, value) for name, value in config.generics.items())) set_generic_name_str = " ".join( ('-g/%s/%s=${vunit_generic_%s}' % (config.entity_name, name, name) for name in config.generics)) pli_str = " ".join("-pli \"%s\"" % fix_path(name) for name in config.sim_options.get('pli', [])) vsim_flags = [ pli_str, set_generic_name_str, "-lib", config.library_name, config.entity_name ] if config.architecture_name is not None: vsim_flags.append(config.architecture_name) if config.sim_options.get("enable_coverage", False): coverage_file_path = join(output_path, "coverage.acdb") self._coverage_files.add(coverage_file_path) vsim_flags += ["-acdb_file {%s}" % fix_path(coverage_file_path)] vsim_flags += [self._vsim_extra_args(config)] if config.sim_options.get("disable_ieee_warnings", False): vsim_flags.append("-ieee_nowarn") # Add the the testbench top-level unit last as coverage is # only collected for the top-level unit specified last vhdl_assert_stop_level_mapping = dict(warning=1, error=2, failure=3) tcl = """ proc vunit_load {{}} {{ {set_generic_str} set vsim_failed [catch {{ vsim {vsim_flags} }}] if {{${{vsim_failed}}}} {{ return true }} global breakassertlevel set breakassertlevel {breaklevel} global builtinbreakassertlevel set builtinbreakassertlevel $breakassertlevel return false }} """.format(set_generic_str=set_generic_str, vsim_flags=" ".join(vsim_flags), breaklevel=vhdl_assert_stop_level_mapping[ config.vhdl_assert_stop_level]) return tcl
def merge_coverage(self, file_name, args=None): """ Merge coverage from all test cases, """ merge_command = "onerror {quit -code 1}\n" merge_command += "acdb merge" for coverage_file in self._coverage_files: if file_exists(coverage_file): merge_command += " -i {%s}" % fix_path(coverage_file) else: LOGGER.warning("Missing coverage file: %s", coverage_file) if args is not None: merge_command += " " + " ".join("{%s}" % arg for arg in args) merge_command += " -o {%s}" % fix_path(file_name) + "\n" merge_script_name = join(self._output_path, "acdb_merge.tcl") with open(merge_script_name, "w") as fptr: fptr.write(merge_command + "\n") vcover_cmd = [ join(self._prefix, 'vsimsa'), '-tcl', '%s' % fix_path(merge_script_name) ] print("Merging coverage files into %s..." % file_name) vcover_merge_process = Process(vcover_cmd, env=self.get_env()) vcover_merge_process.consume_output() print("Done merging coverage files")
def _create_load_function( self, test_suite_name, # pylint: disable=unused-argument config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join( ('-g/%s/%s=%s' % (config.entity_name, name, format_generic(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli \"%s\"" % fix_path(name) for name in config.sim_options.get('pli', [])) vsim_flags = [ "-dataset {%s}" % fix_path(join(output_path, "dataset.asdb")), pli_str, set_generic_str, "-lib", config.library_name, config.entity_name ] if config.architecture_name is not None: vsim_flags.append(config.architecture_name) if config.sim_options.get("enable_coverage", False): coverage_file_path = join(output_path, "coverage.acdb") self._coverage_files.add(coverage_file_path) vsim_flags += ["-acdb_file {%s}" % coverage_file_path] vsim_flags += [self._vsim_extra_args(config)] if config.sim_options.get("disable_ieee_warnings", False): vsim_flags.append("-ieee_nowarn") tcl = """ proc vunit_load {{}} {{ # Make the variable 'aldec' visible; otherwise, the Matlab interface # is broken because vsim does not find the library aldec_matlab_cosim. global aldec set vsim_failed [catch {{ eval vsim {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ return true }} if {{[_vunit_source_init_files_after_load]}} {{ return true }} vhdlassert.break {break_level} vhdlassert.break -builtin {break_level} return false }} """.format(vsim_flags=" ".join(vsim_flags), break_level=config.vhdl_assert_stop_level) return tcl
def _create_load_function(self, test_suite_name, # pylint: disable=unused-argument config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join(('-g/%s/%s=%s' % (config.entity_name, name, format_generic(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli \"%s\"" % fix_path(name) for name in config.sim_options.get('pli', [])) vsim_flags = ["-dataset {%s}" % fix_path(join(output_path, "dataset.asdb")), pli_str, set_generic_str, "-lib", config.library_name, config.entity_name, self._vsim_extra_args(config)] if config.architecture_name is not None: vsim_flags.append(config.architecture_name) if config.sim_options.get("disable_ieee_warnings", False): vsim_flags.append("-ieee_nowarn") tcl = """ proc vunit_load {{}} {{ set vsim_failed [catch {{ eval vsim {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ return 1 }} set no_vhdl_test_runner_exit [catch {{examine /vunit_lib.run_base_pkg/runner.exit_simulation}}] set no_verilog_test_runner_exit [catch {{examine /\\\\package vunit_lib.vunit_pkg\\\\/__runner__}}] if {{${{no_vhdl_test_runner_exit}} && ${{no_verilog_test_runner_exit}}}} {{ echo {{Error: No vunit test runner package used}} return 1 }} vhdlassert.break {break_level} vhdlassert.break -builtin {break_level} return 0 }} """.format(vsim_flags=" ".join(vsim_flags), break_level=config.vhdl_assert_stop_level) return tcl
def _create_load_function(self, # pylint: disable=too-many-arguments library_name, entity_name, architecture_name, config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join(('-g/%s/%s=%s' % (entity_name, name, format_generic(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli \"%s\"" % fix_path(name) for name in config.pli) vsim_flags = ["-dataset {%s}" % fix_path(join(output_path, "dataset.asdb")), pli_str, set_generic_str, "-lib", library_name, entity_name, self._vsim_extra_args(config)] if architecture_name is not None: vsim_flags.append(architecture_name) if config.disable_ieee_warnings: vsim_flags.append("-ieee_nowarn") tcl = """ proc vunit_load {{}} {{ set vsim_failed [catch {{ eval vsim {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ return 1 }} set no_vhdl_test_runner_exit [catch {{examine /vunit_lib.run_base_pkg/runner.exit_simulation}}] set no_verilog_test_runner_exit [catch {{examine /\\\\package vunit_lib.vunit_pkg\\\\/__runner__}}] if {{${{no_vhdl_test_runner_exit}} && ${{no_verilog_test_runner_exit}}}} {{ echo {{Error: No vunit test runner package used}} return 1 }} return 0 }} """.format(vsim_flags=" ".join(vsim_flags)) return tcl
def _create_gui_script(self, common_file_name, config): """ Create the user facing script which loads common functions and prints a help message """ tcl = "" tcl += 'source "%s"\n' % fix_path(common_file_name) tcl += 'workspace create workspace\n' tcl += 'design create -a design .\n' for library in self._libraries: tcl += "vmap %s %s\n" % (library.name, fix_path(library.directory)) tcl += 'vunit_load\n' init_file = config.sim_options.get(self.name + ".init_file.gui", None) if init_file is not None: tcl += 'source "%s"\n' % fix_path(abspath(init_file)) tcl += 'puts "VUnit help: Design already loaded. Use run -all to run the test."\n' return tcl
def _create_batch_script(common_file_name, load_only=False): """ Create tcl script to run in batch mode """ batch_do = "" batch_do += "source \"%s\"\n" % fix_path(common_file_name) batch_do += "set failed [vunit_load]\n" batch_do += "if {$failed} {quit -code 1}\n" if not load_only: batch_do += "set failed [vunit_run]\n" batch_do += "if {$failed} {quit -code 1}\n" batch_do += "quit -code 0\n" return batch_do
def _run_batch_file(self, batch_file_name, gui, cwd): """ Run a test bench in batch by invoking a new vsim process from the command line """ todo = "@do -tcl \"\"%s\"\"" % fix_path(batch_file_name) if not gui: todo = "@onerror {quit -code 1};" + todo try: args = [ join(self._prefix, "vsim"), "-gui" if gui else "-c", "-l", join(dirname(batch_file_name), "transcript"), '-do', todo ] proc = Process(args, cwd=cwd, env=self.get_env()) proc.consume_output() except Process.NonZeroExitCode: return False return True
def _create_load_function(self, test_suite_name, config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join( ('-g/%s/%s=%s' % (config.entity_name, name, encode_generic_value(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli {%s}" % fix_path(name) for name in config.sim_options.get('pli', [])) if config.architecture_name is None: architecture_suffix = "" else: architecture_suffix = "(%s)" % config.architecture_name if self._coverage is None: coverage_save_cmd = "" coverage_args = "" else: coverage_file = join(output_path, "coverage.ucdb") self._coverage_files.add(coverage_file) coverage_save_cmd = ( "coverage save -onexit -testname {%s} -assert -directive -cvg -codeAll {%s}" % (test_suite_name, fix_path(coverage_file))) coverage_args = "-coverage" vsim_flags = [ "-wlf {%s}" % fix_path(join(output_path, "vsim.wlf")), "-quiet", "-t ps", # for correct handling of verilog fatal/finish "-onfinish stop", pli_str, set_generic_str, config.library_name + "." + config.entity_name + architecture_suffix, coverage_args, self._vsim_extra_args(config) ] # There is a known bug in modelsim that prevents the -modelsimini flag from accepting # a space in the path even with escaping, see issue #36 if " " not in self._sim_cfg_file_name: vsim_flags.insert( 0, "-modelsimini %s" % fix_path(self._sim_cfg_file_name)) for library in self._libraries: vsim_flags += ["-L", library.name] vhdl_assert_stop_level_mapping = dict(warning=1, error=2, failure=3) tcl = """ proc vunit_load {{{{vsim_extra_args ""}}}} {{ set vsim_failed [catch {{ eval vsim ${{vsim_extra_args}} {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ echo Command 'vsim ${{vsim_extra_args}} {vsim_flags}' failed echo Bad flag from vsim_extra_args? return true }} if {{[_vunit_source_init_files_after_load]}} {{ return true }} global BreakOnAssertion set BreakOnAssertion {break_on_assert} global NumericStdNoWarnings set NumericStdNoWarnings {no_warnings} global StdArithNoWarnings set StdArithNoWarnings {no_warnings} {coverage_save_cmd} return false }} """.format(coverage_save_cmd=coverage_save_cmd, vsim_flags=" ".join(vsim_flags), break_on_assert=vhdl_assert_stop_level_mapping[ config.vhdl_assert_stop_level], no_warnings=1 if config.sim_options.get("disable_ieee_warnings", False) else 0) return tcl
def _create_load_function(self, test_suite_name, # pylint: disable=unused-argument config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join(('-g/%s/%s=%s' % (config.entity_name, name, format_generic(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli \"%s\"" % fix_path(name) for name in config.sim_options.get('pli', [])) vsim_flags = ["-dataset {%s}" % fix_path(join(output_path, "dataset.asdb")), pli_str, set_generic_str] if config.sim_options.get("enable_coverage", False): coverage_file_path = join(output_path, "coverage.acdb") self._coverage_files.add(coverage_file_path) vsim_flags += ["-acdb_file {%s}" % coverage_file_path] vsim_flags += [self._vsim_extra_args(config)] if config.sim_options.get("disable_ieee_warnings", False): vsim_flags.append("-ieee_nowarn") # Add the the testbench top-level unit last as coverage is # only collected for the top-level unit specified last vsim_flags += ["-lib", config.library_name, config.entity_name] if config.architecture_name is not None: vsim_flags.append(config.architecture_name) tcl = """ proc vunit_load {{}} {{ # Make the variable 'aldec' visible; otherwise, the Matlab interface # is broken because vsim does not find the library aldec_matlab_cosim. global aldec # Make the variable 'LICENSE_QUEUE' visible (if set); otherwise vsim # will not wait for simulation licenses. global LICENSE_QUEUE set vsim_failed [catch {{ eval vsim {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ return true }} if {{[_vunit_source_init_files_after_load]}} {{ return true }} vhdlassert.break {break_level} vhdlassert.break -builtin {break_level} return false }} """.format(vsim_flags=" ".join(vsim_flags), break_level=config.vhdl_assert_stop_level) return tcl
def _create_load_function(self, test_suite_name, config, output_path): """ Create the vunit_load TCL function that runs the vsim command and loads the design """ set_generic_str = " ".join(('-g/%s/%s=%s' % (config.entity_name, name, encode_generic_value(value)) for name, value in config.generics.items())) pli_str = " ".join("-pli {%s}" % fix_path(name) for name in config.sim_options.get('pli', [])) if config.architecture_name is None: architecture_suffix = "" else: architecture_suffix = "(%s)" % config.architecture_name if config.sim_options.get("enable_coverage", False): coverage_file = join(output_path, "coverage.ucdb") self._coverage_files.add(coverage_file) coverage_save_cmd = ( "coverage save -onexit -testname {%s} -assert -directive -cvg -codeAll {%s}" % (test_suite_name, fix_path(coverage_file))) coverage_args = "-coverage" else: coverage_save_cmd = "" coverage_args = "" vsim_flags = ["-wlf {%s}" % fix_path(join(output_path, "vsim.wlf")), "-quiet", "-t ps", # for correct handling of verilog fatal/finish "-onfinish stop", pli_str, set_generic_str, config.library_name + "." + config.entity_name + architecture_suffix, coverage_args, self._vsim_extra_args(config)] # There is a known bug in modelsim that prevents the -modelsimini flag from accepting # a space in the path even with escaping, see issue #36 if " " not in self._sim_cfg_file_name: vsim_flags.insert(0, "-modelsimini %s" % fix_path(self._sim_cfg_file_name)) for library in self._libraries: vsim_flags += ["-L", library.name] vhdl_assert_stop_level_mapping = dict(warning=1, error=2, failure=3) tcl = """ proc vunit_load {{{{vsim_extra_args ""}}}} {{ set vsim_failed [catch {{ eval vsim ${{vsim_extra_args}} {{{vsim_flags}}} }}] if {{${{vsim_failed}}}} {{ echo Command 'vsim ${{vsim_extra_args}} {vsim_flags}' failed echo Bad flag from vsim_extra_args? return true }} if {{[_vunit_source_init_files_after_load]}} {{ return true }} global BreakOnAssertion set BreakOnAssertion {break_on_assert} global NumericStdNoWarnings set NumericStdNoWarnings {no_warnings} global StdArithNoWarnings set StdArithNoWarnings {no_warnings} {coverage_save_cmd} return false }} """.format(coverage_save_cmd=coverage_save_cmd, vsim_flags=" ".join(vsim_flags), break_on_assert=vhdl_assert_stop_level_mapping[config.vhdl_assert_stop_level], no_warnings=1 if config.sim_options.get("disable_ieee_warnings", False) else 0) return tcl