Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added code coverage support to ActiveHDL #461

Merged
merged 3 commits into from
Mar 22, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions vunit/activehdl_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
import logging
from vunit.ostools import Process, write_file, file_exists, renew_path
from vunit.test_suites import get_result_file_name
from vunit.vsim_simulator_mixin import get_is_test_suite_done_tcl
from vunit.vsim_simulator_mixin import (get_is_test_suite_done_tcl,
fix_path)
from vunit.simulator_interface import (SimulatorInterface,
ListOfStringOption,
StringOption)
Expand Down Expand Up @@ -78,6 +79,7 @@ def __init__(self, prefix, output_path, gui=False):
self._prefix = prefix
self._create_library_cfg()
self._libraries = []
self._coverage_files = set()

def setup_library_mapping(self, project):
"""
Expand Down Expand Up @@ -191,7 +193,7 @@ def _vsim_extra_args(self, config):

return " ".join(vsim_extra_args)

def _create_load_function(self, config):
def _create_load_function(self, config, output_path):
"""
Create the vunit_load TCL function that runs the vsim command and loads the design
"""
Expand All @@ -212,11 +214,19 @@ def _create_load_function(self, config):
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 = """
Expand Down Expand Up @@ -264,13 +274,44 @@ def _create_run_function():
}
"""

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_common_script(self, config, output_path):
"""
Create tcl script with functions common to interactive and batch modes
"""
tcl = ""
tcl += get_is_test_suite_done_tcl(get_result_file_name(output_path))
tcl += self._create_load_function(config)
tcl += self._create_load_function(config, output_path)
tcl += self._create_run_function()
return tcl

Expand Down Expand Up @@ -374,8 +415,3 @@ def __call__(self, line):
self.major = int(match.group('major'))
self.minor = int(match.group('minor'))
return True


def fix_path(path):
""" Remove backslash """
return path.replace("\\", "/")