Skip to content

Commit

Permalink
Added support for manual addition of VHDL configurations.
Browse files Browse the repository at this point in the history
  • Loading branch information
LarsAsplund committed Jul 18, 2023
1 parent b7fcc7f commit 6f0615f
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 14 deletions.
18 changes: 18 additions & 0 deletions tests/acceptance/artificial/vhdl/cfg1.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- 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-2023, Lars Asplund lars.anders.asplund@gmail.com

architecture arch1 of ent is
begin
arch <= "arch1";
end;

configuration cfg1 of tb_with_vhdl_configuration is
for tb
for ent_inst : ent
use entity work.ent(arch1);
end for;
end for;
end;
18 changes: 18 additions & 0 deletions tests/acceptance/artificial/vhdl/cfg2.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- 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-2023, Lars Asplund lars.anders.asplund@gmail.com

architecture arch2 of ent is
begin
arch <= "arch2";
end;

configuration cfg2 of tb_with_vhdl_configuration is
for tb
for ent_inst : ent
use entity work.ent(arch2);
end for;
end for;
end;
9 changes: 9 additions & 0 deletions tests/acceptance/artificial/vhdl/ent.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- 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-2023, Lars Asplund lars.anders.asplund@gmail.com

entity ent is
port(arch : out string(1 to 5));
end;
17 changes: 17 additions & 0 deletions tests/acceptance/artificial/vhdl/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,27 @@ def configure_tb_assert_stop_level(ui):
test.set_sim_option("vhdl_assert_stop_level", vhdl_assert_stop_level)


def configure_tb_with_vhdl_configuration(ui):
def make_post_check(expected_arch):
def post_check(output_path):
arch = (Path(output_path) / "result.txt").read_text()
if arch[:-1] != expected_arch:
raise RuntimeError(f"Error! Got {arch[: -1]}, expected {expected_arch}")

return True

return post_check

tb = ui.library("lib").entity("tb_with_vhdl_configuration")
tb.add_config(name="cfg1", post_check=make_post_check("arch1"), vhdl_configuration_name="cfg1")
tb.add_config(name="cfg2", post_check=make_post_check("arch2"), vhdl_configuration_name="cfg2")


configure_tb_with_generic_config()
configure_tb_same_sim_all_pass(vu)
configure_tb_set_generic(vu)
configure_tb_assert_stop_level(vu)
configure_tb_with_vhdl_configuration(vu)
lib.entity("tb_no_generic_override").set_generic("g_val", False)
lib.entity("tb_ieee_warning").test("pass").set_sim_option("disable_ieee_warnings", True)
lib.entity("tb_other_file_tests").scan_tests_from_file(str(root / "other_file_tests.vhd"))
Expand Down
46 changes: 46 additions & 0 deletions tests/acceptance/artificial/vhdl/tb_with_vhdl_configuration.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
-- 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-2023, Lars Asplund lars.anders.asplund@gmail.com

library vunit_lib;
context vunit_lib.vunit_context;

use std.textio.all;

entity tb_with_vhdl_configuration is
generic(runner_cfg : string);
end entity;

architecture tb of tb_with_vhdl_configuration is
component ent
port(arch : out string(1 to 5));
end component;

signal arch : string(1 to 5);

begin
test_runner : process
file result_fptr : text;
variable result_line : line;
begin
test_runner_setup(runner, runner_cfg);

file_open(result_fptr, join(output_path(runner_cfg), "result.txt"), write_mode);
write(result_line, arch);
writeline(result_fptr, result_line);
file_close(result_fptr);

info(arch);

test_runner_cleanup(runner);
wait;
end process;

ent_inst : ent
port map(
arch => arch
);

end architecture;
8 changes: 8 additions & 0 deletions tests/acceptance/test_artificial.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,12 @@ def test_exit_0_flag(self):
"failed",
"lib.tb_assert_stop_level.Report failure when VHDL assert stop level = failure",
),
(
"passed",
"lib.tb_with_vhdl_configuration.cfg1",
),
(
"passed",
"lib.tb_with_vhdl_configuration.cfg2",
),
)
18 changes: 18 additions & 0 deletions tests/unit/test_incisive_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from vunit.ostools import renew_path, write_file, read_file
from vunit.test.bench import Configuration
from vunit.vhdl_standard import VHDL
from tests.common import create_tempdir
from tests.unit.test_test_bench import Entity


