Skip to content
Open
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
137 changes: 67 additions & 70 deletions vunit/vc/verification_component_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import re
import logging
from pathlib import Path
from itertools import chain
from vunit.vc.vci_template import TB_TEMPLATE_TEMPLATE, TB_EPILOGUE_TEMPLATE
from vunit.vhdl_parser import (
VHDLDesignFile,
Expand All @@ -35,18 +36,11 @@ def create_context_items(code, lib_name, initial_library_names, initial_context_
if ref.is_package_reference():
initial_package_refs.add(f"{library_name!s}.{ref.design_unit_name!s}.{ref.name_within!s}")

context_items = ""
for library in sorted(initial_library_names):
if library not in ["std", "work"]:
context_items += f"library {library!s};\n"

for context_ref in sorted(initial_context_refs):
context_items += f"context {context_ref!s};\n"

for package_ref in sorted(initial_package_refs):
context_items += f"use {package_ref!s};\n"

return context_items
return "".join(
[f"library {library!s};\n" for library in sorted(initial_library_names) if library not in ["std", "work"]]
+ [f"context {context_ref!s};\n" for context_ref in sorted(initial_context_refs)]
+ [f"use {package_ref!s};\n" for package_ref in sorted(initial_package_refs)]
)


class VerificationComponentInterface:
Expand Down Expand Up @@ -106,21 +100,14 @@ def _validate_as_sync(code, vc_handle_t):
"""Validates the existence and format of the as_sync function."""

for func in VHDLFunctionSpecification.find(code):
if not func.identifier.startswith("as_sync"):
continue

if func.return_type_mark != "sync_handle_t":
continue

if len(func.parameter_list) != 1:
continue

if len(func.parameter_list[0].identifier_list) != 1:
if (
(not func.identifier.startswith("as_sync"))
or (func.return_type_mark != "sync_handle_t")
or (len(func.parameter_list) != 1)
or (len(func.parameter_list[0].identifier_list) != 1)
or (func.parameter_list[0].subtype_indication.type_mark != vc_handle_t)
):
continue

if func.parameter_list[0].subtype_indication.type_mark != vc_handle_t:
continue

return func

return None
Expand All @@ -129,28 +116,6 @@ def _validate_as_sync(code, vc_handle_t):
def _validate_constructor(code, vc_handle_t):
"""Validates the existence and format of the verification component constructor."""

def create_messages(required_parameter_types, expected_default_value):
messages = [
"Failed to find a constructor function%s for %s starting with new_",
"Found constructor function %s but not with the correct return type %s",
]

for parameter_name, parameter_type in required_parameter_types.items():
messages += [
f"Found constructor function %s for %s but the {parameter_name!s} parameter is missing",
(
f"Found constructor function %s for %s but the {parameter_name} "
f"parameter is not of type {parameter_type}"
),
f"Found constructor function %s for %s but {parameter_name} is lacking a default value",
(
f"Found constructor function %s for %s but {expected_default_value[parameter_name]} "
f"is the only allowed default value for the {parameter_name} parameter"
),
]

return messages

def log_error_message(function_score, messages):
high_score = 0
best_function = ""
Expand All @@ -176,7 +141,31 @@ def log_error_message(function_score, messages):
unexpected_msg_type_policy=None,
)

messages = create_messages(required_parameter_types, expected_default_value)
messages = list(
chain.from_iterable(
[
[
"Failed to find a constructor function%s for %s starting with new_",
"Found constructor function %s but not with the correct return type %s",
]
]
+ [
[
f"Found constructor function %s for %s but the {parameter_name!s} parameter is missing",
(
f"Found constructor function %s for %s but the {parameter_name} "
f"parameter is not of type {parameter_type}"
),
f"Found constructor function %s for %s but {parameter_name} is lacking a default value",
(
f"Found constructor function %s for %s but {expected_default_value[parameter_name]} "
f"is the only allowed default value for the {parameter_name} parameter"
),
]
for parameter_name, parameter_type in required_parameter_types.items()
]
)
)

function_score = {}
for func in VHDLFunctionSpecification.find(code):
Expand Down Expand Up @@ -340,28 +329,36 @@ def create_handle_assignment(
):
mark = self.vc_constructor.return_type_mark
handle_assignment = f" constant {handle_name!s} : {mark!s} := {self.vc_constructor.identifier!s}(\n"

for parameter in unspecified_parameters:
for identifier in parameter.identifier_list:
if identifier in [
"actor",
"logger",
"checker",
"unexpected_msg_type_policy",
]:
continue
handle_assignment += f" {identifier!s} => {identifier!s},\n"
for formal, actual in dict(
actor=actor,
logger=logger,
checker=checker,
unexpected_msg_type_policy=unexpected_msg_type_policy,
).items():
if actual:
handle_assignment += f" {formal!s} => {actual!s},\n"

handle_assignment = handle_assignment[:-2] + "\n );"

return handle_assignment
handle_assignment += "".join(
[
f" {identifier!s} => {identifier!s},\n"
for identifier in parameter.identifier_list
if identifier
not in [
"actor",
"logger",
"checker",
"unexpected_msg_type_policy",
]
]
)

handle_assignment += "".join(
[
f" {formal!s} => {actual!s},\n"
for formal, actual in dict(
actor=actor,
logger=logger,
checker=checker,
unexpected_msg_type_policy=unexpected_msg_type_policy,
).items()
if actual
]
)

return handle_assignment[:-2] + "\n );"

testbench_code = template_code[: match.start()] + TB_EPILOGUE_TEMPLATE.substitute(
vc_handle_t=self.vc_constructor.return_type_mark,
Expand Down