Skip to content

Commit 883d975

Browse files
committed
Added support for VCI and VC belonging to different libraries.
Improved compliance tests to detect lack of as_sync function and added missing functions to VUnit VCIs
1 parent 9b864c4 commit 883d975

File tree

8 files changed

+103
-35
lines changed

8 files changed

+103
-35
lines changed

tests/unit/test_compliance_test.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class TestComplianceTest(TestCase): # pylint: disable=too-many-public-methods
2929
def setUp(self):
3030
self.tmp_dir = Path(__file__).parent / "vc_tmp"
3131
renew_path(str(self.tmp_dir))
32+
self.vc_dir = self.tmp_dir / "vc"
33+
renew_path(str(self.vc_dir))
34+
self.vci_dir = self.tmp_dir / "vci"
35+
renew_path(str(self.vci_dir))
3236
self.vc_contents = """
3337
library ieee
3438
use ieee.std_logic_1164.all;
@@ -45,7 +49,7 @@ def setUp(self):
4549
4650
end entity;
4751
"""
48-
self.vc_path = self.make_file("vc.vhd", self.vc_contents)
52+
self.vc_path = self.make_file("vc.vhd", self.vc_contents, self.vc_dir)
4953

5054
self.vci_contents = """
5155
package vc_pkg is
@@ -59,32 +63,38 @@ def setUp(self):
5963
checker : checker_t := null_checker;
6064
unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail
6165
) return vc_handle_t;
66+
67+
function as_sync(handle : vc_handle_t) return sync_handle_t;
6268
end package;
6369
"""
64-
self.vci_path = self.make_file("vci.vhd", self.vci_contents)
70+
self.vci_path = self.make_file("vci.vhd", self.vci_contents, self.vci_dir)
6571

6672
self.ui = VUnit.from_argv([])
6773

6874
self.vc_lib = self.ui.add_library("vc_lib")
69-
self.vc_lib.add_source_files(str(self.tmp_dir / "*.vhd"))
75+
self.vc_lib.add_source_files(str(self.vc_dir / "*.vhd"))
76+
77+
self.vci_lib = self.ui.add_library("vci_lib")
78+
self.vci_lib.add_source_files(str(self.vci_dir / "*.vhd"))
7079

7180
def tearDown(self):
7281
if self.tmp_dir.exists():
7382
rmtree(self.tmp_dir)
7483

75-
def make_file(self, file_name, contents):
84+
def make_file(self, file_name, contents, directory=None):
7685
"""
7786
Create a file in the temporary directory with contents
7887
Returns the absolute path to the file.
7988
"""
80-
full_file_name = (self.tmp_dir / file_name).resolve()
89+
directory = directory if directory is not None else self.tmp_dir
90+
full_file_name = (directory / file_name).resolve()
8191
with full_file_name.open("w") as outfile:
8292
outfile.write(contents)
8393
return str(full_file_name)
8494