class TestIncisiveInterface(unittest.TestCase):
Expand Down Expand Up @@ -956,6 +958,21 @@ def test_simulate_gui(self, run_command, find_cds_root_irun, find_cds_root_virtu
],
)

@mock.patch("vunit.sim_if.incisive.IncisiveInterface.find_cds_root_virtuoso")
@mock.patch("vunit.sim_if.incisive.IncisiveInterface.find_cds_root_irun")
def test_configuration_and_entity_selection(self, find_cds_root_irun, find_cds_root_virtuoso):
find_cds_root_irun.return_value = "cds_root_irun"
find_cds_root_virtuoso.return_value = None

with create_tempdir() as tempdir:
design_unit = Entity("tb_entity", file_name=str(Path(tempdir) / "file.vhd"))
design_unit.generic_names = ["runner_cfg"]
config = Configuration("name", design_unit, vhdl_configuration_name="cfg")
simif = IncisiveInterface(prefix="prefix", output_path=self.output_path)
self.assertEqual(simif._select_vhdl_top(config), "cfg") # pylint: disable=protected-access
config = Configuration("name", design_unit)
self.assertEqual(simif._select_vhdl_top(config), "lib.tb_entity:arch") # pylint: disable=protected-access

def setUp(self):
self.output_path = str(Path(__file__).parent / "test_incisive_out")
renew_path(self.output_path)
Expand Down Expand Up @@ -985,4 +1002,5 @@ def make_config(sim_options=None, generics=None, verilog=False):

cfg.sim_options = {} if sim_options is None else sim_options
cfg.generics = {} if generics is None else generics
cfg.vhdl_configuration_name = None
return cfg
13 changes: 13 additions & 0 deletions vunit/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ def __init__( # pylint: disable=too-many-arguments
pre_config=None,
post_check=None,
attributes=None,
vhdl_configuration_name=None,
):
self.name = name
self._design_unit = design_unit
self.generics = {} if generics is None else generics
self.sim_options = {} if sim_options is None else sim_options
self.attributes = {} if attributes is None else attributes
self.vhdl_configuration_name = vhdl_configuration_name

self.tb_path = str(Path(design_unit.original_file_name).parent)

Expand All @@ -64,6 +66,7 @@ def copy(self):
pre_config=self.pre_config,
post_check=self.post_check,
attributes=self.attributes.copy(),
vhdl_configuration_name=self.vhdl_configuration_name,
)

@property
Expand Down Expand Up @@ -102,6 +105,12 @@ def set_attribute(self, name, value):
else:
raise AttributeException

def set_vhdl_configuration_name(self, name):
"""
Set VHDL configuration name
"""
self.vhdl_configuration_name = name

def set_generic(self, name, value):
"""
Set generic
Expand Down Expand Up @@ -248,6 +257,7 @@ def add_config( # pylint: disable=too-many-arguments
post_check=None,
sim_options=None,
attributes=None,
vhdl_configuration_name=None,
):
"""
Add a configuration copying unset fields from the default configuration:
Expand Down Expand Up @@ -283,4 +293,7 @@ def add_config( # pylint: disable=too-many-arguments
raise AttributeException
config.attributes.update(attributes)

if vhdl_configuration_name is not None:
config.vhdl_configuration_name = vhdl_configuration_name

configs[config.name] = config
9 changes: 6 additions & 3 deletions vunit/sim_if/activehdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,14 @@ def _create_load_function(self, config, output_path):
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.vhdl_configuration_name is None:
vsim_flags.append(config.entity_name)
if config.architecture_name is not None:
vsim_flags.append(config.architecture_name)
else:
vsim_flags.append(config.vhdl_configuration_name)

if config.sim_options.get("enable_coverage", False):
coverage_file_path = str(Path(output_path) / "coverage.acdb")
Expand Down
6 changes: 5 additions & 1 deletion vunit/sim_if/ghdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,11 @@ def _get_command(self, config, output_path, elaborate_only, ghdl_e, wave_file):
if config.sim_options.get("enable_coverage", False):
# Enable coverage in linker
cmd += ["-Wl,-lgcov"]
cmd += [config.entity_name, config.architecture_name]

if config.vhdl_configuration_name is not None:
cmd += [config.vhdl_configuration_name]
else:
cmd += [config.entity_name, config.architecture_name]

sim = config.sim_options.get("ghdl.sim_flags", [])
for name, value in config.generics.items():
Expand Down
15 changes: 13 additions & 2 deletions vunit/sim_if/incisive.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,17 @@ def _get_mapped_libraries(self):
cds = CDSFile.parse(self._cdslib)
return cds

def simulate(self, output_path, test_suite_name, config, elaborate_only=False): # pylint: disable=too-many-locals
@staticmethod
def _select_vhdl_top(config):
"Select VHDL configuration or entity as top."
if config.vhdl_configuration_name is None:
return f"{config.library_name!s}.{config.entity_name!s}:{config.architecture_name!s}"

return f"{config.vhdl_configuration_name!s}"

def simulate(
self, output_path, test_suite_name, config, elaborate_only=False
): # pylint: disable=too-many-locals,too-many-branches
"""
Elaborates and Simulates with entity as top level using generics
"""
Expand Down Expand Up @@ -336,7 +346,8 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only=False):
args += [f"-top {config.library_name!s}.{config.entity_name!s}:sv"]
else:
# we have a VHDL toplevel:
args += [f"-top {config.library_name!s}.{config.entity_name!s}:{config.architecture_name!s}"]
args += [f"-top {self._select_vhdl_top(config)}"]

