From 1c2f838de6458e44517b79df57110fe44007710f Mon Sep 17 00:00:00 2001 From: Olof Kraigher Date: Sat, 30 May 2015 13:27:18 +0200 Subject: [PATCH] Adds ability to disable ieee warnings --- user_guide.md | 21 ++++++++- vunit/modelsim_interface.py | 25 ++++++++--- vunit/test/acceptance/artificial/run.py | 2 +- .../artificial/vhdl/tb_ieee_warning.vhd | 30 +++++++++++++ vunit/test/acceptance/test_artificial.py | 4 +- vunit/test/unit/test_test_configuration.py | 26 +++++++++++ vunit/test_bench.py | 3 ++ vunit/test_configuration.py | 43 ++++++++++++++++--- vunit/test_scanner.py | 1 + vunit/ui.py | 29 ++++++++++++- 10 files changed, 165 insertions(+), 19 deletions(-) create mode 100644 vunit/test/acceptance/artificial/vhdl/tb_ieee_warning.vhd diff --git a/user_guide.md b/user_guide.md index 58f99cba4..f1e19a2a5 100644 --- a/user_guide.md +++ b/user_guide.md @@ -1,7 +1,7 @@ # VUnit User Guide ## Introduction -The idea in VUnit is to have a single point of entry for compiling and running all tests within a VHDL project. Tests do not need to be manually added to some list as they are automatically detected. There is no need for maintaining a list of files in compile order or manually re-compile selected files after they have been edited as VUnit automatically determines the compile order as well as which files to incrementally re-compile. This is achieved by having a `run.py` file for each project where libraries are defined into which files are added using the VUnit Python interface. The `run.py` file then acts as a command line utility for compiling and running tests within the VHDL project. +The idea in VUnit is to have a single point of entry for compiling and running all tests within a VHDL project. Tests do not need to be manually added to some list as they are automatically detected. There is no need for maintaining a list of files in compile order or manually re-compile selected files after they have been edited as VUnit automatically determines the compile order as well as which files to incrementally re-compile. This is achieved by having a `run.py` file for each project where libraries are defined into which files are added using the VUnit Python interface. The `run.py` file then acts as a command line utility for compiling and running tests within the VHDL project. ## Python Interface @@ -221,3 +221,22 @@ vunit_run It is also possible to automatically run the test case in the gui while logging all signals and variables recursively using the `--gui=run` flag. After simulation the user can manually add objects of interest to the waveform viewer without re-running since everything has been logged. When running large designs this mode can be quite slow and it might be better to just do `--gui=load` and manually add a few signals of interest. + +## Disabling warnings from IEEE packages +Warnings from IEEE packages can be disabled in `run.py`: +```python +# They can be lobally disabled... +vu.disable_ieee_warnings() + +# ... or just disabled for a library +lib = vu.lib("lib") +lib.disable_ieee_warnings() + +# ... or just disabled for a test bench +ent = lib.entity("ent") +ent.disable_ieee_warnings() + +# ... or just disabled for a test case +test = ent.test("test") +test.disable_ieee_warnings() +``` diff --git a/vunit/modelsim_interface.py b/vunit/modelsim_interface.py index 7e8b4c69f..2e4a06ba6 100644 --- a/vunit/modelsim_interface.py +++ b/vunit/modelsim_interface.py @@ -247,17 +247,25 @@ def _create_load_function(self, # pylint: disable=too-many-arguments return tcl @staticmethod - def _create_run_function(fail_on_warning=False): + def _create_run_function(fail_on_warning=False, disable_ieee_warnings=False): """ Create the vunit_run function to run the test bench """ + if disable_ieee_warnings: + no_warnings = 1 + else: + no_warnings = 0 return """ proc vunit_run {} { global BreakOnAssertion - - # Break on error set BreakOnAssertion %i + global NumericStdNoWarnings + set NumericStdNoWarnings %i + + global StdArithNoWarnings + set StdArithNoWarnings %i + proc on_break {} { resume } @@ -294,11 +302,12 @@ def _create_run_function(fail_on_warning=False): } return $failed } -""" % (1 if fail_on_warning else 2) +""" % (1 if fail_on_warning else 2, no_warnings, no_warnings) def _create_common_script(self, # pylint: disable=too-many-arguments library_name, entity_name, architecture_name, - generics, pli, fail_on_warning, output_path): + generics, pli, fail_on_warning, disable_ieee_warnings, + output_path): """ Create tcl script with functions common to interactive and batch modes """ @@ -315,7 +324,7 @@ def _create_common_script(self, # pylint: disable=too-many-arguments } """ tcl += self._create_load_function(library_name, entity_name, architecture_name, generics, pli, output_path) - tcl += self._create_run_function(fail_on_warning) + tcl += self._create_run_function(fail_on_warning, disable_ieee_warnings) return tcl @staticmethod @@ -429,7 +438,8 @@ def _run_persistent(self, common_file_name, load_only=False): def simulate(self, output_path, # pylint: disable=too-many-arguments library_name, entity_name, architecture_name=None, - generics=None, pli=None, load_only=None, fail_on_warning=False): + generics=None, pli=None, load_only=None, fail_on_warning=False, + disable_ieee_warnings=False): """ Run a test bench load_only -- Only load the design performing elaboration without simulating @@ -445,6 +455,7 @@ def simulate(self, output_path, # pylint: disable=too-many-arguments write_file(common_file_name, self._create_common_script(library_name, entity_name, architecture_name, generics, pli, fail_on_warning=fail_on_warning, + disable_ieee_warnings=disable_ieee_warnings, output_path=msim_output_path)) write_file(gui_load_file_name, self._create_gui_load_script(common_file_name)) diff --git a/vunit/test/acceptance/artificial/run.py b/vunit/test/acceptance/artificial/run.py index 4228ba2ad..3e1d08465 100644 --- a/vunit/test/acceptance/artificial/run.py +++ b/vunit/test/acceptance/artificial/run.py @@ -46,5 +46,5 @@ def post_check(output_path): post_check=post_check) configure_tb_with_generic_config(ui) - +lib.entity("tb_ieee_warning").disable_ieee_warnings() ui.main() diff --git a/vunit/test/acceptance/artificial/vhdl/tb_ieee_warning.vhd b/vunit/test/acceptance/artificial/vhdl/tb_ieee_warning.vhd new file mode 100644 index 000000000..217efbf09 --- /dev/null +++ b/vunit/test/acceptance/artificial/vhdl/tb_ieee_warning.vhd @@ -0,0 +1,30 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2015, Lars Asplund lars.anders.asplund@gmail.com + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library vunit_lib; +context vunit_lib.vunit_context; + +entity tb_ieee_warning is + generic (runner_cfg : runner_cfg_t); +end entity; + +architecture vunit_test_bench of tb_ieee_warning is +begin + test_runner : process + variable undefined : unsigned(15 downto 0); + begin + test_runner_setup(runner, runner_cfg); + report integer'image(to_integer(undefined)); + test_runner_cleanup(runner); + wait; + end process; +end architecture; + +-- vunit_pragma fail_on_warning diff --git a/vunit/test/acceptance/test_artificial.py b/vunit/test/acceptance/test_artificial.py index 22e904cc3..1ab5c2d8f 100644 --- a/vunit/test/acceptance/test_artificial.py +++ b/vunit/test/acceptance/test_artificial.py @@ -172,4 +172,6 @@ def check(self, run_file, args=None, persistent_sim=True, clean=True, exit_code= ("passed", "lib.tb_with_generic_config.Test 1"), ("passed", "lib.tb_with_generic_config.Test 2"), ("passed", "lib.tb_with_generic_config.Test 3"), - ("passed", "lib.tb_with_generic_config.Test 4")) + ("passed", "lib.tb_with_generic_config.Test 4"), + + ("passed", "lib.tb_ieee_warning")) diff --git a/vunit/test/unit/test_test_configuration.py b/vunit/test/unit/test_test_configuration.py index 8db9d8dca..56cfd3212 100644 --- a/vunit/test/unit/test_test_configuration.py +++ b/vunit/test/unit/test_test_configuration.py @@ -98,9 +98,33 @@ def test_add_config(self): self.assertEqual(self.cfg.get_configurations(create_scope("lib", "tb_entity", "configured test")), [Configuration("specific_test_config", dict(global_value="global value"))]) + def test_disable_ieee_warnings(self): + lib_scope = create_scope("lib") + ent_scope = create_scope("lib", "entity") + self.assertEqual(self.cfg.get_configurations(lib_scope), + [Configuration(disable_ieee_warnings=False)]) + + self.assertEqual(self.cfg.get_configurations(ent_scope), + [Configuration(disable_ieee_warnings=False)]) + + self.cfg.disable_ieee_warnings(ent_scope) + self.assertEqual(self.cfg.get_configurations(lib_scope), + [Configuration(disable_ieee_warnings=False)]) + + self.assertEqual(self.cfg.get_configurations(ent_scope), + [Configuration(disable_ieee_warnings=True)]) + + self.cfg.disable_ieee_warnings(lib_scope) + self.assertEqual(self.cfg.get_configurations(lib_scope), + [Configuration(disable_ieee_warnings=True)]) + + self.assertEqual(self.cfg.get_configurations(ent_scope), + [Configuration(disable_ieee_warnings=False)]) + def test_more_specific_configurations(self): self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity3")) self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity", "test")) + self.cfg.disable_ieee_warnings(scope=create_scope("lib", "entity_ieee", "test")) self.cfg.add_config(name="name", generics=dict(), scope=create_scope("lib", "entity2", "test")) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity")), [create_scope("lib", "entity", "test")]) @@ -108,6 +132,8 @@ def test_more_specific_configurations(self): [create_scope("lib", "entity2", "test")]) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity3")), []) + self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity_ieee")), + [create_scope("lib", "entity_ieee", "test")]) @staticmethod def write_file(name, contents): diff --git a/vunit/test_bench.py b/vunit/test_bench.py index 30e0cebe4..5c193238e 100644 --- a/vunit/test_bench.py +++ b/vunit/test_bench.py @@ -21,6 +21,7 @@ def __init__(self, # pylint: disable=too-many-arguments generics=None, has_output_path=False, fail_on_warning=False, + disable_ieee_warnings=False, pli=None, elaborate_only=False): self._simulator_if = simulator_if @@ -30,6 +31,7 @@ def __init__(self, # pylint: disable=too-many-arguments self._architecture_name = architecture_name self._has_output_path = has_output_path self._fail_on_warning = fail_on_warning + self._disable_ieee_warnings = disable_ieee_warnings self._pli = pli self._elaborate_only = elaborate_only @@ -51,5 +53,6 @@ def run(self, output_path, extra_generics=None): self._architecture_name, generics, fail_on_warning=self._fail_on_warning, + disable_ieee_warnings=self._disable_ieee_warnings, pli=self._pli, load_only=self._elaborate_only) diff --git a/vunit/test_configuration.py b/vunit/test_configuration.py index 5507984c4..cf4d2abe0 100644 --- a/vunit/test_configuration.py +++ b/vunit/test_configuration.py @@ -44,6 +44,7 @@ def __init__(self): self._generics = {} self._configs = {} self._plis = {} + self._disable_ieee_warnings = set() def set_generic(self, name, value, scope=create_scope()): """ @@ -59,6 +60,12 @@ def set_pli(self, value, scope=create_scope()): """ self._plis[scope] = value + def disable_ieee_warnings(self, scope=create_scope()): + """ + Disable ieee warnings within scope + """ + self._disable_ieee_warnings.add(scope) + def add_config(self, scope, name, generics, post_check=None): """ Add a configuration for scope specifying the name of the @@ -76,16 +83,25 @@ def get_configurations(self, scope): global_generics = self._get_generics_for_scope(scope) pli = self._get_pli_for_scope(scope) configs_for_scope = self._get_configs_for_scope(scope) + disable_ieee_warnings = self._ieee_warnings_disabled_in_scope(scope) configs = [] for config_name in sorted(configs_for_scope.keys()): cfg_generics, post_check = configs_for_scope[config_name] generics = global_generics.copy() generics.update(cfg_generics) - configs.append(Configuration(config_name, generics, post_check, pli)) + configs.append(Configuration(config_name, + generics, + post_check, + pli, + disable_ieee_warnings)) if len(configs) == 0: - configs = [Configuration("", global_generics.copy(), None, pli)] + configs = [Configuration("", + global_generics.copy(), + None, + pli, + disable_ieee_warnings)] return configs @@ -121,6 +137,15 @@ def _get_pli_for_scope(self, scope): plis = self._plis.get(iter_scope, plis) return plis + def _ieee_warnings_disabled_in_scope(self, scope): + """ + Return true if ieee warnings are disabled within scope + """ + for iter_scope in iter_scopes(scope): + if iter_scope in self._disable_ieee_warnings: + return True + return False + def more_specific_configurations(self, scope): """ Return scopes containing more specific configurations @@ -136,6 +161,7 @@ def add(scopes): add(self._generics) add(self._configs) add(self._plis) + add(self._disable_ieee_warnings) return result @@ -143,25 +169,28 @@ class Configuration(object): """ Represents a configuration of a test bench """ - def __init__(self, + def __init__(self, # pylint: disable=too-many-arguments name="", generics=None, post_check=None, - pli=None): + pli=None, + disable_ieee_warnings=False): self.name = name self.generics = generics if generics is not None else {} self.post_check = post_check self.pli = [] if pli is None else pli + self.disable_ieee_warnings = disable_ieee_warnings def __eq__(self, other): return (self.name == other.name and self.generics == other.generics and self.post_check == other.post_check and - self.pli == other.pli) + self.pli == other.pli, + self.disable_ieee_warnings == other.disable_ieee_warnings) def __repr__(self): - return("Configuration(%r, %r, %r, %r)" - % (self.name, self.generics, self.post_check, self.pli)) + return("Configuration(%r, %r, %r, %r, %r)" + % (self.name, self.generics, self.post_check, self.pli, self.disable_ieee_warnings)) def is_within_scope(scope, other_scope): diff --git a/vunit/test_scanner.py b/vunit/test_scanner.py index 72001d53b..7d5e5ffae 100644 --- a/vunit/test_scanner.py +++ b/vunit/test_scanner.py @@ -83,6 +83,7 @@ def add_tb_path_generic(generics): architecture_name=architecture_name, entity_name=entity.name, fail_on_warning=fail_on_warning, + disable_ieee_warnings=config.disable_ieee_warnings, has_output_path="output_path" in entity.generic_names, generics=generics, pli=config.pli, diff --git a/vunit/ui.py b/vunit/ui.py index 11e878f96..35a841b52 100644 --- a/vunit/ui.py +++ b/vunit/ui.py @@ -215,6 +215,12 @@ def set_pli(self, value): """ self._configuration.set_pli(value, scope=create_scope()) + def disable_ieee_warnings(self): + """ + Globally disable ieee warnings + """ + self._configuration.disable_ieee_warnings(scope=create_scope()) + def add_source_files(self, pattern, library_name, preprocessors=None): """ Add source files matching wildcard pattern to library @@ -458,14 +464,21 @@ def __init__(self, library_name, parent, project, configuration): self._parent = parent self._project = project self._configuration = configuration + self._scope = create_scope(self._library_name) def set_generic(self, name, value): """ Set generic within library """ - self._configuration.set_generic(name, value, scope=create_scope(self._library_name)) + self._configuration.set_generic(name, value, scope=self._scope) def set_pli(self, value): """ Set pli within library """ - self._configuration.set_pli(value, scope=create_scope(self._library_name)) + self._configuration.set_pli(value, scope=self._scope) + + def disable_ieee_warnings(self): + """ + Disable ieee warnings within library + """ + self._configuration.disable_ieee_warnings(scope=self._scope) def add_source_files(self, pattern, preprocessors=None): self._parent.add_source_files(pattern, self._library_name, preprocessors) @@ -520,6 +533,12 @@ def add_config(self, name, generics, post_check=None): generics=generics, post_check=post_check) + def disable_ieee_warnings(self): + """ + Disable ieee warnings within entity + """ + self._config.disable_ieee_warnings(scope=self._scope) + def test(self, test_name): """ Return the test case with test_name @@ -587,6 +606,12 @@ def set_generic(self, name, value): """ self._config.set_generic(name, value, scope=self._scope) + def disable_ieee_warnings(self): + """ + Disable ieee warnings for test case + """ + self._config.disable_ieee_warnings(scope=self._scope) + def file_type_of(file_name): """