8595
@mock.patch("vunit.vc.verification_component_interface.LOGGER.error")
8696
def test_not_finding_vc(self, error_mock):
87-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
97+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
8898
self.assertRaises(
8999
SystemExit, VerificationComponent.find, self.vc_lib, "other_vc", vci
90100
)
@@ -95,7 +105,7 @@ def test_not_finding_vci(self, error_mock):
95105
self.assertRaises(
96106
SystemExit,
97107
VerificationComponentInterface.find,
98-
self.vc_lib,
108+
self.vci_lib,
99109
"other_vc_pkg",
100110
"vc_handle_t",
101111
)
@@ -113,15 +123,15 @@ def test_failing_on_multiple_entities(self, error_mock):
113123
end entity;
114124
"""
115125
self.vc_lib.add_source_file(self.make_file("vc1_2.vhd", vc_contents))
116-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
126+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
117127
self.assertRaises(
118128
SystemExit, VerificationComponent.find, self.vc_lib, "vc1", vci
119129
)
120130
error_mock.assert_called_once_with(
121131
"%s must contain a single VC entity", self.tmp_dir / "vc1_2.vhd"
122132
)
123133

124-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
134+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
125135
self.assertRaises(
126136
SystemExit, VerificationComponent.find, self.vc_lib, "vc2", vci
127137
)
@@ -167,7 +177,7 @@ def test_evaluating_vc_generics(self, error_mock):
167177
end entity;
168178
"""
169179
self.vc_lib.add_source_file(self.make_file("vc1.vhd", vc1_contents))
170-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
180+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
171181
self.assertRaises(
172182
SystemExit, VerificationComponent.find, self.vc_lib, "vc1", vci
173183
)
@@ -179,7 +189,7 @@ def test_evaluating_vc_generics(self, error_mock):
179189
end entity;
180190
"""
181191
self.vc_lib.add_source_file(self.make_file("vc2.vhd", vc2_contents))
182-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
192+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
183193
self.assertRaises(
184194
SystemExit, VerificationComponent.find, self.vc_lib, "vc2", vci
185195
)
@@ -191,7 +201,7 @@ def test_evaluating_vc_generics(self, error_mock):
191201
end entity;
192202
"""
193203
self.vc_lib.add_source_file(self.make_file("vc3.vhd", vc3_contents))
194-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
204+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
195205
self.assertRaises(
196206
SystemExit, VerificationComponent.find, self.vc_lib, "vc3", vci
197207
)
@@ -206,6 +216,7 @@ def test_failing_with_no_constructor(self, error_mock):
206216
end record;
207217
208218
impure function create_vc return vc_handle_t;
219+
function as_sync(handle : vc_handle_t) return sync_handle_t;
209220
end package;
210221
"""
211222
self.vc_lib.add_source_file(self.make_file("other_vci.vhd", vci_contents))
@@ -230,6 +241,8 @@ def test_failing_with_wrong_constructor_return_type(self, error_mock):
230241
end record;
231242
232243
impure function new_vc return vc_t;
244+
function as_sync(handle : vc_handle_t) return sync_handle_t;
245+
233246
end package;
234247
"""
235248
self.vc_lib.add_source_file(self.make_file("other_vci.vhd", vci_contents))
@@ -300,6 +313,7 @@ def test_failing_on_incorrect_constructor_parameters(self, error_mock):
300313
vci_contents[:-2]
301314
+ """
302315
) return vc_handle_t;
316+
function as_sync(handle : vc_handle_t) return sync_handle_t;
303317
end package;
304318
"""
305319
)
@@ -348,6 +362,7 @@ def test_failing_on_non_private_handle_elements(self, error_mock):
348362
checker : checker_t := null_checker;
349363
unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail
350364
) return vc_handle_t;
365+
function as_sync(handle : vc_handle_t) return sync_handle_t;
351366
end package;
352367
"""
353368

@@ -378,6 +393,7 @@ def test_failing_on_missing_handle_record(self, error_mock):
378393
checker : checker_t := null_checker;
379394
unexpected_msg_type_policy : unexpected_msg_type_policy_t := fail
380395
) return vc_handle_t;
396+
function as_sync(handle : vc_handle_t) return sync_handle_t;
381397
end package;
382398
"""
383399

@@ -432,6 +448,7 @@ def test_error_on_missing_default_value(self):
432448
vci_contents[:-2]
433449
+ """
434450
) return vc_handle_t;
451+
function as_sync(handle : vc_handle_t) return sync_handle_t;
435452
end package;
436453
"""
437454
)
@@ -472,11 +489,11 @@ def test_create_vhdl_testbench_template_references(self):
472489

