Skip to content

Commit

Permalink
Added support for detecting and failing on ambiguous direct entity in…
Browse files Browse the repository at this point in the history
…stantiations.

This happens when an entity has several architectures but the architecture
is not specified in the instantiation. VHDL allows this and selects the
last successfully compiled architecture. This can never be what the
designer intended since she cannot fully control compile order.
  • Loading branch information
LarsAsplund committed Dec 3, 2021
1 parent 79e0616 commit f344c8b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
50 changes: 50 additions & 0 deletions tests/unit/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,56 @@ def test_specific_architecture_reference_dependencies(self):
self.assert_compiles(ent_a1, before=top1)
self.assert_compiles(ent_a2, before=top2)

def test_error_on_ambiguous_architecture(self):
self.project.add_library("lib", "lib_path")

self.add_source_file(
"lib",
"ent.vhd",
"""
entity ent is
end entity;
""",
)

self.add_source_file(
"lib",
"ent_a1.vhd",
"""
architecture a1 of ent is
begin
end architecture;
""",
)

self.add_source_file(
"lib",
"ent_a2.vhd",
"""
architecture a2 of ent is
begin
end architecture;
""",
)

self.add_source_file(
"lib",
"top.vhd",
"""
entity top is
end entity;
architecture a of top is
begin
inst : entity work.ent;
end architecture;
""",
)
self.assertRaises(
RuntimeError,
self.project.create_dependency_graph,
)

def test_work_library_reference_non_lower_case(self):
"""
Bug discovered in #556
Expand Down
20 changes: 20 additions & 0 deletions vunit/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ def _find_vhdl_library_reference(self, library_name):
real_library_name = self._lower_library_names_dict[library_name.lower()]
return self._libraries[real_library_name]

@staticmethod
def _handle_ambiguous_architecture(source_file, ref, primary_unit):
"""
Pretty print architecture ambiguity
"""
LOGGER.error(
"Ambiguous direct entity instantiation of %s.%s in %s.\n "
"Remove all but one architecture or specify one of:\n %s",
ref.library,
ref.design_unit,
source_file.name,
"\n ".join(
f"{idx}. {name} ({location})"
for idx, (name, location) in enumerate(primary_unit.architecture_names.items(), 1)
),
)

def _find_other_vhdl_design_unit_dependencies( # pylint: disable=too-many-branches
self, source_file, depend_on_package_body, implementation_dependencies
):
Expand Down Expand Up @@ -246,6 +263,9 @@ def _find_other_vhdl_design_unit_dependencies( # pylint: disable=too-many-branc
for name in names:
if name is None:
# Was not a reference to a specific architecture
if len(primary_unit.architecture_names) > 1:
self._handle_ambiguous_architecture(source_file, ref, primary_unit)
raise RuntimeError(f"Ambiguous use of {ref.library}.{ref.design_unit}")
continue

if name in primary_unit.architecture_names:
Expand Down

0 comments on commit f344c8b

Please sign in to comment.