Skip to content

Commit

Permalink
Adds ability to disable ieee warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
kraigher committed May 30, 2015
1 parent 6558a92 commit 1c2f838
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 19 deletions.
21 changes: 20 additions & 1 deletion user_guide.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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()
```
25 changes: 18 additions & 7 deletions vunit/modelsim_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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
"""
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion vunit/test/acceptance/artificial/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
30 changes: 30 additions & 0 deletions vunit/test/acceptance/artificial/vhdl/tb_ieee_warning.vhd
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion vunit/test/acceptance/test_artificial.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
26 changes: 26 additions & 0 deletions vunit/test/unit/test_test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,42 @@ 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")])
self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity2")),
[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):
Expand Down
3 changes: 3 additions & 0 deletions vunit/test_bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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)
43 changes: 36 additions & 7 deletions vunit/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()):
"""
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -136,32 +161,36 @@ def add(scopes):
add(self._generics)
add(self._configs)
add(self._plis)
add(self._disable_ieee_warnings)
return result


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):
Expand Down
1 change: 1 addition & 0 deletions vunit/test_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
29 changes: 27 additions & 2 deletions vunit/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand Down

0 comments on commit 1c2f838

Please sign in to comment.