473490
vc_path = self.make_file("vc2.vhd", vc_contents)
474491
template, _ = VerificationComponent.create_vhdl_testbench_template(
475-
"vc_lib", vc_path, self.vci_path
492+
"vc_lib", "vc_lib", vc_path, self.vci_path
476493
)
477494
template = VHDLDesignFile.parse(template)
478495
refs = template.references
479-
self.assertEqual(len(refs), 13)
496+
self.assertEqual(len(refs), 14)
480497
self.assertIn(VHDLReference("library", "vunit_lib"), refs)
481498
self.assertIn(VHDLReference("library", "vc_lib"), refs)
482499
self.assertIn(VHDLReference("library", "a_lib"), refs)
@@ -485,6 +502,7 @@ def test_create_vhdl_testbench_template_references(self):
485502
self.assertIn(VHDLReference("package", "vc_lib", "vc_pkg", "all"), refs)
486503
self.assertIn(VHDLReference("package", "a_lib", "x", "y"), refs)
487504
self.assertIn(VHDLReference("package", "vunit_lib", "sync_pkg", "all"), refs)
505+
self.assertIn(VHDLReference("package", "vunit_lib", "vc_pkg", "all"), refs)
488506
self.assertIn(VHDLReference("context", "vc_lib", "spam"), refs)
489507
self.assertIn(VHDLReference("context", "a_lib", "eggs"), refs)
490508
self.assertIn(VHDLReference("context", "vunit_lib", "vunit_context"), refs)
@@ -510,7 +528,7 @@ def test_template_with_wrong_name(self):
510528

511529
template_path = self.make_file("template.vhd", template_contents)
512530

513-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
531+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
514532
vc = VerificationComponent.find(self.vc_lib, "vc", vci)
515533
self.assertRaises(RuntimeError, vc.create_vhdl_testbench, template_path)
516534

@@ -532,7 +550,7 @@ def test_template_missing_contructor(self):
532550

533551
template_path = self.make_file("template.vhd", template_contents)
534552

535-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
553+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
536554
vc = VerificationComponent.find(self.vc_lib, "vc", vci)
537555
self.assertRaises(RuntimeError, vc.create_vhdl_testbench, template_path)
538556

@@ -555,7 +573,7 @@ def test_template_missing_runner_cfg(self):
555573

556574
template_path = self.make_file("template.vhd", template_contents)
557575

558-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
576+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
559577
vc = VerificationComponent.find(self.vc_lib, "vc", vci)
560578
self.assertRaises(RuntimeError, vc.create_vhdl_testbench, template_path)
561579

@@ -578,7 +596,7 @@ def test_template_missing_test_runner(self):
578596

579597
template_path = self.make_file("template.vhd", template_contents)
580598

581-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
599+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
582600
vc = VerificationComponent.find(self.vc_lib, "vc", vci)
583601
self.assertRaises(RuntimeError, vc.create_vhdl_testbench, template_path)
584602

@@ -667,7 +685,9 @@ def test_creating_template_with_specified_vc_lib(self):
667685
[
668686
"compliance_test.py",
669687
"create-vc",
670-
"-l",
688+
"--vc-lib-name",
689+
"my_vc_lib",
690+
"--vci-lib-name",
671691
"my_vc_lib",
672692
self.vc_path,
673693
self.vci_path,
@@ -688,7 +708,7 @@ def test_creating_template_with_specified_vc_lib(self):
688708
def test_adding_vhdl_testbench(self):
689709
vc_test_lib = self.ui.add_library("vc_test_lib")
690710

691-
vci = VerificationComponentInterface.find(self.vc_lib, "vc_pkg", "vc_handle_t")
711+
vci = VerificationComponentInterface.find(self.vci_lib, "vc_pkg", "vc_handle_t")
692712
vc = VerificationComponent.find(self.vc_lib, "vc", vci)
693713

694714
vc.add_vhdl_testbench(vc_test_lib, str(self.tmp_dir / "compliance_test"))

vunit/vc/compliance_test.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
def _create_vc_template(args):
1919
"""Creates VC testbench template from args."""
2020
template_code, vc_name = VerificationComponent.create_vhdl_testbench_template(
21-
args.vc_lib_name, args.vc_path, args.vci_path
21+
args.vc_lib_name, args.vci_lib_name, args.vc_path, args.vci_path
2222
)
2323
if not template_code or not vc_name:
2424
sys.exit(1)
@@ -46,21 +46,21 @@ def _create_vci_template(args):
4646
template_code,
4747
vci_name,
4848
) = VerificationComponentInterface.create_vhdl_testbench_template(
49-
args.vc_lib_name, args.vci_path, args.vc_handle_t
49+
args.vci_lib_name, args.vci_path, args.vc_handle_t
5050
)
5151
if not template_code or not vci_name:
5252
sys.exit(1)
5353

