Coverage for pyVHDLModel / Concurrent.py: 52%
367 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 22:37 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-24 22:37 +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.
35Concurrent defines all concurrent statements used in entities, architectures, generates and block statements.
36"""
37from typing import List, Dict, Union, Iterable, Generator, Optional as Nullable
39from pyTooling.Decorators import export, readonly
40from pyTooling.MetaClasses import ExtendedType
42from pyVHDLModel.Base import ModelEntity, LabeledEntityMixin, DocumentedEntityMixin, Range, BaseChoice, BaseCase, IfBranchMixin
43from pyVHDLModel.Base import ElsifBranchMixin, ElseBranchMixin, AssertStatementMixin, BlockStatementMixin, WaveformElement
44from pyVHDLModel.Regions import ConcurrentDeclarationRegionMixin
45from pyVHDLModel.Namespace import Namespace
46from pyVHDLModel.Name import Name
47from pyVHDLModel.Symbol import ComponentInstantiationSymbol, EntityInstantiationSymbol, ArchitectureSymbol, ConfigurationInstantiationSymbol
48from pyVHDLModel.Expression import BaseExpression, QualifiedExpression, FunctionCall, TypeConversion, Literal
49from pyVHDLModel.Association import AssociationItem, ParameterAssociationItem
50from pyVHDLModel.Interface import PortInterfaceItemMixin
51from pyVHDLModel.Common import Statement, ProcedureCallMixin, SignalAssignmentMixin, AllowBlackboxMixin
52from pyVHDLModel.Sequential import SequentialStatement, SequentialStatementsMixin, SequentialDeclarationsMixin
55ExpressionUnion = Union[
56 BaseExpression,
57 QualifiedExpression,
58 FunctionCall,
59 TypeConversion,
60 # ConstantOrSymbol, TODO: ObjectSymbol
61 Literal,
62]
65@export
66class ConcurrentStatement(Statement):
67 """A base-class for all concurrent statements."""
70@export
71class ConcurrentStatementsMixin(metaclass=ExtendedType, mixin=True):
72 """
73 A mixin-class for all language constructs supporting concurrent statements.
75 .. seealso::
77 .. todo:: concurrent declaration region
78 """
80 _statements: List[ConcurrentStatement]
82 _instantiations: Dict[str, 'Instantiation'] # TODO: add another instantiation class level for entity/configuration/component inst.
83 _blocks: Dict[str, 'ConcurrentBlockStatement']
84 _generates: Dict[str, 'GenerateStatement']
85 _hierarchy: Dict[str, Union['ConcurrentBlockStatement', 'GenerateStatement']]
87 def __init__(self, statements: Nullable[Iterable[ConcurrentStatement]] = None) -> None:
88 self._statements = []
90 self._instantiations = {}
91 self._blocks = {}
92 self._generates = {}
93 self._hierarchy = {}
95 if statements is not None:
96 for statement in statements:
97 self._statements.append(statement)
98 statement._parent = self
100 @readonly
101 def Statements(self) -> List[ConcurrentStatement]:
102 return self._statements
104 def IterateInstantiations(self) -> Generator['Instantiation', None, None]:
105 for instance in self._instantiations.values():
106 yield instance
108 for block in self._blocks.values(): 108 ↛ 109line 108 didn't jump to line 109 because the loop on line 108 never started
109 yield from block.IterateInstantiations()
111 for generate in self._generates.values(): 111 ↛ 112line 111 didn't jump to line 112 because the loop on line 111 never started
112 yield from generate.IterateInstantiations()
114 # TODO: move into _init__
115 def IndexStatements(self) -> None:
116 for statement in self._statements:
117 if isinstance(statement, (EntityInstantiation, ComponentInstantiation, ConfigurationInstantiation)): 117 ↛ 119line 117 didn't jump to line 119 because the condition on line 117 was always true
118 self._instantiations[statement.NormalizedLabel] = statement
119 elif isinstance(statement, (ForGenerateStatement, IfGenerateStatement, CaseGenerateStatement)):
120 self._generates[statement.NormalizedLabel] = statement
121 statement.IndexStatement()
122 elif isinstance(statement, ConcurrentBlockStatement):
123 self._hierarchy[statement.NormalizedLabel] = statement
124 statement.IndexStatements()
127@export
128class Instantiation(ConcurrentStatement):
129 """
130 A base-class for all (component) instantiations.
131 """
133 _genericAssociations: List[AssociationItem]
134 _portAssociations: List[AssociationItem]
136 def __init__(
137 self,
138 label: str,
139 genericAssociations: Nullable[Iterable[AssociationItem]] = None,
140 portAssociations: Nullable[Iterable[AssociationItem]] = None,
141 parent: ModelEntity = None
142 ) -> None:
143 super().__init__(label, parent)
145 # TODO: extract to mixin
146 self._genericAssociations = []
147 if genericAssociations is not None: 147 ↛ 148line 147 didn't jump to line 148 because the condition on line 147 was never true
148 for association in genericAssociations:
149 self._genericAssociations.append(association)
150 association._parent = self
152 # TODO: extract to mixin
153 self._portAssociations = []
154 if portAssociations is not None: 154 ↛ 155line 154 didn't jump to line 155 because the condition on line 154 was never true
155 for association in portAssociations:
156 self._portAssociations.append(association)
157 association._parent = self
159 @readonly
160 def GenericAssociations(self) -> List[AssociationItem]:
161 return self._genericAssociations
163 @property
164 def PortAssociations(self) -> List[AssociationItem]:
165 return self._portAssociations
168@export
169class ComponentInstantiation(Instantiation):
170 """
171 Represents a component instantiation by referring to a component name.
173 .. admonition:: Example
175 .. code-block:: VHDL
177 inst : component Counter;
178 """
180 _component: ComponentInstantiationSymbol
182 def __init__(
183 self,
184 label: str,
185 componentSymbol: ComponentInstantiationSymbol,
186 genericAssociations: Nullable[Iterable[AssociationItem]] = None,
187 portAssociations: Nullable[Iterable[AssociationItem]] = None,
188 parent: ModelEntity = None
189 ) -> None:
190 super().__init__(label, genericAssociations, portAssociations, parent)
192 self._component = componentSymbol
193 componentSymbol._parent = self
195 @property
196 def Component(self) -> ComponentInstantiationSymbol:
197 return self._component
200@export
201class EntityInstantiation(Instantiation):
202 """
203 Represents an entity instantiation by referring to an entity name with optional architecture name.
205 .. admonition:: Example
207 .. code-block:: VHDL
209 inst : entity work. Counter;
210 """
212 _entity: EntityInstantiationSymbol
213 _architecture: ArchitectureSymbol
215 def __init__(
216 self,
217 label: str,
218 entitySymbol: EntityInstantiationSymbol,
219 architectureSymbol: Nullable[ArchitectureSymbol] = None,
220 genericAssociations: Nullable[Iterable[AssociationItem]] = None,
221 portAssociations: Nullable[Iterable[AssociationItem]] = None,
222 parent: ModelEntity = None
223 ) -> None:
224 super().__init__(label, genericAssociations, portAssociations, parent)
226 self._entity = entitySymbol
227 entitySymbol._parent = self
229 self._architecture = architectureSymbol
230 if architectureSymbol is not None: 230 ↛ 231line 230 didn't jump to line 231 because the condition on line 230 was never true
231 architectureSymbol._parent = self
233 @property
234 def Entity(self) -> EntityInstantiationSymbol:
235 return self._entity
237 @property
238 def Architecture(self) -> ArchitectureSymbol:
239 return self._architecture
242@export
243class ConfigurationInstantiation(Instantiation):
244 """
245 Represents a configuration instantiation by referring to a configuration name.
247 .. admonition:: Example
249 .. code-block:: VHDL
251 inst : configuration Counter;
252 """
254 _configuration: ConfigurationInstantiationSymbol
256 def __init__(
257 self,
258 label: str,
259 configurationSymbol: ConfigurationInstantiationSymbol,
260 genericAssociations: Nullable[Iterable[AssociationItem]] = None,
261 portAssociations: Nullable[Iterable[AssociationItem]] = None,
262 parent: ModelEntity = None
263 ) -> None:
264 super().__init__(label, genericAssociations, portAssociations, parent)
266 self._configuration = configurationSymbol
267 configurationSymbol._parent = self
269 @property
270 def Configuration(self) -> ConfigurationInstantiationSymbol:
271 return self._configuration
274@export
275class ProcessStatement(ConcurrentStatement, SequentialDeclarationsMixin, SequentialStatementsMixin, DocumentedEntityMixin):
276 """
277 Represents a process statement with sensitivity list, sequential declaration region and sequential statements.
279 .. admonition:: Example
281 .. code-block:: VHDL
283 proc: process(Clock)
284 -- sequential declarations
285 begin
286 -- sequential statements
287 end process;
288 """
290 _sensitivityList: List[Name] # TODO: implement a SignalSymbol
292 def __init__(
293 self,
294 label: Nullable[str] = None,
295 declaredItems: Nullable[Iterable] = None,
296 statements: Nullable[Iterable[SequentialStatement]] = None,
297 sensitivityList: Nullable[Iterable[Name]] = None,
298 documentation: Nullable[str] = None,
299 parent: ModelEntity = None
300 ) -> None:
301 super().__init__(label, parent)
302 SequentialDeclarationsMixin.__init__(self, declaredItems)
303 SequentialStatementsMixin.__init__(self, statements)
304 DocumentedEntityMixin.__init__(self, documentation)
306 if sensitivityList is None:
307 self._sensitivityList = None
308 else:
309 self._sensitivityList = [] # TODO: convert to dict
310 for signalSymbol in sensitivityList:
311 self._sensitivityList.append(signalSymbol)
312 # signalSymbol._parent = self # FIXME: currently str are provided
314 @property
315 def SensitivityList(self) -> List[Name]:
316 return self._sensitivityList
319@export
320class ConcurrentProcedureCall(ConcurrentStatement, ProcedureCallMixin):
321 def __init__(
322 self,
323 label: str,
324 procedureName: Name,
325 parameterMappings: Nullable[Iterable[ParameterAssociationItem]] = None,
326 parent: ModelEntity = None
327 ) -> None:
328 super().__init__(label, parent)
329 ProcedureCallMixin.__init__(self, procedureName, parameterMappings)
332@export
333class ConcurrentBlockStatement(ConcurrentStatement, BlockStatementMixin, LabeledEntityMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, DocumentedEntityMixin, AllowBlackboxMixin):
334 _portItems: List[PortInterfaceItemMixin]
336 def __init__(
337 self,
338 label: str,
339 portItems: Nullable[Iterable[PortInterfaceItemMixin]] = None,
340 declaredItems: Nullable[Iterable] = None,
341 statements: Iterable['ConcurrentStatement'] = None,
342 documentation: Nullable[str] = None,
343 allowBlackbox: Nullable[bool] = None,
344 parent: ModelEntity = None
345 ) -> None:
346 super().__init__(label, parent)
347 BlockStatementMixin.__init__(self)
348 LabeledEntityMixin.__init__(self, label)
349 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
350 ConcurrentStatementsMixin.__init__(self, statements)
351 DocumentedEntityMixin.__init__(self, documentation)
352 AllowBlackboxMixin.__init__(self, allowBlackbox)
354 # TODO: extract to mixin
355 self._portItems = []
356 if portItems is not None:
357 for item in portItems:
358 self._portItems.append(item)
359 item._parent = self
361 @property
362 def PortItems(self) -> List[PortInterfaceItemMixin]:
363 return self._portItems
366@export
367class GenerateBranch(ModelEntity, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
368 """
369 A base-class for all branches in a generate statements.
371 .. seealso::
373 * :class:`If-generate branch <pyVHDLModel.Concurrent.IfGenerateBranch>`
374 * :class:`Elsif-generate branch <pyVHDLModel.Concurrent.ElsifGenerateBranch>`
375 * :class:`Else-generate branch <pyVHDLModel.Concurrent.ElseGenerateBranch>`
376 """
378 _alternativeLabel: Nullable[str]
379 _normalizedAlternativeLabel: Nullable[str]
381 _namespace: Namespace
383 def __init__(
384 self,
385 declaredItems: Nullable[Iterable] = None,
386 statements: Nullable[Iterable[ConcurrentStatement]] = None,
387 alternativeLabel: Nullable[str] = None,
388 allowBlackbox: Nullable[bool] = None,
389 parent: ModelEntity = None
390 ) -> None:
391 super().__init__(parent)
392 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
393 ConcurrentStatementsMixin.__init__(self, statements)
394 AllowBlackboxMixin.__init__(self, allowBlackbox)
396 self._alternativeLabel = alternativeLabel
397 self._normalizedAlternativeLabel = alternativeLabel.lower() if alternativeLabel is not None else None
399 self._namespace = Namespace(self._normalizedAlternativeLabel)
401 @property
402 def AlternativeLabel(self) -> Nullable[str]:
403 return self._alternativeLabel
405 @property
406 def NormalizedAlternativeLabel(self) -> Nullable[str]:
407 return self._normalizedAlternativeLabel
410@export
411class IfGenerateBranch(GenerateBranch, IfBranchMixin):
412 """
413 Represents if-generate branch in a generate statement with a concurrent declaration region and concurrent statements.
415 .. admonition:: Example
417 .. code-block:: VHDL
419 gen: if condition generate
420 -- concurrent declarations
421 begin
422 -- concurrent statements
423 elsif condition generate
424 -- ...
425 else generate
426 -- ...
427 end generate;
428 """
430 def __init__(
431 self,
432 condition: ExpressionUnion,
433 declaredItems: Nullable[Iterable] = None,
434 statements: Nullable[Iterable[ConcurrentStatement]] = None,
435 alternativeLabel: Nullable[str] = None,
436 allowBlackbox: Nullable[bool] = None,
437 parent: ModelEntity = None
438 ) -> None:
439 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent)
440 IfBranchMixin.__init__(self, condition)
443@export
444class ElsifGenerateBranch(GenerateBranch, ElsifBranchMixin):
445 """
446 Represents elsif-generate branch in a generate statement with a concurrent declaration region and concurrent statements.
448 .. admonition:: Example
450 .. code-block:: VHDL
452 gen: if condition generate
453 -- ...
454 elsif condition generate
455 -- concurrent declarations
456 begin
457 -- concurrent statements
458 else generate
459 -- ...
460 end generate;
461 """
463 def __init__(
464 self,
465 condition: ExpressionUnion,
466 declaredItems: Nullable[Iterable] = None,
467 statements: Nullable[Iterable[ConcurrentStatement]] = None,
468 alternativeLabel: Nullable[str] = None,
469 allowBlackbox: Nullable[bool] = None,
470 parent: ModelEntity = None
471 ) -> None:
472 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent)
473 ElsifBranchMixin.__init__(self, condition)
476@export
477class ElseGenerateBranch(GenerateBranch, ElseBranchMixin):
478 """
479 Represents else-generate branch in a generate statement with a concurrent declaration region and concurrent statements.
481 .. admonition:: Example
483 .. code-block:: VHDL
485 gen: if condition generate
486 -- ...
487 elsif condition generate
488 -- ...
489 else generate
490 -- concurrent declarations
491 begin
492 -- concurrent statements
493 end generate;
494 """
496 def __init__(
497 self,
498 declaredItems: Nullable[Iterable] = None,
499 statements: Nullable[Iterable[ConcurrentStatement]] = None,
500 alternativeLabel: Nullable[str] = None,
501 allowBlackbox: Nullable[bool] = None,
502 parent: ModelEntity = None
503 ) -> None:
504 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent)
505 ElseBranchMixin.__init__(self)
508@export
509class GenerateStatement(ConcurrentStatement, AllowBlackboxMixin):
510 """
511 A base-class for all generate statements.
513 .. seealso::
515 * :class:`If...generate statement <pyVHDLModel.Concurrent.IfGenerateStatement>`
516 * :class:`Case...generate statement <pyVHDLModel.Concurrent.CaseGenerateStatement>`
517 * :class:`For...generate statement <pyVHDLModel.Concurrent.ForGenerateStatement>`
518 """
520 _namespace: Namespace
522 def __init__(
523 self,
524 label: Nullable[str] = None,
525 allowBlackbox: Nullable[bool] = None,
526 parent: ModelEntity = None
527 ) -> None:
528 super().__init__(label, parent)
529 AllowBlackboxMixin.__init__(self, allowBlackbox)
531 self._namespace = Namespace(self._normalizedLabel)
533 # @mustoverride
534 def IterateInstantiations(self) -> Generator[Instantiation, None, None]:
535 raise NotImplementedError()
537 # @mustoverride
538 def IndexStatement(self) -> None:
539 raise NotImplementedError()
542@export
543class IfGenerateStatement(GenerateStatement):
544 """
545 Represents an if...generate statement.
547 .. admonition:: Example
549 .. code-block:: VHDL
551 gen: if condition generate
552 -- ...
553 elsif condition generate
554 -- ...
555 else generate
556 -- ...
557 end generate;
559 .. seealso::
561 * :class:`Generate branch <pyVHDLModel.Concurrent.GenerateBranch>` base-class
562 * :class:`If-generate branch <pyVHDLModel.Concurrent.IfGenerateBranch>`
563 * :class:`Elsif-generate branch <pyVHDLModel.Concurrent.ElsifGenerateBranch>`
564 * :class:`Else-generate branch <pyVHDLModel.Concurrent.ElseGenerateBranch>`
565 """
567 _ifBranch: IfGenerateBranch
568 _elsifBranches: List[ElsifGenerateBranch]
569 _elseBranch: Nullable[ElseGenerateBranch]
571 def __init__(
572 self,
573 label: str,
574 ifBranch: IfGenerateBranch,
575 elsifBranches: Nullable[Iterable[ElsifGenerateBranch]] = None,
576 elseBranch: Nullable[ElseGenerateBranch] = None,
577 allowBlackbox: Nullable[bool] = None,
578 parent: ModelEntity = None
579 ) -> None:
580 super().__init__(label, allowBlackbox, parent)
582 self._ifBranch = ifBranch
583 ifBranch._parent = self
585 self._elsifBranches = []
586 if elsifBranches is not None:
587 for branch in elsifBranches:
588 self._elsifBranches.append(branch)
589 branch._parent = self
591 if elseBranch is not None:
592 self._elseBranch = elseBranch
593 elseBranch._parent = self
594 else:
595 self._elseBranch = None
597 @property
598 def IfBranch(self) -> IfGenerateBranch:
599 return self._ifBranch
601 @property
602 def ElsifBranches(self) -> List[ElsifGenerateBranch]:
603 return self._elsifBranches
605 @property
606 def ElseBranch(self) -> Nullable[ElseGenerateBranch]:
607 return self._elseBranch
609 def IterateInstantiations(self) -> Generator[Instantiation, None, None]:
610 yield from self._ifBranch.IterateInstantiations()
611 for branch in self._elsifBranches:
612 yield from branch.IterateInstantiations()
613 if self._elseBranch is not None:
614 yield from self._ifBranch.IterateInstantiations()
616 def IndexStatement(self) -> None:
617 self._ifBranch.IndexStatements()
618 for branch in self._elsifBranches:
619 branch.IndexStatements()
620 if self._elseBranch is not None:
621 self._elseBranch.IndexStatements()
624@export
625class ConcurrentChoice(BaseChoice):
626 """A base-class for all concurrent choices (in case...generate statements)."""
629@export
630class IndexedGenerateChoice(ConcurrentChoice):
631 _expression: ExpressionUnion
633 def __init__(self, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
634 super().__init__(parent)
636 self._expression = expression
637 expression._parent = self
639 @property
640 def Expression(self) -> ExpressionUnion:
641 return self._expression
643 def __str__(self) -> str:
644 return str(self._expression)
647@export
648class RangedGenerateChoice(ConcurrentChoice):
649 _range: 'Range'
651 def __init__(self, rng: 'Range', parent: ModelEntity = None) -> None:
652 super().__init__(parent)
654 self._range = rng
655 rng._parent = self
657 @property
658 def Range(self) -> 'Range':
659 return self._range
661 def __str__(self) -> str:
662 return str(self._range)
665@export
666class ConcurrentCase(BaseCase, LabeledEntityMixin, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin, AllowBlackboxMixin):
667 def __init__(
668 self,
669 declaredItems: Nullable[Iterable] = None,
670 statements: Nullable[Iterable[ConcurrentStatement]] = None,
671 alternativeLabel: Nullable[str] = None,
672 allowBlackbox: Nullable[bool] = None,
673 parent: ModelEntity = None
674 ) -> None:
675 super().__init__(parent)
676 LabeledEntityMixin.__init__(self, alternativeLabel)
677 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
678 ConcurrentStatementsMixin.__init__(self, statements)
679 AllowBlackboxMixin.__init__(self, allowBlackbox)
682@export
683class GenerateCase(ConcurrentCase):
684 _choices: List[ConcurrentChoice]
686 def __init__(
687 self,
688 choices: Iterable[ConcurrentChoice],
689 declaredItems: Nullable[Iterable] = None,
690 statements: Nullable[Iterable[ConcurrentStatement]] = None,
691 alternativeLabel: Nullable[str] = None,
692 allowBlackbox: Nullable[bool] = None,
693 parent: ModelEntity = None
694 ) -> None:
695 super().__init__(declaredItems, statements, alternativeLabel, allowBlackbox, parent)
697 # TODO: move to parent or grandparent
698 self._choices = []
699 if choices is not None:
700 for choice in choices:
701 self._choices.append(choice)
702 choice._parent = self
704 # TODO: move to parent or grandparent
705 @property
706 def Choices(self) -> List[ConcurrentChoice]:
707 return self._choices
709 def __str__(self) -> str:
710 return "when {choices} =>".format(choices=" | ".join(str(c) for c in self._choices))
713@export
714class OthersGenerateCase(ConcurrentCase):
715 def __str__(self) -> str:
716 return "when others =>"
719@export
720class CaseGenerateStatement(GenerateStatement):
721 """
722 Represents a case...generate statement.
724 .. admonition:: Example
726 .. code-block:: VHDL
728 gen: case selector generate
729 case choice1 =>
730 -- ...
731 case choice2 =>
732 -- ...
733 case others =>
734 -- ...
735 end generate;
736 """
738 _expression: ExpressionUnion
739 _cases: List[GenerateCase]
741 def __init__(
742 self,
743 label: str,
744 expression: ExpressionUnion,
745 cases: Iterable[ConcurrentCase],
746 allowBlackbox: Nullable[bool] = None,
747 parent: ModelEntity = None
748 ) -> None:
749 super().__init__(label, allowBlackbox, parent)
751 self._expression = expression
752 expression._parent = self
754 # TODO: create a mixin for things with cases
755 self._cases = []
756 if cases is not None:
757 for case in cases:
758 self._cases.append(case)
759 case._parent = self
761 @property
762 def SelectExpression(self) -> ExpressionUnion:
763 return self._expression
765 @property
766 def Cases(self) -> List[GenerateCase]:
767 return self._cases
769 def IterateInstantiations(self) -> Generator[Instantiation, None, None]:
770 for case in self._cases:
771 yield from case.IterateInstantiations()
773 def IndexStatement(self) -> None:
774 for case in self._cases:
775 case.IndexStatements()
778@export
779class ForGenerateStatement(GenerateStatement, ConcurrentDeclarationRegionMixin, ConcurrentStatementsMixin):
780 """
781 Represents a for...generate statement.
783 .. admonition:: Example
785 .. code-block:: VHDL
787 gen: for i in 0 to 3 generate
788 -- ...
789 end generate;
790 """
792 _loopIndex: str
793 _range: Range
795 def __init__(
796 self,
797 label: str,
798 loopIndex: str,
799 rng: Range,
800 declaredItems: Nullable[Iterable] = None,
801 statements: Nullable[Iterable[ConcurrentStatement]] = None,
802 allowBlackbox: Nullable[bool] = None,
803 parent: ModelEntity = None
804 ) -> None:
805 super().__init__(label, allowBlackbox, parent)
806 ConcurrentDeclarationRegionMixin.__init__(self, declaredItems)
807 ConcurrentStatementsMixin.__init__(self, statements)
809 self._loopIndex = loopIndex
811 self._range = rng
812 rng._parent = self
814 @property
815 def LoopIndex(self) -> str:
816 return self._loopIndex
818 @property
819 def Range(self) -> Range:
820 return self._range
822 # IndexDeclaredItems = ConcurrentStatements.IndexDeclaredItems
824 def IndexStatement(self) -> None:
825 self.IndexStatements()
827 def IndexStatements(self) -> None:
828 super().IndexStatements()
830 def IterateInstantiations(self) -> Generator[Instantiation, None, None]:
831 return ConcurrentStatementsMixin.IterateInstantiations(self)
834@export
835class ConcurrentSignalAssignment(ConcurrentStatement, SignalAssignmentMixin):
836 """
837 A base-class for concurrent signal assignments.
839 .. seealso::
841 * :class:`~pyVHDLModel.Concurrent.ConcurrentSimpleSignalAssignment`
842 * :class:`~pyVHDLModel.Concurrent.ConcurrentSelectedSignalAssignment`
843 * :class:`~pyVHDLModel.Concurrent.ConcurrentConditionalSignalAssignment`
844 """
845 def __init__(self, label: str, target: Name, parent: ModelEntity = None) -> None:
846 super().__init__(label, parent)
847 SignalAssignmentMixin.__init__(self, target)
850@export
851class ConcurrentSimpleSignalAssignment(ConcurrentSignalAssignment):
852 _waveform: List[WaveformElement]
854 def __init__(self, label: str, target: Name, waveform: Iterable[WaveformElement], parent: ModelEntity = None) -> None:
855 super().__init__(label, target, parent)
857 # TODO: extract to mixin
858 self._waveform = []
859 if waveform is not None:
860 for waveformElement in waveform:
861 self._waveform.append(waveformElement)
862 waveformElement._parent = self
864 @property
865 def Waveform(self) -> List[WaveformElement]:
866 return self._waveform
869@export
870class ConcurrentSelectedSignalAssignment(ConcurrentSignalAssignment):
871 def __init__(self, label: str, target: Name, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
872 super().__init__(label, target, parent)
875@export
876class ConcurrentConditionalSignalAssignment(ConcurrentSignalAssignment):
877 def __init__(self, label: str, target: Name, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
878 super().__init__(label, target, parent)
881@export
882class ConcurrentAssertStatement(ConcurrentStatement, AssertStatementMixin):
883 def __init__(
884 self,
885 condition: ExpressionUnion,
886 message: ExpressionUnion,
887 severity: Nullable[ExpressionUnion] = None,
888 label: Nullable[str] = None,
889 parent: ModelEntity = None
890 ) -> None:
891 super().__init__(label, parent)
892 AssertStatementMixin.__init__(self, condition, message, severity)