argsfile = f"{script_path!s}/irun_{step!s}.args"
write_file(argsfile, "\n".join(args))
if not run_command(
Expand Down
8 changes: 7 additions & 1 deletion vunit/sim_if/modelsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ def _create_load_function(self, test_suite_name, config, output_path):
coverage_save_cmd = ""
coverage_args = ""

simulation_target = (
config.library_name + "." + config.entity_name + architecture_suffix
if config.vhdl_configuration_name is None
else config.library_name + "." + config.vhdl_configuration_name
)

vsim_flags = [
f"-wlf {{{fix_path(str(Path(output_path) / 'vsim.wlf'))!s}}}",
"-quiet",
Expand All @@ -266,7 +272,7 @@ def _create_load_function(self, test_suite_name, config, output_path):
"-onfinish stop",
pli_str,
set_generic_str,
config.library_name + "." + config.entity_name + architecture_suffix,
simulation_target,
coverage_args,
self._vsim_extra_args(config),
]
Expand Down
7 changes: 5 additions & 2 deletions vunit/sim_if/nvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def compile_vhdl_file_command(self, source_file):
cmd += [source_file.name]
return cmd

def simulate(self, output_path, test_suite_name, config, elaborate_only):
def simulate(self, output_path, test_suite_name, config, elaborate_only): # pylint: disable=too-many-branches
"""
Simulate with entity as top level using generics
"""
Expand All @@ -261,7 +261,10 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only):
cmd += ["-e"]

cmd += config.sim_options.get("nvc.elab_flags", [])
cmd += [f"{config.entity_name}-{config.architecture_name}"]
if config.vhdl_configuration_name is not None:
cmd += [config.vhdl_configuration_name]
else:
cmd += [f"{config.entity_name}-{config.architecture_name}"]

for name, value in config.generics.items():
cmd += [f"-g{name}={value}"]
Expand Down
15 changes: 10 additions & 5 deletions vunit/sim_if/rivierapro.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,17 @@ def _create_load_function(self, test_suite_name, config, output_path): # pylint
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]
vsim_flags += ["-lib", config.library_name]

if config.architecture_name is not None:
vsim_flags.append(config.architecture_name)
if config.vhdl_configuration_name is None:
# Add the the testbench top-level unit last as coverage is
# only collected for the top-level unit specified last
vsim_flags += [config.entity_name]

if config.architecture_name is not None:
vsim_flags.append(config.architecture_name)
else:
vsim_flags += [config.vhdl_configuration_name]

tcl = """
proc vunit_load {{}} {{
Expand Down
2 changes: 2 additions & 0 deletions vunit/ui/testbench.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def add_config( # pylint: disable=too-many-arguments
post_check=None,
sim_options=None,
attributes=None,
vhdl_configuration_name=None,
):
"""
Add a configuration of this test bench or to all test cases within it by copying the default configuration.
Expand Down Expand Up @@ -181,6 +182,7 @@ def add_config( # pylint: disable=too-many-arguments
post_check=post_check,
sim_options=sim_options,
attributes=attributes,
vhdl_configuration_name=vhdl_configuration_name,
)

def test(self, name):
Expand Down

0 comments on commit 6f0615f

Please sign in to comment.