Coverage for pyVHDLModel/DesignUnit.py: 91%
307 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-11 23:50 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-11 23:50 +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 typing import ClassVar, List, Dict, Union, Iterable, Optional as Nullable
39from pyTooling.Decorators import export, readonly
40from pyTooling.MetaClasses import ExtendedType, abstractmethod
41from pyTooling.Graph import Vertex
43from pyVHDLModel.Common import AllowBlackboxMixin
44from pyVHDLModel.Exception import VHDLModelException
45from pyVHDLModel.Base import ModelEntity, NamedEntityMixin, DocumentedEntityMixin
46from pyVHDLModel.Namespace import Namespace
47from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin
48from pyVHDLModel.Symbol import Symbol, PackageSymbol, EntitySymbol, LibraryReferenceSymbol
49from pyVHDLModel.Interface import GenericInterfaceItemMixin, PortInterfaceItemMixin, WithGenericsMixin, WithPortsMixin
50from pyVHDLModel.Object import DeferredConstant
51from pyVHDLModel.Concurrent import ConcurrentStatement, ConcurrentStatementsMixin
52from pyVHDLModel.Configuration import BlockConfiguration
55@export
56class Reference(ModelEntity):
57 """
58 A base-class for all references.
60 .. seealso::
62 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>`
63 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>`
64 * :class:`Context reference <pyVHDLModel.DesignUnit.ContextReference>`
65 """
67 _symbols: List[Symbol] #: List of all symbols referenced by this clause.
69 def __init__(self, symbols: Iterable[Symbol], parent: Nullable[ModelEntity] = None) -> None:
70 """
71 Initializes a reference by taking a list of symbols and a parent reference.
73 :param symbols: A list of symbols this reference references to.
74 :param parent: Reference to the logical parent in the model hierarchy.
75 """
76 super().__init__(parent)
78 self._symbols = [s for s in symbols]
80 @readonly
81 def Symbols(self) -> List[Symbol]:
82 """
83 Read-only property to access the symbols this reference references to (:attr:`_symbols`).
85 :returns: A list of symbols.
86 """
87 return self._symbols
90@export
91class LibraryClause(Reference):
92 """
93 Represents a library clause.
95 .. admonition:: Example
97 .. code-block:: VHDL
99 library std, ieee;
100 """
102 @readonly
103 def Symbols(self) -> List[LibraryReferenceSymbol]:
104 """
105 Read-only property to access the symbols this library clause references to (:attr:`_symbols`).
107 :returns: A list of library reference symbols.
108 """
109 return self._symbols
112@export
113class UseClause(Reference):
114 """
115 Represents a use clause.
117 .. admonition:: Example
119 .. code-block:: VHDL
121 use std.text_io.all, ieee.numeric_std.all;
122 """
125@export
126class ContextReference(Reference):
127 """
128 Represents a context reference.
130 .. hint:: It's called *context reference* not *context clause* by the LRM.
132 .. admonition:: Example
134 .. code-block:: VHDL
136 context ieee.ieee_std_context;
137 """
140ContextUnion = Union[
141 LibraryClause,
142 UseClause,
143 ContextReference
144]
147@export
148class DesignUnitWithContextMixin(metaclass=ExtendedType, mixin=True):
149 """
150 A mixin-class for all design units with a context.
152 .. seealso::
154 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
155 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
156 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
157 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
158 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
159 """
162@export
163class DesignUnit(ModelEntity, NamedEntityMixin, DocumentedEntityMixin):
164 """
165 A base-class for all design units.
167 When a design unit is formatted, an unknown part - a library that is not set, or an entity with no
168 known architecture - is rendered as ``?``.
170 .. seealso::
172 * :class:`Primary design units <pyVHDLModel.DesignUnit.PrimaryUnit>`
174 * :class:`Context <pyVHDLModel.DesignUnit.Context>`
175 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
176 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
177 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
179 * :class:`Secondary design units <pyVHDLModel.DesignUnit.SecondaryUnit>`
181 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
182 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
183 """
185 _continuesParentRegion: ClassVar[bool] = False #: ``True`` if it continues its parent's declarative region.
187 _document: 'Document' #: The VHDL library, the design unit was analyzed into.
189 # Either written as statements before (e.g. entity, architecture, package, ...), or as statements inside (context)
190 _contextItems: List['ContextUnion'] #: List of all context items (library, use and context clauses).
191 _libraryReferences: List['LibraryClause'] #: List of library clauses.
192 _packageReferences: List['UseClause'] #: List of use clauses.
193 _contextReferences: List['ContextReference'] #: List of context clauses.
195 _referencedLibraries: Dict[str, 'Library'] #: Referenced libraries based on explicit library clauses or implicit inheritance
196 _referencedPackages: Dict[str, Dict[str, 'Package']] #: Referenced packages based on explicit use clauses or implicit inheritance
197 _referencedContexts: Dict[str, 'Context'] #: Referenced contexts based on explicit context references or implicit inheritance
199 _dependencyVertex: Vertex[None, None, str, 'DesignUnit', None, None, None, None, None, None, None, None, None, None, None, None, None] #: Reference to the vertex in the dependency graph representing the design unit. |br| This reference is set by :meth:`~pyVHDLModel.Design.CreateDependencyGraph`.
200 _hierarchyVertex: Vertex[None, None, str, 'DesignUnit', None, None, None, None, None, None, None, None, None, None, None, None, None] #: The vertex in the hierarchy graph
202 _namespace: 'Namespace' #: The namespace of this design unit's declarative region.
204 def __init__(self, identifier: str, contextItems: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
205 """
206 Initializes a design unit.
208 :param identifier: Identifier (name) of the design unit.
209 :param contextItems: A sequence of library, use or context clauses.
210 :param documentation: Associated documentation of the design unit.
211 :param parent: Reference to the logical parent in the model hierarchy.
212 """
213 super().__init__(parent)
214 NamedEntityMixin.__init__(self, identifier)
215 DocumentedEntityMixin.__init__(self, documentation)
217 self._document = None
219 self._contextItems = []
220 self._libraryReferences = []
221 self._packageReferences = []
222 self._contextReferences = []
224 if contextItems is not None:
225 for item in contextItems:
226 self._contextItems.append(item)
227 if isinstance(item, UseClause):
228 self._packageReferences.append(item)
229 elif isinstance(item, LibraryClause):
230 self._libraryReferences.append(item)
231 elif isinstance(item, ContextReference): 231 ↛ 225line 231 didn't jump to line 225 because the condition on line 231 was always true
232 self._contextReferences.append(item)
234 self._referencedLibraries = {}
235 self._referencedPackages = {}
236 self._referencedContexts = {}
238 self._dependencyVertex = None
239 self._hierarchyVertex = None
241 self._namespace = Namespace(self._normalizedIdentifier, sharesRegionWithParent=self._continuesParentRegion)
243 @property
244 def Document(self) -> 'Document':
245 """
246 Property to access the document (:attr:`_document`).
248 :returns: The document.
249 """
250 return self._document
252 @Document.setter
253 def Document(self, document: 'Document') -> None:
254 self._document = document
256 @property
257 def Library(self) -> 'Library':
258 """
259 Property to access the library (:attr:`_parent`).
261 :returns: The library.
262 """
263 return self._parent
265 @Library.setter
266 def Library(self, library: 'Library') -> None:
267 self._parent = library
269 @readonly
270 def ContextItems(self) -> List['ContextUnion']:
271 """
272 Read-only property to access the sequence of all context items comprising library, use and context clauses
273 (:attr:`_contextItems`).
275 :returns: Sequence of context items.
276 """
277 return self._contextItems
279 @readonly
280 def ContextReferences(self) -> List['ContextReference']:
281 """
282 Read-only property to access the sequence of context clauses (:attr:`_contextReferences`).
284 :returns: Sequence of context clauses.
285 """
286 return self._contextReferences
288 @readonly
289 def LibraryReferences(self) -> List['LibraryClause']:
290 """
291 Read-only property to access the sequence of library clauses (:attr:`_libraryReferences`).
293 :returns: Sequence of library clauses.
294 """
295 return self._libraryReferences
297 @readonly
298 def PackageReferences(self) -> List['UseClause']:
299 """
300 Read-only property to access the sequence of use clauses (:attr:`_packageReferences`).
302 :returns: Sequence of use clauses.
303 """
304 return self._packageReferences
306 @readonly
307 def ReferencedLibraries(self) -> Dict[str, 'Library']:
308 """
309 Read-only property to access the referenced libraries (:attr:`_referencedLibraries`).
311 :returns: Dictionary of referenced libraries, indexed by normalized identifier.
312 """
313 return self._referencedLibraries
315 @readonly
316 def ReferencedPackages(self) -> Dict[str, 'Package']:
317 """
318 Read-only property to access the referenced packages (:attr:`_referencedPackages`).
320 :returns: Dictionary of referenced packages, indexed by normalized identifier.
321 """
322 return self._referencedPackages
324 @readonly
325 def ReferencedContexts(self) -> Dict[str, 'Context']:
326 """
327 Read-only property to access the referenced contexts (:attr:`_referencedContexts`).
329 :returns: Dictionary of referenced contexts, indexed by normalized identifier.
330 """
331 return self._referencedContexts
333 @readonly
334 def DependencyVertex(self) -> Vertex:
335 """
336 Read-only property to access the corresponding dependency vertex (:attr:`_dependencyVertex`).
338 The dependency vertex references this design unit by its value field.
340 :returns: The corresponding dependency vertex.
341 """
342 return self._dependencyVertex
344 @readonly
345 def HierarchyVertex(self) -> Vertex:
346 """
347 Read-only property to access the corresponding hierarchy vertex (:attr:`_hierarchyVertex`).
349 The hierarchy vertex references this design unit by its value field.
351 :returns: The corresponding hierarchy vertex.
352 """
353 return self._hierarchyVertex
355 @abstractmethod
356 def __str__(self) -> str:
357 """
358 Formats the design unit.
360 Every concrete design unit renders itself, so this base-class provides no implementation.
362 :returns: Formatted design unit.
363 """
366@export
367class PrimaryUnit(DesignUnit):
368 """
369 A base-class for all primary design units.
371 .. seealso::
373 * :class:`Context <pyVHDLModel.DesignUnit.Context>`
374 * :class:`Package <pyVHDLModel.DesignUnit.Package>`
375 * :class:`Entity <pyVHDLModel.DesignUnit.Entity>`
376 * :class:`Configuration <pyVHDLModel.DesignUnit.Configuration>`
377 * :class:`PSL primary unit <pyVHDLModel.PSLModel.PSLPrimaryUnit>` (PSL is not supported)
378 """
381@export
382class SecondaryUnit(DesignUnit):
383 """
384 A base-class for all secondary design units.
386 .. seealso::
388 * :class:`Package body <pyVHDLModel.DesignUnit.PackageBody>`
389 * :class:`Architecture <pyVHDLModel.DesignUnit.Architecture>`
390 """
393@export
394class Context(PrimaryUnit):
395 """
396 Represents a context declaration.
398 A context contains a generic list of all its items (library clauses, use clauses and context references) in
399 :data:`_references`.
401 Furthermore, when a context gets initialized, the item kinds get separated into individual lists:
403 * :class:`~pyVHDLModel.DesignUnit.LibraryClause` |rarr| :data:`_libraryReferences`
404 * :class:`~pyVHDLModel.DesignUnit.UseClause` |rarr| :data:`_packageReferences`
405 * :class:`~pyVHDLModel.DesignUnit.ContextReference` |rarr| :data:`_contextReferences`
407 When :meth:`pyVHDLModel.Design.LinkContexts` got called, these lists were processed and the fields:
409 * :data:`_referencedLibraries` (:pycode:`Dict[libName, Library]`)
410 * :data:`_referencedPackages` (:pycode:`Dict[libName, [pkgName, Package]]`)
411 * :data:`_referencedContexts` (:pycode:`Dict[libName, [ctxName, Context]]`)
413 are populated.
415 .. admonition:: Example
417 .. code-block:: VHDL
419 context ctx is
420 -- ...
421 end context;
423 .. seealso::
425 * :class:`Library clause <pyVHDLModel.DesignUnit.LibraryClause>`
426 * :class:`Use clause <pyVHDLModel.DesignUnit.UseClause>`
427 """
429 _references: List[ContextUnion] #: All context items, in declaration order.
431 def __init__(self, identifier: str, references: Nullable[Iterable[ContextUnion]] = None, documentation: Nullable[str] = None, parent: Nullable[ModelEntity] = None) -> None:
432 """
433 Initializes a context declaration.
435 :param identifier: The identifier of a model entity.
436 :param references: All context items, in declaration order.
437 :param documentation: The documentation comment associated with this declaration.
438 :param parent: The parent model entity of this entity.
439 :raises VHDLModelException: If a context item is neither a library clause, use clause, nor context reference.
440 """
441 super().__init__(identifier, None, documentation, parent)
443 self._references = []
444 self._libraryReferences = []
445 self._packageReferences = []
446 self._contextReferences = []
448 if references is not None:
449 for reference in references:
450 self._references.append(reference)
451 reference.Parent = self
453 if isinstance(reference, LibraryClause):
454 self._libraryReferences.append(reference)
455 elif isinstance(reference, UseClause):
456 self._packageReferences.append(reference)
457 elif isinstance(reference, ContextReference):
458 self._contextReferences.append(reference)
459 else:
460 raise VHDLModelException(f"Reference '{reference!r}' is neither a library clause, use clause, nor context reference.")
462 @readonly
463 def LibraryReferences(self) -> List[LibraryClause]:
464 """
465 Read-only property to access the library references (:attr:`_libraryReferences`).
467 :returns: List of library references.
468 """
469 return self._libraryReferences
471 @readonly
472 def PackageReferences(self) -> List[UseClause]:
473 """
474 Read-only property to access the package references (:attr:`_packageReferences`).
476 :returns: List of package references.
477 """
478 return self._packageReferences
480 @readonly
481 def ContextReferences(self) -> List[ContextReference]:
482 """
483 Read-only property to access the context references (:attr:`_contextReferences`).
485 :returns: List of context references.
486 """
487 return self._contextReferences
489 def __str__(self) -> str:
490 """
491 Formats the context declaration.
493 **Format:** ``Context: mylib.myContext``
495 :returns: Formatted context declaration.
496 """
497 lib = self._parent._identifier if self._parent is not None else "?"
499 return f"Context: {lib}.{self._identifier}"
502@export
503class Package(PrimaryUnit, DesignUnitWithContextMixin, WithGenericsMixin, ConcurrentDeclarationRegionMixin, AllowBlackboxMixin):
504 """
505 Represents a package declaration.
507 .. admonition:: Example
509 .. code-block:: VHDL
511 package pkg is
512 -- ...
513 end package;
515 .. seealso::
517 * :class:`Package instantiation <pyVHDLModel.Instantiation.PackageInstantiation>`
518 * :class:`Predefined package <pyVHDLModel.Predefined.PredefinedPackage>`
519 * :class:`Package body implementing it <pyVHDLModel.DesignUnit.PackageBody>`
520 """
522 _packageBody: Nullable["PackageBody"] #: The corresponding package body, or ``None`` if none was analyzed.
524 _deferredConstants: Dict[str, DeferredConstant] #: Deferred constants, indexed by name.
525 _components: Dict[str, 'Component'] #: Components, indexed by name.
527 def __init__(
528 self,
529 identifier: str,
530 contextItems: Nullable[Iterable[ContextUnion]] = None,
531 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
532 declaredItems: Nullable[Iterable] = None,
533 documentation: Nullable[str] = None,
534 allowBlackbox: Nullable[bool] = None,
535 parent: Nullable[ModelEntity] = None
536 ) -> None:
537 """
538 Initialize a package.
540 :param identifier: Name of the VHDL package.
541 :param contextItems:
542 :param genericItems:
543 :param declaredItems:
544 :param documentation:
545 :param allowBlackbox: Specify if blackboxes are allowed in this design.
546 :param parent: The parent model entity (library) of this VHDL package.
547 """
548 super().__init__(identifier, contextItems, documentation, parent)
549 DesignUnitWithContextMixin.__init__(self)
550 WithGenericsMixin.__init__(self, genericItems)
551 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
552 AllowBlackboxMixin.__init__(self, allowBlackbox)
554 self._packageBody = None
556 self._deferredConstants = {}
557 self._components = {}
559 @readonly
560 def PackageBody(self) -> Nullable["PackageBody"]:
561 """
562 Read-only property to access the package body (:attr:`_packageBody`).
564 :returns: The package body, or ``None`` if not set.
565 """
566 return self._packageBody
568 @readonly
569 def DeclaredItems(self) -> List:
570 """
571 Read-only property to access the declared items (:attr:`_declaredItems`).
573 :returns: List of declared items.
574 """
575 return self._declaredItems
577 @readonly
578 def DeferredConstants(self) -> Dict[str, DeferredConstant]:
579 """
580 Read-only property to access the deferred constants (:attr:`_deferredConstants`).
582 :returns: Dictionary of deferred constants, indexed by normalized identifier.
583 """
584 return self._deferredConstants
586 @readonly
587 def Components(self) -> Dict[str, 'Component']:
588 """
589 Read-only property to access the components (:attr:`_components`).
591 :returns: Dictionary of components, indexed by normalized identifier.
592 """
593 return self._components
595 def _IndexOtherDeclaredItem(self, item) -> None:
596 if isinstance(item, DeferredConstant): 596 ↛ 599line 596 didn't jump to line 599 because the condition on line 596 was always true
597 for normalizedIdentifier in item.NormalizedIdentifiers:
598 self._deferredConstants[normalizedIdentifier] = item
599 elif isinstance(item, Component):
600 self._components[item._normalizedIdentifier] = item
601 else:
602 super()._IndexOtherDeclaredItem(item)
604 def __str__(self) -> str:
605 """
606 Formats the package declaration.
608 **Format:** ``Package: 'mylib.myPackage'``
610 :returns: Formatted package declaration.
611 """
612 lib = self._parent._identifier if self._parent is not None else "?"
614 return f"Package: '{lib}.{self._identifier}'"
616 def __repr__(self) -> str:
617 """
618 Formats a representation of the package declaration.
620 **Format:** ``mylib.myPackage``
622 :returns: String representation of the package declaration.
623 """
624 lib = self._parent._identifier if self._parent is not None else "?"
626 return f"{lib}.{self._identifier}"
629 def IndexDeclaredItems(self) -> None:
630 """A generic package's generics share the declarative region of its declarative part."""
631 self._IndexGenericItems()
633 super().IndexDeclaredItems()
636@export
637class PackageBody(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin):
638 """
639 Represents a package body declaration.
641 .. admonition:: Example
643 .. code-block:: VHDL
645 package body pkg is
646 -- ...
647 end package body;
649 .. seealso::
651 * :class:`Predefined package body <pyVHDLModel.Predefined.PredefinedPackageBody>`
652 * :class:`Package it implements <pyVHDLModel.DesignUnit.Package>`
653 """
655 _continuesParentRegion: ClassVar[bool] = True #: A package body continues its package's declarative region.
657 _package: PackageSymbol #: Reference to the package this body implements.
659 def __init__(
660 self,
661 packageSymbol: PackageSymbol,
662 contextItems: Nullable[Iterable[ContextUnion]] = None,
663 declaredItems: Nullable[Iterable] = None,
664 documentation: Nullable[str] = None,
665 parent: Nullable[ModelEntity] = None
666 ) -> None:
667 """
668 Initializes a package body declaration.
670 :param packageSymbol: Reference to the package this body implements.
671 :param contextItems: List of all context items (library, use and context clauses).
672 :param declaredItems: List of all declared items in this concurrent declaration region.
673 :param documentation: The documentation comment associated with this declaration.
674 :param parent: The parent model entity of this entity.
675 """
676 super().__init__(packageSymbol.Name.Identifier, contextItems, documentation, parent)
677 DesignUnitWithContextMixin.__init__(self)
678 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
680 self._package = packageSymbol
681 packageSymbol.Parent = self
683 @readonly
684 def Package(self) -> PackageSymbol:
685 """
686 Read-only property to access the package (:attr:`_package`).
688 :returns: The package.
689 """
690 return self._package
692 @readonly
693 def DeclaredItems(self) -> List:
694 """
695 Read-only property to access the declared items (:attr:`_declaredItems`).
697 :returns: List of declared items.
698 """
699 return self._declaredItems
701 def LinkDeclaredItemsToPackage(self) -> None:
702 pass
704 def __str__(self) -> str:
705 """
706 Formats the package body declaration.
708 **Format:** ``Package Body: mylib.myPackage(body)``
710 :returns: Formatted package body declaration.
711 """
712 lib = self._parent._identifier if self._parent is not None else "?"
714 return f"Package Body: {lib}.{self._identifier}(body)"
716 def __repr__(self) -> str:
717 """
718 Formats a representation of the package body declaration.
720 **Format:** ``mylib.myPackage(body)``
722 :returns: String representation of the package body declaration.
723 """
724 lib = self._parent._identifier if self._parent is not None else "?"
726 return f"{lib}.{self._identifier}(body)"
729@export
730class Entity(PrimaryUnit, DesignUnitWithContextMixin, WithGenericsMixin, WithPortsMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
731 """
732 Represents an entity declaration.
734 .. admonition:: Example
736 .. code-block:: VHDL
738 entity ent is
739 -- ...
740 end entity;
742 .. seealso::
744 * :class:`Architecture implementing it <pyVHDLModel.DesignUnit.Architecture>`
745 * :class:`Component declaring the same interface <pyVHDLModel.DesignUnit.Component>`
746 * :class:`Configuration binding it <pyVHDLModel.DesignUnit.Configuration>`
747 """
749 _architectures: Dict[str, 'Architecture'] #: Dictionary of all architectures of this entity, indexed by name.
751 def __init__(
752 self,
753 identifier: str,
754 contextItems: Nullable[Iterable[ContextUnion]] = None,
755 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
756 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None,
757 declaredItems: Nullable[Iterable] = None,
758 statements: Nullable[Iterable[ConcurrentStatement]] = None,
759 documentation: Nullable[str] = None,
760 allowBlackbox: Nullable[bool] = None,
761 parent: Nullable[ModelEntity] = None
762 ) -> None:
763 """
764 Initializes an entity declaration.
766 :param identifier: The identifier of a model entity.
767 :param contextItems: List of all context items (library, use and context clauses).
768 :param genericItems: List of all generics, in declaration order.
769 :param portItems: List of all ports, in declaration order.
770 :param declaredItems: List of all declared items in this concurrent declaration region.
771 :param statements: List of all concurrent statements in this construct.
772 :param documentation: The documentation comment associated with this declaration.
773 :param allowBlackbox: Allow blackboxes for components in language entity.
774 :param parent: The parent model entity of this entity.
775 """
776 super().__init__(identifier, contextItems, documentation, parent)
777 DesignUnitWithContextMixin.__init__(self)
778 WithGenericsMixin.__init__(self, genericItems)
779 WithPortsMixin.__init__(self, portItems)
780 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
781 ConcurrentStatementsMixin.__init__(self, statements)
782 AllowBlackboxMixin.__init__(self, allowBlackbox)
784 self._architectures = {}
786 @readonly
787 def Architectures(self) -> Dict[str, 'Architecture']:
788 """
789 Read-only property to access the architectures (:attr:`_architectures`).
791 :returns: Dictionary of architectures, indexed by normalized identifier.
792 """
793 return self._architectures
795 def __str__(self) -> str:
796 """
797 Formats the entity declaration.
799 **Format:** ``Entity: 'mylib.myEntity(rtl, sim)'``
801 The parenthesis lists the known architectures, or ``?`` if there are none.
803 :returns: Formatted entity declaration.
804 """
805 lib = self._parent._identifier if self._parent is not None else "?"
806 archs = ', '.join(self._architectures.keys()) if self._architectures else "?"
808 return f"Entity: '{lib}.{self._identifier}({archs})'"
810 def __repr__(self) -> str:
811 """
812 Formats a representation of the entity declaration.
814 **Format:** ``mylib.myEntity(rtl, sim)``
816 :returns: String representation of the entity declaration.
817 """
818 lib = self._parent._identifier if self._parent is not None else "?"
819 archs = ', '.join(self._architectures.keys()) if self._architectures else "?"
821 return f"{lib}.{self._identifier}({archs})"
824 def IndexDeclaredItems(self) -> None:
825 """An entity's generics and ports share the declarative region of its declarative part."""
826 self._IndexGenericItems()
827 self._IndexPortItems()
829 super().IndexDeclaredItems()
832@export
833class Architecture(SecondaryUnit, DesignUnitWithContextMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
834 """
835 Represents an architecture declaration.
837 .. admonition:: Example
839 .. code-block:: VHDL
841 architecture rtl of ent is
842 -- ...
843 begin
844 -- ...
845 end architecture;
847 .. seealso::
849 * :class:`Entity it implements <pyVHDLModel.DesignUnit.Entity>`
850 """
852 _continuesParentRegion: ClassVar[bool] = True #: An architecture continues its entity's declarative region.
854 _entity: EntitySymbol #: Reference to the entity this architecture implements.
856 def __init__(
857 self,
858 identifier: str,
859 entity: EntitySymbol,
860 contextItems: Nullable[Iterable[Context]] = None,
861 declaredItems: Nullable[Iterable] = None,
862 statements: Iterable['ConcurrentStatement'] = None,
863 documentation: Nullable[str] = None,
864 allowBlackbox: Nullable[bool] = None,
865 parent: Nullable[ModelEntity] = None
866 ) -> None:
867 """
868 Initializes an architecture declaration.
870 :param identifier: The identifier of a model entity.
871 :param entity: Reference to the entity this architecture implements.
872 :param contextItems: List of all context items (library, use and context clauses).
873 :param declaredItems: List of all declared items in this concurrent declaration region.
874 :param statements: List of all concurrent statements in this construct.
875 :param documentation: The documentation comment associated with this declaration.
876 :param allowBlackbox: Allow blackboxes for components in language entity.
877 :param parent: The parent model entity of this entity.
878 """
879 super().__init__(identifier, contextItems, documentation, parent)
880 DesignUnitWithContextMixin.__init__(self)
881 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
882 ConcurrentStatementsMixin.__init__(self, statements)
883 AllowBlackboxMixin.__init__(self, allowBlackbox)
885 self._entity = entity
886 entity.Parent = self
888 @readonly
889 def Entity(self) -> EntitySymbol: # FIXME: change to entitySymbol, offer entity directly, but raise exception if not resolved.
890 """
891 Read-only property to access the entity (:attr:`_entity`).
893 :returns: The entity.
894 """
895 return self._entity
897 def __str__(self) -> str:
898 """
899 Formats the architecture declaration.
901 **Format:** ``Architecture: mylib.myEntity(rtl)``
903 :returns: Formatted architecture declaration.
904 """
905 lib = self._parent._identifier if self._parent is not None else "?"
906 ent = self._entity._name._identifier if self._entity is not None else "?"
908 return f"Architecture: {lib}.{ent}({self._identifier})"
910 def __repr__(self) -> str:
911 """
912 Formats a representation of the architecture declaration.
914 **Format:** ``mylib.myEntity(rtl)``
916 :returns: String representation of the architecture declaration.
917 """
918 lib = self._parent._identifier if self._parent is not None else "?"
919 ent = self._entity._name._identifier if self._entity is not None else "?"
921 return f"{lib}.{ent}({self._identifier})"
924@export
925class Component(ModelEntity, NamedEntityMixin, DocumentedEntityMixin, AllowBlackboxMixin):
926 """
927 Represents a component declaration.
929 .. admonition:: Example
931 .. code-block:: VHDL
933 component ent is
934 -- ...
935 end component;
937 .. seealso::
939 * :class:`Entity it may be bound to <pyVHDLModel.DesignUnit.Entity>`
940 * :class:`Component configuration <pyVHDLModel.Configuration.ComponentConfiguration>`
941 """
943 _isBlackbox: Nullable[bool] #: Component is a blackbox.
945 _genericItems: List[GenericInterfaceItemMixin] #: List of all generics of this component, in declaration order.
946 _portItems: List[PortInterfaceItemMixin] #: List of all ports of this component, in declaration order.
948 _entity: Nullable[Entity] #: Linked entity, or ``None`` if unresolved.
950 def __init__(
951 self,
952 identifier: str,
953 genericItems: Nullable[Iterable[GenericInterfaceItemMixin]] = None,
954 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None,
955 documentation: Nullable[str] = None,
956 allowBlackbox: Nullable[bool] = None,
957 parent: Nullable[ModelEntity] = None
958 ) -> None:
959 """
960 Initializes a component declaration.
962 :param identifier: The identifier of a model entity.
963 :param genericItems: List of all generics of this component, in declaration order.
964 :param portItems: List of all ports of this component, in declaration order.
965 :param documentation: The documentation comment associated with this declaration.
966 :param allowBlackbox: Allow blackboxes for components in language entity.
967 :param parent: The parent model entity of this entity.
968 """
969 super().__init__(parent)
970 NamedEntityMixin.__init__(self, identifier)
971 DocumentedEntityMixin.__init__(self, documentation)
972 AllowBlackboxMixin.__init__(self, allowBlackbox)
974 self._isBlackbox = None
975 self._entity = None
977 # TODO: extract to mixin
978 self._genericItems = []
979 if genericItems is not None:
980 for item in genericItems:
981 self._genericItems.append(item)
982 item.Parent = self
984 # TODO: extract to mixin
985 self._portItems = []
986 if portItems is not None:
987 for item in portItems:
988 self._portItems.append(item)
989 item.Parent = self
991 @readonly
992 def IsBlackbox(self) -> Nullable[bool]:
993 """
994 Check if the component is a blackbox (:attr:`_isBlackbox`).
996 If components were not linked to matching entities, this property returns ``None``.
998 :returns: ``True``, if the component is a blackbox; ``False``, if it is not; ``None``, if components
999 were not linked to entities yet.
1000 """
1001 return self._isBlackbox
1003 @readonly
1004 def GenericItems(self) -> List[GenericInterfaceItemMixin]:
1005 """
1006 Read-only property to access the generic items (:attr:`_genericItems`).
1008 :returns: List of generic items.
1009 """
1010 return self._genericItems
1012 @readonly
1013 def PortItems(self) -> List[PortInterfaceItemMixin]:
1014 """
1015 Read-only property to access the port items (:attr:`_portItems`).
1017 :returns: List of port items.
1018 """
1019 return self._portItems
1021 @property
1022 def Entity(self) -> Nullable[Entity]:
1023 """
1024 Property to access the entity (:attr:`_entity`).
1026 :returns: The entity, or ``None`` if not set.
1027 """
1028 return self._entity
1030 @Entity.setter
1031 def Entity(self, value: Entity) -> None:
1032 self._entity = value
1033 self._isBlackbox = False
1035 def __str__(self) -> str:
1036 """
1037 Formats the component declaration.
1039 **Format:** ``Component: myComponent``
1041 :returns: Formatted component declaration.
1042 """
1043 return f"Component: {self._identifier}"
1045 def __repr__(self) -> str:
1046 """
1047 Formats a representation of the component declaration.
1049 **Format:** ``mylib.myPackage:myComponent``
1051 :returns: String representation of the component declaration.
1052 """
1053 return f"{self._parent!r}:{self._identifier}"
1056@export
1057class Configuration(PrimaryUnit, DesignUnitWithContextMixin):
1058 """
1059 Represents a configuration declaration.
1061 .. admonition:: Example
1063 .. code-block:: VHDL
1065 configuration cfg of ent is
1066 for rtl
1067 -- ...
1068 end for;
1069 end configuration;
1071 .. seealso::
1073 * :class:`Entity it configures <pyVHDLModel.DesignUnit.Entity>`
1074 * :class:`Block configuration <pyVHDLModel.Configuration.BlockConfiguration>`
1075 """
1077 _entity: EntitySymbol #: Reference to the entity this configuration configures.
1078 _blockConfiguration: BlockConfiguration #: The configuration of the entity's architecture.
1080 def __init__(
1081 self,
1082 identifier: str,
1083 entity: EntitySymbol,
1084 blockConfiguration: BlockConfiguration,
1085 contextItems: Nullable[Iterable[Context]] = None,
1086 documentation: Nullable[str] = None,
1087 parent: Nullable[ModelEntity] = None
1088 ) -> None:
1089 """
1090 Initializes a configuration declaration.
1092 :param identifier: The identifier of a model entity.
1093 :param entity: Reference to the entity this configuration configures.
1094 :param blockConfiguration: The configuration of the entity's architecture.
1095 :param contextItems: List of all context items (library, use and context clauses).
1096 :param documentation: The documentation comment associated with this declaration.
1097 :param parent: The parent model entity of this entity.
1098 """
1099 super().__init__(identifier, contextItems, documentation, parent)
1100 DesignUnitWithContextMixin.__init__(self)
1102 self._entity = entity
1103 entity.Parent = self
1105 self._blockConfiguration = blockConfiguration
1106 blockConfiguration.Parent = self
1108 @readonly
1109 def Entity(self) -> EntitySymbol:
1110 """
1111 Read-only property to access the entity (:attr:`_entity`).
1113 :returns: The entity.
1114 """
1115 return self._entity
1117 @readonly
1118 def BlockConfiguration(self) -> BlockConfiguration:
1119 """
1120 Read-only property to access the block configuration (:attr:`_blockConfiguration`).
1122 :returns: The block configuration.
1123 """
1124 return self._blockConfiguration
1126 def __str__(self) -> str:
1127 """
1128 Formats the configuration declaration.
1130 **Format:** ``Configuration: mylib.myConfiguration``
1132 :returns: Formatted configuration declaration.
1133 """
1134 lib = self._parent._identifier if self._parent is not None else "?"
1136 return f"Configuration: {lib}.{self._identifier}"
1138 def __repr__(self) -> str:
1139 """
1140 Formats a representation of the configuration declaration.
1142 **Format:** ``mylib.myConfiguration``
1144 :returns: String representation of the configuration declaration.
1145 """
1146 lib = self._parent._identifier if self._parent is not None else "?"
1148 return f"{lib}.{self._identifier}"