5454
if not args.output_path:
55-
output_dir = args.vci_path.parent / ".vc" / vci_name
55+
output_dir = args.vc_path.parent / ".vc" / vci_name
5656
if not output_dir.exists():
5757
output_dir.mkdir(parents=True)
5858

5959
output_path = output_dir / ("tb_%s_compliance_template.vhd" % args.vc_handle_t)
6060
elif args.output_path.is_dir():
6161
output_dir = args.output_path / vci_name
6262
if not output_dir.exists():
63-
output_dir.mkdir(parents=True)
63+
output_dir.exists(parents=True)
6464
output_path = output_dir / ("tb_%s_compliance_template.vhd" % args.vc_handle_t)
6565
else:
6666
output_path = args.output_path
@@ -79,9 +79,13 @@ def create_vc_parser(subparsers):
7979
"create-vc", help="Creates a VC compliance test template"
8080
)
8181
parser.add_argument(
82-
"-l",
8382
"--vc-lib-name",
84-
help="Name of library hosting the VC and the VCI (default: vc_lib)",
83+
help="Name of library hosting the VC (default: vc_lib)",
84+
default="vc_lib",
85+
)
86+
parser.add_argument(
87+
"--vci-lib-name",
88+
help="Name of library hosting the VCI (default: vc_lib)",
8589
default="vc_lib",
8690
)
8791
parser.add_argument(
@@ -102,9 +106,8 @@ def create_vci_parser(subparsers):
102106
"create-vci", help="Creates a VCI compliance test template"
103107
)
104108
parser.add_argument(
105-
"-l",
106-
"--vc-lib-name",
107-
help="Name of library hosting the VC and the VCI (default: vc_lib)",
109+
"--vci-lib-name",
110+
help="Name of library hosting the VCI (default: vc_lib)",
108111
default="vc_lib",
109112
)
110113
parser.add_argument(

vunit/vc/verification_component.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ def validate(vc_path):
9999
return vc_code
100100

101101
@staticmethod
102-
def create_vhdl_testbench_template(vc_lib_name, vc_path, vci_path):
102+
def create_vhdl_testbench_template(vc_lib_name, vci_lib_name, vc_path, vci_path):
103103
"""
104104
Creates a template for a VC compliance testbench.
105105
106-
:param vc_lib_name: Name of the library containing the verification component and its interface.
106+
:param vc_lib_name: Name of the library containing the verification component.
107+
:param vci_lib_name: Name of the library containing the verification component interface.
107108
:param vc_path: Path to the file containing the verification component entity.
108109
:param vci_path: Path to the file containing the verification component interface package.
109110
@@ -209,8 +210,9 @@ def create_signal_declarations_and_vc_instantiation(vc_entity, vc_lib_name):
209210

210211
initial_package_refs = set(
211212
[
213+
"vunit_lib.vc_pkg.all",
212214
"vunit_lib.sync_pkg.all",
213-
"%s.%s.all" % (vc_lib_name, vci_code.packages[0].identifier),
215+
"%s.%s.all" % (vci_lib_name, vci_code.packages[0].identifier),
214216
]
215217
)
216218
context_items = create_context_items(
@@ -385,6 +387,7 @@ def update_generics(code):
385387
else:
386388
template_code, _ = self.create_vhdl_testbench_template(
387389
self.vc_facade.library,
390+
self.vci.vci_facade.library,
388391
self.vc_facade.source_file.name,
389392
self.vci.vci_facade.source_file.name,
390393
)

0 commit comments

Comments
 (0)