Coverage for pyVHDLModel/DesignUnit.py: 94%
469 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-25 10:05 +0000
1# ==================================================================================================================== #
2# __ ___ _ ____ _ __ __ _ _ #
3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2026 Patrick Lehmann - Boetzingen, Germany #
15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany #
16# #
17# Licensed under the Apache License, Version 2.0 (the "License"); #
18# you may not use this file except in compliance with the License. #
19# You may obtain a copy of the License at #
20# #
21# http://www.apache.org/licenses/LICENSE-2.0 #
22# #
23# Unless required by applicable law or agreed to in writing, software #
24# distributed under the License is distributed on an "AS IS" BASIS, #
25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
26# See the License for the specific language governing permissions and #
27# limitations under the License. #
28# #
29# SPDX-License-Identifier: Apache-2.0 #
30# ==================================================================================================================== #
31#
32"""
33This module contains parts of an abstract document language model for VHDL.
35Design units are contexts, entities, architectures, packages and their bodies as well as configurations.
36"""
37from __future__ import annotations
39from typing import TYPE_CHECKING, ClassVar, Union, Iterable, Optional as Nullable
41from pyTooling.Common import getFullyQualifiedName, getTypeName
42from pyTooling.Decorators import export, readonly
43from pyTooling.MetaClasses import ExtendedType, abstractmethod, abstractclass
44from pyTooling.Graph import Vertex
46from pyVHDLModel.Common import AllowBlackboxMixin
47from pyVHDLModel.Exception import VHDLModelException, AlreadyInDesignError, NotAChildError
48from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, MultipleNamedEntityMixin, DocumentedEntityMixin, \
49 normalizedIdentifiersOf
50from pyVHDLModel.Namespace import Namespace
51from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin, WithGenericsMixin, WithPortsMixin, \
52 WithoutStatementsMixin
53from pyVHDLModel.Symbol import Symbol, PackageSymbol, EntitySymbol, LibraryReferenceSymbol
54from pyVHDLModel.Interface import GenericInterfaceItemMixin, PortInterfaceItemMixin
55from pyVHDLModel.Object import DeferredConstant
56from pyVHDLModel.Concurrent import ConcurrentStatement, ConcurrentStatementsMixin
57from pyVHDLModel.Configuration import BlockConfiguration
59if TYPE_CHECKING: 59 ↛ 60line 59 didn't jump to line 60 because the condition on line 59 was never true
60 from pyVHDLModel.Visitor import Visitor
63@export
64@abstractclass
65class Reference(ModelEntity):
66 """
67 A base-class for all references.
69 .. seealso::
71 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>`
72 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>`
73 * :class:`Context reference <pyVHDLModel.DesignUnit.ContextReference>`
74 """
76 _symbols: list[Symbol] #: List of all symbols referenced by this clause.
78 def __init__(self, symbols: Iterable[Symbol], parent: Nullable[ModelEntity] = None) -> None:
79 """
80 Initializes a reference by taking a list of symbols and a parent reference.
82 :param symbols: A list of symbols this reference references to.
83 :param parent: Reference to the logical parent in the model hierarchy.
84 """
85 super().__init__(parent)
87 self._symbols = list(symbols)
89 @readonly
90 def Symbols(self) -> list[Symbol]:
91 """
92 Read-only property to access the symbols this reference references to (:attr:`_symbols`).
94 :returns: A list of symbols.
95 """
96 return self._symbols
98 def _VisitSymbols(self, visitor: Visitor) -> None:
99 """
100 Walk the referenced symbols, separated by commas, with a visitor.
102 :param visitor: The visitor receiving the events.
103 """
104 for index, symbol in enumerate(self._symbols):
105 if index > 0:
106 visitor.VisitComma(self)
108 symbol.Visit(visitor)
111@export
112class LibraryClause(Reference):
113 """
114 Represents a library clause.
116 .. admonition:: Example
118 .. code-block:: VHDL
120 library std, ieee;
121 """
123 @readonly
124 def Symbols(self) -> list[LibraryReferenceSymbol]:
125 """
126 Read-only property to access the symbols this library clause references to (:attr:`_symbols`).
128 :returns: A list of library reference symbols.
129 """
130 return self._symbols
132 def Visit(self, visitor: Visitor) -> None:
133 """
134 Walk this library clause and its library names with a visitor.
136 :param visitor: The visitor receiving the events.
137 """
138 visitor.VisitLibraryClause(self)
139 self._VisitSymbols(visitor)
140 visitor.DepartLibraryClause(self)
143@export
144class UseClause(Reference):
145 """
146 Represents a use clause.
148 .. admonition:: Example
150 .. code-block:: VHDL
152 use std.text_io.all, ieee.numeric_std.all;
153 """
155 def Visit(self, visitor: Visitor) -> None:
156 """
157 Walk this use clause and its selected names with a visitor.
159 :param visitor: The visitor receiving the events.
160 """
161 visitor.VisitUseClause(self)
162 self._VisitSymbols(visitor)
163 visitor.DepartUseClause(self)
166@export
167class ContextReference(Reference):
168 """
169 Represents a context reference.
171 .. hint:: It's called *context reference* not *context clause* by the LRM.
173 .. admonition:: Example
175 .. code-block:: VHDL
177 context ieee.ieee_std_context;
178 """
180 def Visit(self, visitor: Visitor) -> None:
181 """
182 Walk this context reference and its context names with a visitor.
184 :param visitor: The visitor receiving the events.
185 """
186 visitor.VisitContextReference(self)
187 self._VisitSymbols(visitor)
188 visitor.DepartContextReference(self)
191ContextUnion = Union[
192 LibraryClause,
193 UseClause,
194 ContextReference
195]
198@export
199class DesignUnitWithContextMixin(metaclass=ExtendedType, mixin=True):
200 """
201 A mixin-class for all design units with a context.
203 .. seealso::
205 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
206 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
207 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
208 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
209 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
210 """
213@export
214@abstractclass
215class DesignUnit(ModelEntity, NamedEntityMixin, DocumentedEntityMixin):
216 """
217 A base-class for all design units.
219 When a design unit is formatted, an unknown part - a library that is not set, or an entity with no
220 known architecture - is rendered as ``?``.
222 .. seealso::
224 * :class:`Primary design units <pyVHDLModel.DesignUnit.PrimaryUnit>`
226 * :class:`Context <pyVHDLModel.DesignUnit.Context>`
227 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
228 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
229 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
231 * :class:`Secondary design units <pyVHDLModel.DesignUnit.SecondaryUnit>`
233 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
234 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
235 """
237 _CONTINUES_PARENT_REGION: ClassVar[bool] = False #: ``True`` if it continues its parent's declarative region.
239 _document: Document #: The VHDL library, the design unit was analyzed into.
241 # Either written as statements before (e.g. entity, architecture, package, ...), or as statements inside (context)
242 _contextItems: list[ContextUnion] #: List of all context items (library, use and context clauses).
243 _libraryReferences: list[LibraryClause] #: List of library clauses.
244 _packageReferences: list[UseClause] #: List of use clauses.
245 _contextReferences: list[ContextReference] #: List of context clauses.
247 _referencedLibraries: dict[str, Library] #: Referenced libraries based on explicit library clauses or implicit inheritance
248 _referencedPackages: dict[str, dict[str, Package]] #: Referenced packages based on explicit use clauses or implicit inheritance
249 _referencedContexts: dict[str, Context] #: Referenced contexts based on explicit context references or implicit inheritance
251 _dependencyVertex: Vertex #: Reference to the vertex in the dependency graph representing the design unit. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateDependencyGraph`.
252 _hierarchyVertex: Vertex #: The vertex in the hierarchy graph
254 def __init__(self, identifier: str, contextItems: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
255 """
256 Initializes a design unit.
258 :param identifier: Identifier (name) of the design unit.
259 :param contextItems: A sequence of library, use or context clauses.
260 :param documentation: Associated documentation of the design unit.
261 :param parent: Reference to the logical parent in the model hierarchy.
262 """
263 super().__init__(parent)
264 NamedEntityMixin.__init__(self, identifier)
265 DocumentedEntityMixin.__init__(self, documentation)
267 self._document = None
269 self._contextItems = contextItemList = []
270 self._libraryReferences = libraryReferences = []
271 self._packageReferences = packageReferences = []
272 self._contextReferences = contextReferences = []
274 if contextItems is not None:
275 for item in contextItems:
276 contextItemList.append(item)
277 item.Parent = self
278 if isinstance(item, UseClause):
279 packageReferences.append(item)
280 elif isinstance(item, LibraryClause):
281 libraryReferences.append(item)
282 elif isinstance(item, ContextReference): 282 ↛ 275line 282 didn't jump to line 275 because the condition on line 282 was always true
283 contextReferences.append(item)
285 self._referencedLibraries = {}
286 self._referencedPackages = {}
287 self._referencedContexts = {}
289 self._dependencyVertex = None
290 self._hierarchyVertex = None
292 @property
293 def Document(self) -> Document:
294 """
295 Property to access the document (:attr:`_document`).
297 :returns: The document.
298 """
299 return self._document
301 @Document.setter
302 def Document(self, document: Document) -> None:
303 self._document = document
305 @property
306 def Library(self) -> Library:
307 """
308 Property to access the library (:attr:`_parent`).
310 :returns: The library.
311 """
312 return self._parent
314 @Library.setter
315 def Library(self, library: Library) -> None:
316 self._parent = library
318 @readonly
319 def ContextItems(self) -> list[ContextUnion]:
320 """
321 Read-only property to access the sequence of all context items comprising library, use and context clauses
322 (:attr:`_contextItems`).
324 :returns: Sequence of context items.
325 """
326 return self._contextItems
328 @readonly
329 def ContextReferences(self) -> list[ContextReference]:
330 """
331 Read-only property to access the sequence of context clauses (:attr:`_contextReferences`).
333 :returns: Sequence of context clauses.
334 """
335 return self._contextReferences
337 @readonly
338 def LibraryReferences(self) -> list[LibraryClause]:
339 """
340 Read-only property to access the sequence of library clauses (:attr:`_libraryReferences`).
342 :returns: Sequence of library clauses.
343 """
344 return self._libraryReferences
346 def _VisitContextClause(self, visitor: Visitor) -> None:
347 """
348 Walk the context clause, i.e. the context items preceding the design unit, with a visitor.
350 The context clause is reported, even if it has no context items.
352 :param visitor: The visitor receiving the events.
353 """
354 visitor.VisitContextClause(self)
355 for item in self._contextItems:
356 item.Visit(visitor)
358 visitor.DepartContextClause(self)
360 @readonly
361 def PackageReferences(self) -> list[UseClause]:
362 """
363 Read-only property to access the sequence of use clauses (:attr:`_packageReferences`).
365 :returns: Sequence of use clauses.
366 """
367 return self._packageReferences
369 def AddContextItem(self, contextItem: ContextUnion) -> None:
370 """
371 Add a context item at the end of the context clause.
373 The context item's parent is set to this design unit. A library clause is also added to :data:`LibraryReferences`, a
374 use clause to :data:`PackageReferences` and a context reference to :data:`ContextReferences`, in the order of
375 :data:`ContextItems`. A context item may repeat an earlier one.
377 :param contextItem: The library clause, use clause or context reference to add.
378 :raises ValueError: If parameter 'contextItem' is ``None``.
379 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause`
380 or :class:`ContextReference`.
381 :raises AlreadyInDesignError: If parameter 'contextItem' already has a parent.
383 .. attention::
385 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the
386 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`,
387 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the
388 references of the symbols. A design changed after its analysis needs a new analysis.
390 .. seealso::
392 :meth:`InsertContextItem`
393 |rarr| Insert a context item at a position of the context clause.
394 :meth:`RemoveContextItem`
395 |rarr| Remove a context item from the context clause.
396 """
397 self.InsertContextItem(len(self._contextItems), contextItem)
399 def InsertContextItem(self, index: int, contextItem: ContextUnion) -> None:
400 """
401 Insert a context item at a position of the context clause.
403 The context item's parent is set to this design unit. A library clause is also added to :data:`LibraryReferences`, a
404 use clause to :data:`PackageReferences` and a context reference to :data:`ContextReferences`, in the order of
405 :data:`ContextItems`. A context item may repeat an earlier one.
407 :param index: Position, from ``0`` (first) to the number of context items (append). A negative index
408 counts from the end, as for :meth:`list.insert`: ``-1`` inserts before the last
409 context item.
410 :param contextItem: The library clause, use clause or context reference to insert.
411 :raises ValueError: If parameter 'index' is ``None``.
412 :raises TypeError: If parameter 'index' is not of type :class:`int`.
413 :raises ValueError: If parameter 'index' is out of range.
414 :raises ValueError: If parameter 'contextItem' is ``None``.
415 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause`
416 or :class:`ContextReference`.
417 :raises AlreadyInDesignError: If parameter 'contextItem' already has a parent.
419 .. attention::
421 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the
422 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`,
423 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the
424 references of the symbols. A design changed after its analysis needs a new analysis.
426 .. seealso::
428 :meth:`AddContextItem`
429 |rarr| Add a context item at the end of the context clause.
430 :meth:`RemoveContextItem`
431 |rarr| Remove a context item from the context clause.
432 """
433 count = len(self._contextItems)
434 if index is None:
435 raise ValueError("Parameter 'index' is None.")
436 elif not isinstance(index, int):
437 ex = TypeError("Parameter 'index' is not of type 'int'.")
438 ex.add_note(f"Got type '{getFullyQualifiedName(index)}'.")
439 raise ex
440 elif not (-count <= index <= count):
441 ex = ValueError(f"Parameter 'index' is out of range {-count}..{count}.")
442 ex.add_note(f"Got value '{index}'.")
443 raise ex
445 if contextItem is None:
446 raise ValueError("Parameter 'contextItem' is None.")
447 elif not isinstance(contextItem, (LibraryClause, UseClause, ContextReference)):
448 ex = TypeError("Parameter 'contextItem' is not of type 'LibraryClause', 'UseClause' or 'ContextReference'.")
449 ex.add_note(f"Got type '{getFullyQualifiedName(contextItem)}'.")
450 raise ex
451 elif contextItem._parent is not None:
452 ex = AlreadyInDesignError(
453 f"{getTypeName(contextItem)} already has a parent.",
454 element=contextItem,
455 parent=contextItem._parent
456 )
457 ex.add_note(f"Remove it from its {getTypeName(contextItem._parent)} first.")
458 raise ex
460 if isinstance(contextItem, LibraryClause):
461 references = self._libraryReferences
462 referenceType = LibraryClause
463 elif isinstance(contextItem, UseClause):
464 references = self._packageReferences
465 referenceType = UseClause
466 else:
467 references = self._contextReferences
468 referenceType = ContextReference
470 position = index if index >= 0 else count + index
471 referenceIndex = sum(1 for item in self._contextItems[:position] if isinstance(item, referenceType))
473 self._contextItems.insert(position, contextItem)
474 references.insert(referenceIndex, contextItem)
475 contextItem.Parent = self
477 def RemoveContextItem(self, contextItem: ContextUnion) -> None:
478 """
479 Remove a context item from the context clause.
481 The context item is detached: its parent is cleared, and it's removed from :data:`ContextItems` and from
482 :data:`LibraryReferences`, :data:`PackageReferences` or :data:`ContextReferences`. The context item itself is
483 unchanged and can be added to another design unit, or inserted at another position.
485 :param contextItem: The library clause, use clause or context reference to remove.
486 :raises ValueError: If parameter 'contextItem' is ``None``.
487 :raises TypeError: If parameter 'contextItem' is not of type :class:`LibraryClause`, :class:`UseClause` or
488 :class:`ContextReference`.
489 :raises NotAChildError: If parameter 'contextItem' is not a context item of this design unit.
491 .. attention::
493 The mutator doesn't update what :meth:`~pyVHDLModel.Design.Analyze` derived from the context items: the
494 referenced libraries, packages and contexts (:data:`ReferencedLibraries`, :data:`ReferencedPackages`,
495 :data:`ReferencedContexts`), the namespace entries of a use clause, the edges of the dependency graph, and the
496 references of the symbols. A design changed after its analysis needs a new analysis.
498 .. seealso::
500 :meth:`AddContextItem`
501 |rarr| Add a context item at the end of the context clause.
502 :meth:`InsertContextItem`
503 |rarr| Insert a context item at a position of the context clause.
504 """
505 if contextItem is None:
506 raise ValueError("Parameter 'contextItem' is None.")
507 elif not isinstance(contextItem, (LibraryClause, UseClause, ContextReference)):
508 ex = TypeError("Parameter 'contextItem' is not of type 'LibraryClause', 'UseClause' or 'ContextReference'.")
509 ex.add_note(f"Got type '{getFullyQualifiedName(contextItem)}'.")
510 raise ex
512 for index, item in enumerate(self._contextItems):
513 if item is contextItem:
514 break
515 else:
516 raise NotAChildError(
517 f"{getTypeName(contextItem)} is not a context item of this {getTypeName(self)}.",
518 element=contextItem,
519 parent=self
520 )
522 if isinstance(contextItem, LibraryClause):
523 references = self._libraryReferences
524 elif isinstance(contextItem, UseClause): 524 ↛ 527line 524 didn't jump to line 527 because the condition on line 524 was always true
525 references = self._packageReferences
526 else:
527 references = self._contextReferences
529 del self._contextItems[index]
530 references.remove(contextItem)
531 contextItem._parent = None
533 @readonly
534 def ReferencedLibraries(self) -> dict[str, Library]:
535 """
536 Read-only property to access the referenced libraries (:attr:`_referencedLibraries`).
538 :returns: Dictionary of referenced libraries, indexed by normalized identifier.
539 """
540 return self._referencedLibraries
542 @readonly
543 def ReferencedPackages(self) -> dict[str, Package]:
544 """
545 Read-only property to access the referenced packages (:attr:`_referencedPackages`).
547 :returns: Dictionary of referenced packages, indexed by normalized identifier.
548 """
549 return self._referencedPackages
551 @readonly
552 def ReferencedContexts(self) -> dict[str, Context]:
553 """
554 Read-only property to access the referenced contexts (:attr:`_referencedContexts`).
556 :returns: Dictionary of referenced contexts, indexed by normalized identifier.
557 """
558 return self._referencedContexts
560 @readonly
561 def DependencyVertex(self) -> Vertex:
562 """
563 Read-only property to access the corresponding dependency vertex (:attr:`_dependencyVertex`).
565 The dependency vertex references this design unit by its value field.
567 :returns: The corresponding dependency vertex.
568 """
569 return self._dependencyVertex
571 @readonly
572 def HierarchyVertex(self) -> Vertex:
573 """
574 Read-only property to access the corresponding hierarchy vertex (:attr:`_hierarchyVertex`).
576 The hierarchy vertex references this design unit by its value field.
578 :returns: The corresponding hierarchy vertex.
579 """
580 return self._hierarchyVertex
582 @abstractmethod
583 def __str__(self) -> str:
584 """
585 Formats the design unit.
587 Every concrete design unit renders itself, so this base-class provides no implementation.
589 :returns: Formatted design unit.
590 """
593@export
594@abstractclass
595class PrimaryUnit(DesignUnit):
596 """
597 A base-class for all primary design units.
599 .. seealso::
601 * :class:`Context <pyVHDLModel.DesignUnit.Context>`
602 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
603 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
604 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
605 * :class:`PSL primary unit <pyVHDLModel.PSLModel.PSLPrimaryUnit>` (PSL is not supported)
606 """
609@export
610@abstractclass
611class SecondaryUnit(DesignUnit):
612 """
613 A base-class for all secondary design units.
615 .. seealso::
617 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
618 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
619 """
622@export
623class Context(PrimaryUnit):
624 """
625 Represents a context declaration.
627 A context contains a generic list of all its items (library clauses, use clauses and context references) in
628 :data:`_contextItems`.
630 Furthermore, when a context gets initialized, the item kinds get separated into individual lists:
632 * :class:`~pyVHDLModel.DesignUnit.LibraryClause` |rarr| :data:`_libraryReferences`
633 * :class:`~pyVHDLModel.DesignUnit.UseClause` |rarr| :data:`_packageReferences`
634 * :class:`~pyVHDLModel.DesignUnit.ContextReference` |rarr| :data:`_contextReferences`
636 When :meth:`pyVHDLModel.Design.LinkContexts` got called, these lists were processed and the fields:
638 * :data:`_referencedLibraries` (:pycode:`dict[libName, Library]`)
639 * :data:`_referencedPackages` (:pycode:`dict[libName, [pkgName, Package]]`)
640 * :data:`_referencedContexts` (:pycode:`dict[libName, [ctxName, Context]]`)
642 are populated.
644 .. admonition:: Example
646 .. code-block:: VHDL
648 context ctx is
649 -- ...
650 end context;
652 .. seealso::
654 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>`
655 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>`
656 """
658 def __init__(self, identifier: str, references: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
659 """
660 Initializes a context declaration.
662 :param identifier: The identifier of a model entity.
663 :param references: All context items, in declaration order.
664 :param documentation: The documentation comment associated with this declaration.
665 :param parent: The parent model entity of this entity.
666 :raises VHDLModelException: If a context item is neither a library clause, use clause, nor context reference.
667 """
668 super().__init__(identifier, None, documentation, parent)
670 if references is not None:
671 for reference in references:
672 self._contextItems.append(reference)
673 reference.Parent = self
675 if isinstance(reference, LibraryClause):
676 self._libraryReferences.append(reference)
677 elif isinstance(reference, UseClause):
678 self._packageReferences.append(reference)
679 elif isinstance(reference, ContextReference):
680 self._contextReferences.append(reference)
681 else:
682 raise VHDLModelException(f"Reference '{reference!r}' is neither a library clause, use clause, nor context reference.")
684 @readonly
685 def LibraryReferences(self) -> list[LibraryClause]:
686 """
687 Read-only property to access the library references (:attr:`_libraryReferences`).
689 :returns: List of library references.
690 """
691 return self._libraryReferences
693 @readonly
694 def PackageReferences(self) -> list[UseClause]:
695 """
696 Read-only property to access the package references (:attr:`_packageReferences`).
698 :returns: List of package references.
699 """
700 return self._packageReferences
702 @readonly
703 def ContextReferences(self) -> list[ContextReference]:
704 """
705 Read-only property to access the context references (:attr:`_contextReferences`).
707 :returns: List of context references.
708 """
709 return self._contextReferences
711 def Visit(self, visitor: Visitor) -> None:
712 """
713 Walk this context declaration and its context items with a visitor.
715 A context declaration has no context clause: its context items are walked inside the declaration.
717 :param visitor: The visitor receiving the events.
718 """
719 visitor.VisitContext(self)
720 for item in self._contextItems:
721 item.Visit(visitor)
723 visitor.DepartContext(self)
725 def __str__(self) -> str:
726 """
727 Formats the context declaration.
729 **Format:** ``Context: mylib.myContext``
731 :returns: Formatted context declaration.
732 """
733 lib = self._parent._identifier if self._parent is not None else "?"
735 return f"Context: {lib}.{self._identifier}"
738@export
739class Package(
740 PrimaryUnit,
741 DesignUnitWithContextMixin,
742 WithGenericsMixin,
743 ConcurrentDeclarationRegionMixin,
744 WithoutStatementsMixin,
745 AllowBlackboxMixin
746):
747 """
748 Represents a package declaration.
750 .. admonition:: Example
752 .. code-block:: VHDL
754 package pkg is
755 -- ...
756 end package;
758 .. seealso::
760 * :class:`Package instantiation <pyVHDLModel.Instantiation.PackageInstantiation>`
761 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>`
762 * :class:`Package body implementing it <pyVHDLModel.DesignUnit.PackageBody>`
763 """
765 _packageBody: Nullable[PackageBody] #: The corresponding package body, or ``None`` if none was analyzed.
767 _deferredConstants: dict[str, DeferredConstant] #: Deferred constants, indexed by name.
769 def __init__(
770 self,
771 identifier: str,
772 contextItems: Nullable[Iterable[ContextUnion]] = None,
773 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
774 declaredItems: Nullable[Iterable] = None,
775 documentation: Nullable[str] = None,
776 allowBlackbox: Nullable[bool] = None,
777 parent: Nullable[ModelEntity] = None
778 ) -> None:
779 """
780 Initialize a package.
782 :param identifier: Name of the VHDL package.
783 :param contextItems:
784 :param genericItems:
785 :param declaredItems:
786 :param documentation:
787 :param allowBlackbox: Specify if blackboxes are allowed in this design.
788 :param parent: The parent model entity (library) of this VHDL package.
789 """
790 super().__init__(identifier, contextItems, documentation, parent)
791 DesignUnitWithContextMixin.__init__(self)
792 ConcurrentDeclarationRegionMixin.__init__(
793 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION
794 )
795 WithGenericsMixin.__init__(self, genericItems)
796 AllowBlackboxMixin.__init__(self, allowBlackbox)
798 self._packageBody = None
800 self._deferredConstants = {}
801 self._components = {}
803 @readonly
804 def PackageBody(self) -> Nullable[PackageBody]:
805 """
806 Read-only property to access the package body (:attr:`_packageBody`).
808 :returns: The package body, or ``None`` if not set.
809 """
810 return self._packageBody
812 @readonly
813 def DeclaredItems(self) -> list:
814 """
815 Read-only property to access the declared items (:attr:`_declaredItems`).
817 :returns: List of declared items.
818 """
819 return self._declaredItems
821 @readonly
822 def DeferredConstants(self) -> dict[str, DeferredConstant]:
823 """
824 Read-only property to access the deferred constants (:attr:`_deferredConstants`).
826 :returns: Dictionary of deferred constants, indexed by normalized identifier.
827 """
828 return self._deferredConstants
830 @readonly
831 def Components(self) -> dict[str, Component]:
832 """
833 Read-only property to access the components (:attr:`_components`).
835 :returns: Dictionary of components, indexed by normalized identifier.
836 """
837 return self._components
839 def _IndexOtherDeclaredItem(self, item) -> None:
840 if isinstance(item, DeferredConstant): 840 ↛ 843line 840 didn't jump to line 843 because the condition on line 840 was always true
841 for normalizedIdentifier in item.NormalizedIdentifiers:
842 self._deferredConstants[normalizedIdentifier] = item
843 elif isinstance(item, Component):
844 self._components[item._normalizedIdentifier] = item
845 else:
846 super()._IndexOtherDeclaredItem(item)
848 def _UnindexOtherDeclaredItem(self, item: ModelEntity) -> None:
849 """
850 Remove a declared item, which a concurrent declaration region doesn't handle itself.
852 A deferred constant is removed from :attr:`_deferredConstants`. An entry referring to another deferred constant of
853 the same identifier (a duplicate declaration) is kept: :meth:`RemoveDeclaredItem` indexes the region again.
855 :param item: The declared item.
856 """
857 if isinstance(item, DeferredConstant): 857 ↛ 862line 857 didn't jump to line 862 because the condition on line 857 was always true
858 for normalizedIdentifier in item._normalizedIdentifiers:
859 if self._deferredConstants.get(normalizedIdentifier) is item: 859 ↛ 858line 859 didn't jump to line 858 because the condition on line 859 was always true
860 del self._deferredConstants[normalizedIdentifier]
861 else:
862 super()._UnindexOtherDeclaredItem(item)
864 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]:
865 """
866 Return the other language constructs forming one declarative region with this package.
868 :returns: Tuple of the package body, if linked (:attr:`_packageBody`).
869 """
870 return () if self._packageBody is None else (self._packageBody, )
872 def Visit(self, visitor: Visitor) -> None:
873 """
874 Walk this package declaration, its context clause, its generic clause and its declared items with a visitor.
876 :param visitor: The visitor receiving the events.
877 """
878 self._VisitContextClause(visitor)
879 visitor.VisitPackage(self)
880 self._VisitGenericClause(visitor)
881 self._VisitDeclaredItems(visitor)
882 visitor.DepartPackage(self)
884 def __str__(self) -> str:
885 """
886 Formats the package declaration.
888 **Format:** ``Package: 'mylib.myPackage'``
890 :returns: Formatted package declaration.
891 """
892 lib = self._parent._identifier if self._parent is not None else "?"
894 return f"Package: '{lib}.{self._identifier}'"
896 def __repr__(self) -> str:
897 """
898 Formats a representation of the package declaration.
900 **Format:** ``mylib.myPackage``
902 :returns: String representation of the package declaration.
903 """
904 lib = self._parent._identifier if self._parent is not None else "?"
906 return f"{lib}.{self._identifier}"
909 def IndexDeclaredItems(self) -> None:
910 """
911 A generic package's generics share the declarative region of its declarative part.
913 :raises UnhandledCriticalWarningError: If an identifier is declared twice in a declarative region and no
914 :class:`~pyTooling.Warning.WarningCollector` collects the
915 :exc:`~pyVHDLModel.Exception.DuplicateDeclarationWarning`.
916 """
917 self._deferredConstants.clear()
918 self._IndexGenericItems()
920 super().IndexDeclaredItems()
922 def _Declarations(self) -> tuple[ModelEntity, ...]:
923 """
924 Return all declarations of this package: its generics share the declarative region.
926 :returns: Tuple of declarations: the generics, then the declared items.
927 """
928 return (*self._genericItems, *super()._Declarations())
931@export
932class PackageBody(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin, WithoutStatementsMixin):
933 """
934 Represents a package body declaration.
936 .. admonition:: Example
938 .. code-block:: VHDL
940 package body pkg is
941 -- ...
942 end package body;
944 .. seealso::
946 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>`
947 * :class:`Package it implements <pyVHDLModel.DesignUnit.Package>`
948 """
950 _CONTINUES_PARENT_REGION: ClassVar[bool] = True #: A package body continues its package's declarative region.
952 _package: PackageSymbol #: Reference to the package this body implements.
954 def __init__(
955 self,
956 packageSymbol: PackageSymbol,
957 contextItems: Nullable[Iterable[ContextUnion]] = None,
958 declaredItems: Nullable[Iterable] = None,
959 documentation: Nullable[str] = None,
960 parent: Nullable[ModelEntity] = None
961 ) -> None:
962 """
963 Initializes a package body declaration.
965 :param packageSymbol: Reference to the package this body implements.
966 :param contextItems: List of all context items (library, use and context clauses).
967 :param declaredItems: List of all declared items in this concurrent declaration region.
968 :param documentation: The documentation comment associated with this declaration.
969 :param parent: The parent model entity of this entity.
970 """
971 super().__init__(packageSymbol.Name.Identifier, contextItems, documentation, parent)
972 DesignUnitWithContextMixin.__init__(self)
973 ConcurrentDeclarationRegionMixin.__init__(
974 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION
975 )
977 self._package = packageSymbol
978 packageSymbol.Parent = self
980 @readonly
981 def Package(self) -> PackageSymbol:
982 """
983 Read-only property to access the package (:attr:`_package`).
985 :returns: The package.
986 """
987 return self._package
989 @readonly
990 def DeclaredItems(self) -> list:
991 """
992 Read-only property to access the declared items (:attr:`_declaredItems`).
994 :returns: List of declared items.
995 """
996 return self._declaredItems
998 def LinkDeclaredItemsToPackage(self) -> None:
999 pass
1001 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]:
1002 """
1003 Return the other language constructs forming one declarative region with this package body.
1005 :returns: Tuple of the package, if linked.
1006 """
1007 package = self._package.Package
1008 return () if package is None else (package, )
1010 def Visit(self, visitor: Visitor) -> None:
1011 """
1012 Walk this package body, its context clause and its declared items with a visitor.
1014 :param visitor: The visitor receiving the events.
1015 """
1016 self._VisitContextClause(visitor)
1017 visitor.VisitPackageBody(self)
1018 self._VisitDeclaredItems(visitor)
1019 visitor.DepartPackageBody(self)
1021 def __str__(self) -> str:
1022 """
1023 Formats the package body declaration.
1025 **Format:** ``Package Body: mylib.myPackage(body)``
1027 :returns: Formatted package body declaration.
1028 """
1029 lib = self._parent._identifier if self._parent is not None else "?"
1031 return f"Package Body: {lib}.{self._identifier}(body)"
1033 def __repr__(self) -> str:
1034 """
1035 Formats a representation of the package body declaration.
1037 **Format:** ``mylib.myPackage(body)``
1039 :returns: String representation of the package body declaration.
1040 """
1041 lib = self._parent._identifier if self._parent is not None else "?"
1043 return f"{lib}.{self._identifier}(body)"
1046@export
1047class Entity(PrimaryUnit, DesignUnitWithContextMixin, WithGenericsMixin, WithPortsMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
1048 """
1049 Represents an entity declaration.
1051 .. admonition:: Example
1053 .. code-block:: VHDL
1055 entity ent is
1056 -- ...
1057 end entity;
1059 .. seealso::
1061 * :class:`Architecture implementing it <pyVHDLModel.DesignUnit.Architecture>`
1062 * :class:`Component declaring the same interface <pyVHDLModel.DesignUnit.Component>`
1063 * :class:`Configuration binding it <pyVHDLModel.DesignUnit.Configuration>`
1064 """
1066 _architectures: dict[str, Architecture] #: Dictionary of all architectures of this entity, indexed by name.
1068 def __init__(
1069 self,
1070 identifier: str,
1071 contextItems: Nullable[Iterable[ContextUnion]] = None,
1072 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
1073 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None,
1074 declaredItems: Nullable[Iterable] = None,
1075 statements: Nullable[Iterable[ConcurrentStatement]] = None,
1076 documentation: Nullable[str] = None,
1077 allowBlackbox: Nullable[bool] = None,
1078 parent: Nullable[ModelEntity] = None
1079 ) -> None:
1080 """
1081 Initializes an entity declaration.
1083 :param identifier: The identifier of a model entity.
1084 :param contextItems: List of all context items (library, use and context clauses).
1085 :param genericItems: List of all generics, in declaration order.
1086 :param portItems: List of all ports, in declaration order.
1087 :param declaredItems: List of all declared items in this concurrent declaration region.
1088 :param statements: List of all concurrent statements in this construct.
1089 :param documentation: The documentation comment associated with this declaration.
1090 :param allowBlackbox: Allow blackboxes for components in language entity.
1091 :param parent: The parent model entity of this entity.
1092 """
1093 super().__init__(identifier, contextItems, documentation, parent)
1094 DesignUnitWithContextMixin.__init__(self)
1095 ConcurrentDeclarationRegionMixin.__init__(
1096 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION
1097 )
1098 WithGenericsMixin.__init__(self, genericItems)
1099 WithPortsMixin.__init__(self, portItems)
1100 ConcurrentStatementsMixin.__init__(self, statements)
1101 AllowBlackboxMixin.__init__(self, allowBlackbox)
1103 self._architectures = {}
1105 @readonly
1106 def Architectures(self) -> dict[str, Architecture]:
1107 """
1108 Read-only property to access the architectures (:attr:`_architectures`).
1110 :returns: Dictionary of architectures, indexed by normalized identifier.
1111 """
1112 return self._architectures
1114 def Visit(self, visitor: Visitor) -> None:
1115 """
1116 Walk this entity, its context clause, its interface, its declared items and its statements with a visitor.
1118 :param visitor: The visitor receiving the events.
1119 """
1120 self._VisitContextClause(visitor)
1121 visitor.VisitEntity(self)
1122 self._VisitGenericClause(visitor)
1123 self._VisitPortClause(visitor)
1124 self._VisitDeclaredItems(visitor)
1125 visitor.VisitBegin(self)
1126 self._VisitStatements(visitor)
1127 visitor.DepartEntity(self)
1129 def __str__(self) -> str:
1130 """
1131 Formats the entity declaration.
1133 **Format:** ``Entity: 'mylib.myEntity(rtl, sim)'``
1135 The parenthesis lists the known architectures, or ``?`` if there are none.
1137 :returns: Formatted entity declaration.
1138 """
1139 lib = self._parent._identifier if self._parent is not None else "?"
1140 archs = ', '.join(self._architectures.keys()) if self._architectures else "?"
1142 return f"Entity: '{lib}.{self._identifier}({archs})'"
1144 def __repr__(self) -> str:
1145 """
1146 Formats a representation of the entity declaration.
1148 **Format:** ``mylib.myEntity(rtl, sim)``
1150 :returns: String representation of the entity declaration.
1151 """
1152 lib = self._parent._identifier if self._parent is not None else "?"
1153 archs = ', '.join(self._architectures.keys()) if self._architectures else "?"
1155 return f"{lib}.{self._identifier}({archs})"
1158 def IndexDeclaredItems(self) -> None:
1159 """
1160 An entity's generics and ports share the declarative region of its declarative part.
1162 :raises UnhandledCriticalWarningError: If an identifier is declared twice in a declarative region and no
1163 :class:`~pyTooling.Warning.WarningCollector` collects the
1164 :exc:`~pyVHDLModel.Exception.DuplicateDeclarationWarning`.
1165 """
1166 self._IndexGenericItems()
1167 self._IndexPortItems()
1169 super().IndexDeclaredItems()
1171 def _Declarations(self) -> tuple[ModelEntity, ...]:
1172 """
1173 Return all declarations of this entity: its generics and ports share the declarative region.
1175 :returns: Tuple of declarations: the generics, the ports, then the declared items.
1176 """
1177 return (*self._genericItems, *self._portItems, *super()._Declarations())
1179 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]:
1180 """
1181 Return the other language constructs forming one declarative region with this entity.
1183 :returns: Tuple of the linked architectures (:attr:`_architectures`).
1184 """
1185 return tuple(self._architectures.values())
1188@export
1189class Architecture(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
1190 """
1191 Represents an architecture declaration.
1193 .. admonition:: Example
1195 .. code-block:: VHDL
1197 architecture rtl of ent is
1198 -- ...
1199 begin
1200 -- ...
1201 end architecture;
1203 .. seealso::
1205 * :class:`Entity it implements <pyVHDLModel.DesignUnit.Entity>`
1206 """
1208 _CONTINUES_PARENT_REGION: ClassVar[bool] = True #: An architecture continues its entity's declarative region.
1210 _entity: EntitySymbol #: Reference to the entity this architecture implements.
1212 def __init__(
1213 self,
1214 identifier: str,
1215 entity: EntitySymbol,
1216 contextItems: Nullable[Iterable[Context]] = None,
1217 declaredItems: Nullable[Iterable] = None,
1218 statements: Iterable[ConcurrentStatement] = None,
1219 documentation: Nullable[str] = None,
1220 allowBlackbox: Nullable[bool] = None,
1221 parent: Nullable[ModelEntity] = None
1222 ) -> None:
1223 """
1224 Initializes an architecture declaration.
1226 :param identifier: The identifier of a model entity.
1227 :param entity: Reference to the entity this architecture implements.
1228 :param contextItems: List of all context items (library, use and context clauses).
1229 :param declaredItems: List of all declared items in this concurrent declaration region.
1230 :param statements: List of all concurrent statements in this construct.
1231 :param documentation: The documentation comment associated with this declaration.
1232 :param allowBlackbox: Allow blackboxes for components in language entity.
1233 :param parent: The parent model entity of this entity.
1234 """
1235 super().__init__(identifier, contextItems, documentation, parent)
1236 DesignUnitWithContextMixin.__init__(self)
1237 ConcurrentDeclarationRegionMixin.__init__(
1238 self, self._normalizedIdentifier, declaredItems, self._CONTINUES_PARENT_REGION
1239 )
1240 ConcurrentStatementsMixin.__init__(self, statements)
1241 AllowBlackboxMixin.__init__(self, allowBlackbox)
1243 self._entity = entity
1244 entity.Parent = self
1246 @readonly
1247 def Entity(self) -> EntitySymbol: # FIXME: change to entitySymbol, offer entity directly, but raise exception if not resolved.
1248 """
1249 Read-only property to access the entity (:attr:`_entity`).
1251 :returns: The entity.
1252 """
1253 return self._entity
1255 def Visit(self, visitor: Visitor) -> None:
1256 """
1257 Walk this architecture, its context clause, its entity, its declared items and its statements with a visitor.
1259 :param visitor: The visitor receiving the events.
1260 """
1261 self._VisitContextClause(visitor)
1262 visitor.VisitArchitecture(self)
1263 self._entity.Visit(visitor)
1264 visitor.VisitIs(self)
1265 self._VisitDeclaredItems(visitor)
1266 visitor.VisitBegin(self)
1267 self._VisitStatements(visitor)
1268 visitor.DepartArchitecture(self)
1270 def __str__(self) -> str:
1271 """
1272 Formats the architecture declaration.
1274 **Format:** ``Architecture: mylib.myEntity(rtl)``
1276 :returns: Formatted architecture declaration.
1277 """
1278 lib = self._parent._identifier if self._parent is not None else "?"
1279 ent = self._entity._name._identifier if self._entity is not None else "?"
1281 return f"Architecture: {lib}.{ent}({self._identifier})"
1283 def __repr__(self) -> str:
1284 """
1285 Formats a representation of the architecture declaration.
1287 **Format:** ``mylib.myEntity(rtl)``
1289 :returns: String representation of the architecture declaration.
1290 """
1291 lib = self._parent._identifier if self._parent is not None else "?"
1292 ent = self._entity._name._identifier if self._entity is not None else "?"
1294 return f"{lib}.{ent}({self._identifier})"
1296 def _SharedRegions(self) -> tuple[ConcurrentDeclarationRegionMixin, ...]:
1297 """
1298 Return the other language constructs forming one declarative region with this architecture.
1300 :returns: Tuple of the entity, if linked.
1301 """
1302 entity = self._entity.Entity
1303 return () if entity is None else (entity, )
1306@export
1307class Component(
1308 ModelEntity,
1309 NamedEntityMixin,
1310 DocumentedEntityMixin,
1311 WithGenericsMixin,
1312 WithPortsMixin,
1313 AllowBlackboxMixin
1314):
1315 """
1316 Represents a component declaration.
1318 .. admonition:: Example
1320 .. code-block:: VHDL
1322 component ent is
1323 -- ...
1324 end component;
1326 .. seealso::
1328 * :class:`Entity it may be bound to <pyVHDLModel.DesignUnit.Entity>`
1329 * :class:`Component configuration <pyVHDLModel.Configuration.ComponentConfiguration>`
1330 """
1332 _isBlackbox: Nullable[bool] #: Component is a blackbox.
1333 _entity: Nullable[Entity] #: Linked entity, or ``None`` if unresolved.
1335 def __init__(
1336 self,
1337 identifier: str,
1338 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
1339 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None,
1340 documentation: Nullable[str] = None,
1341 allowBlackbox: Nullable[bool] = None,
1342 parent: Nullable[ModelEntity] = None
1343 ) -> None:
1344 """
1345 Initializes a component declaration.
1347 :param identifier: The identifier of a model entity.
1348 :param genericItems: List of all generics of this component, in declaration order.
1349 :param portItems: List of all ports of this component, in declaration order.
1350 :param documentation: The documentation comment associated with this declaration.
1351 :param allowBlackbox: Allow blackboxes for components in language entity.
1352 :param parent: The parent model entity of this entity.
1353 """
1354 super().__init__(parent)
1355 NamedEntityMixin.__init__(self, identifier)
1356 DocumentedEntityMixin.__init__(self, documentation)
1357 WithGenericsMixin.__init__(self, genericItems)
1358 WithPortsMixin.__init__(self, portItems)
1359 AllowBlackboxMixin.__init__(self, allowBlackbox)
1361 self._isBlackbox = None
1362 self._entity = None
1364 def Visit(self, visitor: Visitor) -> None:
1365 """
1366 Walk this component declaration, its generic clause and its port clause with a visitor.
1368 :param visitor: The visitor receiving the events.
1369 """
1370 visitor.VisitComponent(self)
1371 self._VisitGenericClause(visitor)
1372 self._VisitPortClause(visitor)
1373 visitor.DepartComponent(self)
1375 def _AddToNamespace(self, element: NamedEntityMixin | MultipleNamedEntityMixin) -> None:
1376 """
1377 Add nothing, because a component has no namespace.
1379 :param element: The named element, e.g. an interface item.
1380 """
1382 def _RemoveFromNamespace(self, element: NamedEntityMixin | MultipleNamedEntityMixin) -> None:
1383 """
1384 Remove nothing, because a component has no namespace.
1386 :param element: The named element, e.g. an interface item.
1387 """
1389 def _ClashingDeclarations(self, item: NamedEntityMixin | MultipleNamedEntityMixin) -> tuple[ModelEntity, ...]:
1390 """
1391 Return the generics and ports of this component sharing an identifier with the given item.
1393 :param item: The new generic or port.
1394 :returns: Tuple of clashing generics and ports.
1395 """
1396 identifiers = set(normalizedIdentifiersOf(item))
1397 return tuple(
1398 declaration for declaration in (*self._genericItems, *self._portItems)
1399 if not identifiers.isdisjoint(normalizedIdentifiersOf(declaration))
1400 )
1402 @readonly
1403 def IsBlackbox(self) -> Nullable[bool]:
1404 """
1405 Check if the component is a blackbox (:attr:`_isBlackbox`).
1407 If components were not linked to matching entities, this property returns ``None``.
1409 :returns: ``True``, if the component is a blackbox; ``False``, if it is not; ``None``, if components
1410 were not linked to entities yet.
1411 """
1412 return self._isBlackbox
1414 @property
1415 def Entity(self) -> Nullable[Entity]:
1416 """
1417 Property to access the entity (:attr:`_entity`).
1419 :returns: The entity, or ``None`` if not set.
1420 """
1421 return self._entity
1423 @Entity.setter
1424 def Entity(self, value: Entity) -> None:
1425 self._entity = value
1426 self._isBlackbox = False
1428 def __str__(self) -> str:
1429 """
1430 Formats the component declaration.
1432 **Format:** ``Component: myComponent``
1434 :returns: Formatted component declaration.
1435 """
1436 return f"Component: {self._identifier}"
1438 def __repr__(self) -> str:
1439 """
1440 Formats a representation of the component declaration.
1442 **Format:** ``mylib.myPackage:myComponent``
1444 :returns: String representation of the component declaration.
1445 """
1446 return f"{self._parent!r}:{self._identifier}"
1449@export
1450class Configuration(PrimaryUnit, DesignUnitWithContextMixin):
1451 """
1452 Represents a configuration declaration.
1454 .. admonition:: Example
1456 .. code-block:: VHDL
1458 configuration cfg of ent is
1459 for rtl
1460 -- ...
1461 end for;
1462 end configuration;
1464 .. seealso::
1466 * :class:`Entity it configures <pyVHDLModel.DesignUnit.Entity>`
1467 * :class:`Block configuration <pyVHDLModel.Configuration.BlockConfiguration>`
1468 """
1470 _entity: EntitySymbol #: Reference to the entity this configuration configures.
1471 _blockConfiguration: BlockConfiguration #: The configuration of the entity's architecture.
1472 _namespace: Namespace #: The namespace of this configuration's declarative region.
1474 def __init__(
1475 self,
1476 identifier: str,
1477 entity: EntitySymbol,
1478 blockConfiguration: BlockConfiguration,
1479 contextItems: Nullable[Iterable[Context]] = None,
1480 documentation: Nullable[str] = None,
1481 parent: Nullable[ModelEntity] = None
1482 ) -> None:
1483 """
1484 Initializes a configuration declaration.
1486 :param identifier: The identifier of a model entity.
1487 :param entity: Reference to the entity this configuration configures.
1488 :param blockConfiguration: The configuration of the entity's architecture.
1489 :param contextItems: List of all context items (library, use and context clauses).
1490 :param documentation: The documentation comment associated with this declaration.
1491 :param parent: The parent model entity of this entity.
1492 """
1493 super().__init__(identifier, contextItems, documentation, parent)
1494 DesignUnitWithContextMixin.__init__(self)
1496 self._namespace = Namespace(self._normalizedIdentifier)
1498 self._entity = entity
1499 entity.Parent = self
1501 self._blockConfiguration = blockConfiguration
1502 blockConfiguration.Parent = self
1504 @readonly
1505 def Entity(self) -> EntitySymbol:
1506 """
1507 Read-only property to access the entity (:attr:`_entity`).
1509 :returns: The entity.
1510 """
1511 return self._entity
1513 @readonly
1514 def BlockConfiguration(self) -> BlockConfiguration:
1515 """
1516 Read-only property to access the block configuration (:attr:`_blockConfiguration`).
1518 :returns: The block configuration.
1519 """
1520 return self._blockConfiguration
1522 def Visit(self, visitor: Visitor) -> None:
1523 """
1524 Walk this configuration, its context clause, its entity and its block configuration with a visitor.
1526 :param visitor: The visitor receiving the events.
1527 """
1528 self._VisitContextClause(visitor)
1529 visitor.VisitConfiguration(self)
1530 self._entity.Visit(visitor)
1531 visitor.VisitIs(self)
1532 self._blockConfiguration.Visit(visitor)
1533 visitor.DepartConfiguration(self)
1535 def __str__(self) -> str:
1536 """
1537 Formats the configuration declaration.
1539 **Format:** ``Configuration: mylib.myConfiguration``
1541 :returns: Formatted configuration declaration.
1542 """
1543 lib = self._parent._identifier if self._parent is not None else "?"
1545 return f"Configuration: {lib}.{self._identifier}"
1547 def __repr__(self) -> str:
1548 """
1549 Formats a representation of the configuration declaration.
1551 **Format:** ``mylib.myConfiguration``
1553 :returns: String representation of the configuration declaration.
1554 """
1555 lib = self._parent._identifier if self._parent is not None else "?"
1557 return f"{lib}.{self._identifier}"