aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/dom
diff options
context:
space:
mode:
Diffstat (limited to 'pyGHDL/dom')
-rw-r--r--pyGHDL/dom/Aggregates.py16
-rw-r--r--pyGHDL/dom/Attribute.py4
-rw-r--r--pyGHDL/dom/Concurrent.py791
-rw-r--r--pyGHDL/dom/DesignUnit.py168
-rw-r--r--pyGHDL/dom/Expression.py116
-rw-r--r--pyGHDL/dom/InterfaceItem.py98
-rw-r--r--pyGHDL/dom/Literal.py16
-rw-r--r--pyGHDL/dom/Misc.py4
-rw-r--r--pyGHDL/dom/Names.py12
-rw-r--r--pyGHDL/dom/NonStandard.py51
-rw-r--r--pyGHDL/dom/Object.py97
-rw-r--r--pyGHDL/dom/PSL.py1
-rw-r--r--pyGHDL/dom/Range.py7
-rw-r--r--pyGHDL/dom/Sequential.py555
-rw-r--r--pyGHDL/dom/Subprogram.py2
-rw-r--r--pyGHDL/dom/Symbol.py6
-rw-r--r--pyGHDL/dom/Type.py77
-rw-r--r--pyGHDL/dom/_Translate.py604
-rw-r--r--pyGHDL/dom/_Utils.py8
-rw-r--r--pyGHDL/dom/formatting/__init__.py32
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py330
-rw-r--r--pyGHDL/dom/requirements.txt2
22 files changed, 2595 insertions, 402 deletions
diff --git a/pyGHDL/dom/Aggregates.py b/pyGHDL/dom/Aggregates.py
index 87bc44360..dfaee9a2d 100644
--- a/pyGHDL/dom/Aggregates.py
+++ b/pyGHDL/dom/Aggregates.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: VHDL design units (e.g. context or package).
+# Package module: DOM: Aggregates.
#
# License:
# ============================================================================
@@ -41,13 +41,13 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
SimpleAggregateElement as VHDLModel_SimpleAggregateElement,
IndexedAggregateElement as VHDLModel_IndexedAggregateElement,
RangedAggregateElement as VHDLModel_RangedAggregateElement,
NamedAggregateElement as VHDLModel_NamedAggregateElement,
OthersAggregateElement as VHDLModel_OthersAggregateElement,
- Expression,
+ ExpressionUnion,
Symbol,
)
from pyGHDL.libghdl._types import Iir
@@ -59,34 +59,34 @@ __all__ = []
@export
class SimpleAggregateElement(VHDLModel_SimpleAggregateElement, DOMMixin):
- def __init__(self, node: Iir, expression: Expression):
+ def __init__(self, node: Iir, expression: ExpressionUnion):
super().__init__(expression)
DOMMixin.__init__(self, node)
@export
class IndexedAggregateElement(VHDLModel_IndexedAggregateElement, DOMMixin):
- def __init__(self, node: Iir, index: Expression, expression: Expression):
+ def __init__(self, node: Iir, index: ExpressionUnion, expression: ExpressionUnion):
super().__init__(index, expression)
DOMMixin.__init__(self, node)
@export
class RangedAggregateElement(VHDLModel_RangedAggregateElement, DOMMixin):
- def __init__(self, node: Iir, rng: Range, expression: Expression):
+ def __init__(self, node: Iir, rng: Range, expression: ExpressionUnion):
super().__init__(rng, expression)
DOMMixin.__init__(self, node)
@export
class NamedAggregateElement(VHDLModel_NamedAggregateElement, DOMMixin):
- def __init__(self, node: Iir, name: Symbol, expression: Expression):
+ def __init__(self, node: Iir, name: Symbol, expression: ExpressionUnion):
super().__init__(name, expression)
DOMMixin.__init__(self, node)
@export
class OthersAggregateElement(VHDLModel_OthersAggregateElement, DOMMixin):
- def __init__(self, node: Iir, expression: Expression):
+ def __init__(self, node: Iir, expression: ExpressionUnion):
super().__init__(expression)
DOMMixin.__init__(self, node)
diff --git a/pyGHDL/dom/Attribute.py b/pyGHDL/dom/Attribute.py
index 270f8feb3..97a01f65a 100644
--- a/pyGHDL/dom/Attribute.py
+++ b/pyGHDL/dom/Attribute.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: Interface items (e.g. generic or port)
+# Package module: DOM: Attributes.
#
# License:
# ============================================================================
@@ -34,7 +34,7 @@ from typing import List
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
Attribute as VHDLModel_Attribute,
AttributeSpecification as VHDLModel_AttributeSpecification,
Name,
diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py
new file mode 100644
index 000000000..e7162cc81
--- /dev/null
+++ b/pyGHDL/dom/Concurrent.py
@@ -0,0 +1,791 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package module: DOM: Concurrent statements.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from typing import Iterable
+
+from pydecor import export
+
+from pyGHDL.dom.Range import Range
+from pyVHDLModel.SyntaxModel import (
+ GenericAssociationItem as VHDLModel_GenericAssociationItem,
+ PortAssociationItem as VHDLModel_PortAssociationItem,
+ ParameterAssociationItem as VHDLModel_ParameterAssociationItem,
+ ComponentInstantiation as VHDLModel_ComponentInstantiation,
+ EntityInstantiation as VHDLModel_EntityInstantiation,
+ ConfigurationInstantiation as VHDLModel_ConfigurationInstantiation,
+ ConcurrentBlockStatement as VHDLModel_ConcurrentBlockStatement,
+ ProcessStatement as VHDLModel_ProcessStatement,
+ IfGenerateBranch as VHDLModel_IfGenerateBranch,
+ ElsifGenerateBranch as VHDLModel_ElsifGenerateBranch,
+ ElseGenerateBranch as VHDLModel_ElseGenerateBranch,
+ IfGenerateStatement as VHDLModel_IfGenerateStatement,
+ IndexedGenerateChoice as VHDLModel_IndexedGenerateChoice,
+ RangedGenerateChoice as VHDLModel_RangedGenerateChoice,
+ OthersGenerateCase as VHDLModel_OthersGenerateCase,
+ GenerateCase as VHDLModel_GenerateCase,
+ CaseGenerateStatement as VHDLModel_CaseGenerateStatement,
+ ForGenerateStatement as VHDLModel_ForGenerateStatement,
+ WaveformElement as VHDLModel_WaveformElement,
+ ConcurrentSimpleSignalAssignment as VHDLModel_ConcurrentSimpleSignalAssignment,
+ ConcurrentProcedureCall as VHDLModel_ConcurrentProcedureCall,
+ Name,
+ ConcurrentStatement,
+ SequentialStatement,
+ ExpressionUnion,
+ ConcurrentChoice,
+ ConcurrentCase,
+ AssociationItem,
+)
+
+from pyGHDL.libghdl import Iir, utils
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin, DOMException, Position
+from pyGHDL.dom._Utils import GetNameOfNode
+
+
+@export
+class GenericAssociationItem(VHDLModel_GenericAssociationItem, DOMMixin):
+ def __init__(
+ self, associationNode: Iir, actual: ExpressionUnion, formal: Name = None
+ ):
+ super().__init__(actual, formal)
+ DOMMixin.__init__(self, associationNode)
+
+
+@export
+class PortAssociationItem(VHDLModel_PortAssociationItem, DOMMixin):
+ def __init__(
+ self, associationNode: Iir, actual: ExpressionUnion, formal: Name = None
+ ):
+ super().__init__(actual, formal)
+ DOMMixin.__init__(self, associationNode)
+
+
+@export
+class ParameterAssociationItem(VHDLModel_ParameterAssociationItem, DOMMixin):
+ def __init__(
+ self, associationNode: Iir, actual: ExpressionUnion, formal: Name = None
+ ):
+ super().__init__(actual, formal)
+ DOMMixin.__init__(self, associationNode)
+
+
+@export
+class ComponentInstantiation(VHDLModel_ComponentInstantiation, DOMMixin):
+ def __init__(
+ self,
+ instantiationNode: Iir,
+ label: str,
+ componentName: Name,
+ genericAssociations: Iterable[AssociationItem] = None,
+ portAssociations: Iterable[AssociationItem] = None,
+ ):
+ super().__init__(label, componentName, genericAssociations, portAssociations)
+ DOMMixin.__init__(self, instantiationNode)
+
+ @classmethod
+ def parse(
+ cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str
+ ) -> "ComponentInstantiation":
+ from pyGHDL.dom._Translate import (
+ GetNameFromNode,
+ GetGenericMapAspect,
+ GetPortMapAspect,
+ )
+
+ componentName = GetNameFromNode(instantiatedUnit)
+ genericAssociations = GetGenericMapAspect(
+ nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)
+ )
+ portAssociations = GetPortMapAspect(
+ nodes.Get_Port_Map_Aspect_Chain(instantiationNode)
+ )
+
+ return cls(
+ instantiationNode,
+ label,
+ componentName,
+ genericAssociations,
+ portAssociations,
+ )
+
+
+@export
+class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin):
+ def __init__(
+ self,
+ instantiationNode: Iir,
+ label: str,
+ entityName: Name,
+ architectureName: Name = None,
+ genericAssociations: Iterable[AssociationItem] = None,
+ portAssociations: Iterable[AssociationItem] = None,
+ ):
+ super().__init__(
+ label, entityName, architectureName, genericAssociations, portAssociations
+ )
+ DOMMixin.__init__(self, instantiationNode)
+
+ @classmethod
+ def parse(
+ cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str
+ ) -> "EntityInstantiation":
+ from pyGHDL.dom._Translate import (
+ GetNameFromNode,
+ GetGenericMapAspect,
+ GetPortMapAspect,
+ )
+
+ entityId = nodes.Get_Entity_Name(instantiatedUnit)
+ entityName = GetNameFromNode(entityId)
+
+ architectureName = None
+ architectureId = nodes.Get_Architecture(instantiatedUnit)
+ if architectureId != nodes.Null_Iir:
+ architectureName = GetNameOfNode(architectureId)
+
+ genericAssociations = GetGenericMapAspect(
+ nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)
+ )
+ portAssociations = GetPortMapAspect(
+ nodes.Get_Port_Map_Aspect_Chain(instantiationNode)
+ )
+
+ return cls(
+ instantiationNode,
+ label,
+ entityName,
+ architectureName,
+ genericAssociations,
+ portAssociations,
+ )
+
+
+@export
+class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin):
+ def __init__(
+ self,
+ instantiationNode: Iir,
+ label: str,
+ configurationName: Name,
+ genericAssociations: Iterable[AssociationItem] = None,
+ portAssociations: Iterable[AssociationItem] = None,
+ ):
+ super().__init__(
+ label, configurationName, genericAssociations, portAssociations
+ )
+ DOMMixin.__init__(self, instantiationNode)
+
+ @classmethod
+ def parse(
+ cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str
+ ) -> "ConfigurationInstantiation":
+ from pyGHDL.dom._Translate import (
+ GetNameFromNode,
+ GetGenericMapAspect,
+ GetPortMapAspect,
+ )
+
+ configurationId = nodes.Get_Configuration_Name(instantiatedUnit)
+ configurationName = GetNameFromNode(configurationId)
+
+ genericAssociations = GetGenericMapAspect(
+ nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)
+ )
+ portAssociations = GetPortMapAspect(
+ nodes.Get_Port_Map_Aspect_Chain(instantiationNode)
+ )
+
+ return cls(
+ instantiationNode,
+ label,
+ configurationName,
+ genericAssociations,
+ portAssociations,
+ )
+
+
+@export
+class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin):
+ def __init__(
+ self,
+ blockNode: Iir,
+ label: str,
+ declaredItems: Iterable = None,
+ statements: Iterable["ConcurrentStatement"] = None,
+ ):
+ super().__init__(label, None, declaredItems, statements)
+ DOMMixin.__init__(self, blockNode)
+
+ @classmethod
+ def parse(cls, blockNode: Iir, label: str) -> "ConcurrentBlockStatement":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ )
+
+ # genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode))
+ # portAssociations = GetPortMapAspect(nodes.Get_Port_Map_Aspect_Chain(instantiationNode))
+
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(blockNode), "block", label
+ )
+ statements = GetConcurrentStatementsFromChainedNodes(
+ nodes.Get_Concurrent_Statement_Chain(blockNode), "block", label
+ )
+
+ return cls(blockNode, label, declaredItems, statements)
+
+
+@export
+class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin):
+ def __init__(
+ self,
+ processNode: Iir,
+ label: str = None,
+ declaredItems: Iterable = None,
+ statements: Iterable[SequentialStatement] = None,
+ sensitivityList: Iterable[Name] = None,
+ ):
+ super().__init__(label, declaredItems, statements, sensitivityList)
+ DOMMixin.__init__(self, processNode)
+
+ @classmethod
+ def parse(
+ cls, processNode: Iir, label: str, hasSensitivityList: bool
+ ) -> "ProcessStatement":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetSequentialStatementsFromChainedNodes,
+ )
+
+ sensitivityList = None
+ if hasSensitivityList:
+ pass
+ # FIXME: sensitity list
+ # sensitivityListNode = nodes.Get_Sensitivity_List(processNode)
+ # print("sensi", GetIirKindOfNode(sensitivityListNode))
+
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(processNode), "process", label
+ )
+ statements = GetSequentialStatementsFromChainedNodes(
+ nodes.Get_Sequential_Statement_Chain(processNode), "process", label
+ )
+
+ return cls(processNode, label, declaredItems, statements, sensitivityList)
+
+
+@export
+class IfGenerateBranch(VHDLModel_IfGenerateBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ condition: ExpressionUnion,
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ alternativeLabel: str = None,
+ ):
+ super().__init__(condition, declaredItems, statements, alternativeLabel)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir) -> "IfGenerateBranch":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ GetExpressionFromNode,
+ )
+
+ condition = GetExpressionFromNode(nodes.Get_Condition(generateNode))
+ body = nodes.Get_Generate_Statement_Body(generateNode)
+
+ # TODO: alternative label
+ # alternativeLabelId = nodes.Get_Alternative_Label(body)
+ alternativeLabel = ""
+
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "if-generate branch", alternativeLabel
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "if-generate branch", alternativeLabel
+ )
+
+ return cls(generateNode, condition, declaredItems, statements, alternativeLabel)
+
+
+@export
+class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ condition: ExpressionUnion,
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ alternativeLabel: str = None,
+ ):
+ super().__init__(condition, declaredItems, statements, alternativeLabel)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir, condition: Iir) -> "ElsifGenerateBranch":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ GetExpressionFromNode,
+ )
+
+ condition = GetExpressionFromNode(condition)
+ body = nodes.Get_Generate_Statement_Body(generateNode)
+
+ # TODO: alternative label
+ # alternativeLabelId = nodes.Get_Alternative_Label(body)
+ alternativeLabel = ""
+
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "elsif-generate branch", alternativeLabel
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "elsif-generate branch", alternativeLabel
+ )
+
+ return cls(generateNode, condition, declaredItems, statements, alternativeLabel)
+
+
+@export
+class ElseGenerateBranch(VHDLModel_ElseGenerateBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ alternativeLabel: str = None,
+ ):
+ super().__init__(declaredItems, statements, alternativeLabel)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir) -> "ElseGenerateBranch":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ )
+
+ body = nodes.Get_Generate_Statement_Body(generateNode)
+
+ # TODO: alternative label
+ # alternativeLabelId = nodes.Get_Alternative_Label(body)
+ alternativeLabel = ""
+
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "else-generate branch", alternativeLabel
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "else-generate branch", alternativeLabel
+ )
+
+ return cls(generateNode, declaredItems, statements, alternativeLabel)
+
+
+@export
+class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin):
+ def __init__(
+ self,
+ generateNode: Iir,
+ label: str,
+ ifBranch: IfGenerateBranch,
+ elsifBranches: Iterable[ElsifGenerateBranch] = None,
+ elseBranch: ElseGenerateBranch = None,
+ ):
+ super().__init__(label, ifBranch, elsifBranches, elseBranch)
+ DOMMixin.__init__(self, generateNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir, label: str) -> "IfGenerateStatement":
+ ifBranch = IfGenerateBranch.parse(generateNode)
+ elsifBranches = []
+ elseBranch = None
+ # WORKAROUND: Python 3.8 syntax
+ # elseClause = generateNode
+ # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir:
+ elseClause = nodes.Get_Generate_Else_Clause(generateNode)
+ while elseClause != nodes.Null_Iir:
+ condition = nodes.Get_Condition(elseClause)
+ if condition != nodes.Null_Iir:
+ elsifBranches.append(ElsifGenerateBranch.parse(elseClause, condition))
+ else:
+ elseBranch = ElseGenerateBranch.parse(elseClause)
+ break
+
+ elseClause = nodes.Get_Generate_Else_Clause(elseClause)
+
+ return cls(generateNode, label, ifBranch, elsifBranches, elseBranch)
+
+
+@export
+class IndexedGenerateChoice(VHDLModel_IndexedGenerateChoice, DOMMixin):
+ def __init__(self, node: Iir, expression: ExpressionUnion):
+ super().__init__(expression)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class RangedGenerateChoice(VHDLModel_RangedGenerateChoice, DOMMixin):
+ def __init__(self, node: Iir, rng: Range):
+ super().__init__(rng)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class GenerateCase(VHDLModel_GenerateCase, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ choices: Iterable[ConcurrentChoice],
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ alternativeLabel: str = None,
+ ):
+ super().__init__(choices, declaredItems, statements, alternativeLabel)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(
+ cls, caseNode: Iir, choices: Iterable[ConcurrentChoice]
+ ) -> "GenerateCase":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ )
+
+ body = nodes.Get_Associated_Block(caseNode)
+
+ # TODO: alternative label
+ # alternativeLabelId = nodes.Get_Alternative_Label(body)
+ alternativeLabel = ""
+
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "generate case", alternativeLabel
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "generate case", alternativeLabel
+ )
+
+ return cls(caseNode, choices, declaredItems, statements, alternativeLabel)
+
+
+@export
+class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin):
+ def __init__(
+ self,
+ caseNode: Iir,
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ alternativeLabel: str = None,
+ ):
+ super().__init__(declaredItems, statements, alternativeLabel)
+ DOMMixin.__init__(self, caseNode)
+
+ @classmethod
+ def parse(cls, caseNode: Iir) -> "OthersGenerateCase":
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ )
+
+ body = nodes.Get_Associated_Block(caseNode)
+
+ # TODO: alternative label
+ # alternativeLabelId = nodes.Get_Alternative_Label(body)
+ alternativeLabel = ""
+
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "case-generate others", alternativeLabel
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "case-generate others", alternativeLabel
+ )
+
+ return cls(caseNode, declaredItems, statements, alternativeLabel)
+
+
+@export
+class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin):
+ def __init__(
+ self,
+ generateNode: Iir,
+ label: str,
+ expression: ExpressionUnion,
+ cases: Iterable[ConcurrentCase],
+ ):
+ super().__init__(label, expression, cases)
+ DOMMixin.__init__(self, generateNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+ from pyGHDL.dom._Translate import (
+ GetExpressionFromNode,
+ GetRangeFromNode,
+ GetNameFromNode,
+ )
+
+ expression = GetExpressionFromNode(nodes.Get_Expression(generateNode))
+
+ cases = []
+ choices = None
+ alternative = nodes.Get_Case_Statement_Alternative_Chain(generateNode)
+ caseNode = alternative
+
+ while alternative != nodes.Null_Iir:
+ choiceKind = GetIirKindOfNode(alternative)
+ sameAlternative = nodes.Get_Same_Alternative_Flag(alternative)
+
+ if choiceKind in (
+ nodes.Iir_Kind.Choice_By_Name,
+ nodes.Iir_Kind.Choice_By_Expression,
+ ):
+ choiceExpression = GetExpressionFromNode(
+ nodes.Get_Choice_Expression(alternative)
+ )
+
+ choice = IndexedGenerateChoice(alternative, choiceExpression)
+ if sameAlternative:
+ choices.append(choice)
+ alternative = nodes.Get_Chain(alternative)
+ continue
+ elif choiceKind is nodes.Iir_Kind.Choice_By_Range:
+ choiceRange = nodes.Get_Choice_Range(alternative)
+ choiceRangeKind = GetIirKindOfNode(choiceRange)
+ if choiceRangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(choiceRange)
+ elif choiceRangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(choiceRange)
+ else:
+ pos = Position.parse(alternative)
+ raise DOMException(
+ "Unknown choice range kind '{kind}' in case...generate statement at line {line}.".format(
+ kind=choiceRangeKind.name, line=pos.Line
+ )
+ )
+
+ choice = RangedGenerateChoice(alternative, rng)
+ if sameAlternative:
+ choices.append(choice)
+ alternative = nodes.Get_Chain(alternative)
+ continue
+ elif choiceKind is nodes.Iir_Kind.Choice_By_Others:
+ if choices is not None:
+ cases.append(GenerateCase.parse(alternative, choices))
+ choices = None
+ cases.append(OthersGenerateCase.parse(alternative))
+ alternative = nodes.Get_Chain(alternative)
+ caseNode = alternative
+ continue
+ else:
+ pos = Position.parse(alternative)
+ raise DOMException(
+ "Unknown choice kind '{kind}' in case...generate statement at line {line}.".format(
+ kind=choiceKind.name, line=pos.Line
+ )
+ )
+
+ if choices is not None:
+ cases.append(GenerateCase.parse(caseNode, choices))
+
+ caseNode = alternative
+ choices = [
+ choice,
+ ]
+
+ alternative = nodes.Get_Chain(alternative)
+
+ if choices is not None:
+ cases.append(GenerateCase.parse(caseNode, choices))
+
+ return cls(generateNode, label, expression, cases)
+
+
+@export
+class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin):
+ def __init__(
+ self,
+ generateNode: Iir,
+ label: str,
+ loopIndex: str,
+ rng: Range,
+ declaredItems: Iterable = None,
+ statements: Iterable[ConcurrentStatement] = None,
+ ):
+ super().__init__(label, loopIndex, rng, declaredItems, statements)
+ DOMMixin.__init__(self, generateNode)
+
+ @classmethod
+ def parse(cls, generateNode: Iir, label: str) -> "ForGenerateStatement":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+ from pyGHDL.dom._Translate import (
+ GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
+ GetRangeFromNode,
+ GetNameFromNode,
+ )
+
+ spec = nodes.Get_Parameter_Specification(generateNode)
+ loopIndex = GetNameOfNode(spec)
+
+ discreteRange = nodes.Get_Discrete_Range(spec)
+ rangeKind = GetIirKindOfNode(discreteRange)
+ if rangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(discreteRange)
+ elif rangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(discreteRange)
+ else:
+ pos = Position.parse(generateNode)
+ raise DOMException(
+ "Unknown discete range kind '{kind}' in for...generate statement at line {line}.".format(
+ kind=rangeKind.name, line=pos.Line
+ )
+ )
+
+ body = nodes.Get_Generate_Statement_Body(generateNode)
+ declarationChain = nodes.Get_Declaration_Chain(body)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ declarationChain, "for-generate", label
+ )
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetConcurrentStatementsFromChainedNodes(
+ statementChain, "for-generate", label
+ )
+
+ return cls(generateNode, label, loopIndex, rng, declaredItems, statements)
+
+
+@export
+class WaveformElement(VHDLModel_WaveformElement, DOMMixin):
+ def __init__(
+ self, waveNode: Iir, expression: ExpressionUnion, after: ExpressionUnion
+ ):
+ super().__init__(expression, after)
+ DOMMixin.__init__(self, waveNode)
+
+ @classmethod
+ def parse(cls, waveNode: Iir):
+ from pyGHDL.dom._Translate import GetExpressionFromNode
+
+ value = GetExpressionFromNode(nodes.Get_We_Value(waveNode))
+
+ timeNode = nodes.Get_Time(waveNode)
+ if timeNode is nodes.Null_Iir:
+ time = None
+ else:
+ time = GetExpressionFromNode(timeNode)
+
+ return cls(waveNode, value, time)
+
+
+@export
+class ConcurrentSimpleSignalAssignment(
+ VHDLModel_ConcurrentSimpleSignalAssignment, DOMMixin
+):
+ def __init__(
+ self,
+ assignmentNode: Iir,
+ label: str,
+ target: Name,
+ waveform: Iterable[WaveformElement],
+ ):
+ super().__init__(label, target, waveform)
+ DOMMixin.__init__(self, assignmentNode)
+
+ @classmethod
+ def parse(
+ cls, assignmentNode: Iir, label: str
+ ) -> "ConcurrentSimpleSignalAssignment":
+ from pyGHDL.dom._Translate import GetNameFromNode
+
+ target = nodes.Get_Target(assignmentNode)
+ targetName = GetNameFromNode(target)
+
+ waveform = []
+ for wave in utils.chain_iter(nodes.Get_Waveform_Chain(assignmentNode)):
+ waveform.append(WaveformElement.parse(wave))
+
+ return cls(assignmentNode, label, targetName, waveform)
+
+
+@export
+class ConcurrentProcedureCall(VHDLModel_ConcurrentProcedureCall, DOMMixin):
+ def __init__(
+ self,
+ callNode: Iir,
+ label: str,
+ procedureName: Name,
+ parameterMappings: Iterable,
+ ):
+ super().__init__(label, procedureName, parameterMappings)
+ DOMMixin.__init__(self, callNode)
+
+ @classmethod
+ def parse(cls, concurrentCallNode: Iir, label: str) -> "ConcurrentProcedureCall":
+ from pyGHDL.dom._Translate import GetNameFromNode, GetParameterMapAspect
+
+ callNode = nodes.Get_Procedure_Call(concurrentCallNode)
+
+ prefix = nodes.Get_Prefix(callNode)
+ procedureName = GetNameFromNode(prefix)
+ parameterAssociations = GetParameterMapAspect(
+ nodes.Get_Parameter_Association_Chain(callNode)
+ )
+
+ return cls(concurrentCallNode, label, procedureName, parameterAssociations)
diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py
index d5bf161fd..3fe8f74bf 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -39,12 +39,15 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
-from typing import List
+from typing import Iterable
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel import ContextUnion, EntityOrSymbol
+from pyVHDLModel.SyntaxModel import (
+ LibraryClause as VHDLModel_LibraryClause,
UseClause as VHDLModel_UseClause,
+ ContextReference as VHDLModel_ContextReference,
Entity as VHDLModel_Entity,
Architecture as VHDLModel_Architecture,
Package as VHDLModel_Package,
@@ -55,20 +58,22 @@ from pyVHDLModel.VHDLModel import (
Component as VHDLModel_Component,
GenericInterfaceItem,
PortInterfaceItem,
- EntityOrSymbol,
Name,
ConcurrentStatement,
)
+from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.dom import DOMMixin
+from pyGHDL.dom import DOMMixin, Position, DOMException
from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom._Translate import (
GetGenericsFromChainedNodes,
GetPortsFromChainedNodes,
GetDeclaredItemsFromChainedNodes,
+ GetConcurrentStatementsFromChainedNodes,
)
+from pyGHDL.dom.Names import SimpleName
from pyGHDL.dom.Symbol import EntitySymbol
@@ -76,19 +81,44 @@ __all__ = []
@export
+class LibraryClause(VHDLModel_LibraryClause, DOMMixin):
+ def __init__(self, libraryNode: Iir, names: Iterable[Name]):
+ super().__init__(names)
+ DOMMixin.__init__(self, libraryNode)
+
+
+@export
class UseClause(VHDLModel_UseClause, DOMMixin):
- def __init__(self, node: Iir, name: str):
- super().__init__(name)
- DOMMixin.__init__(self, node)
+ def __init__(self, useNode: Iir, names: Iterable[Name]):
+ super().__init__(names)
+ DOMMixin.__init__(self, useNode)
@classmethod
def parse(cls, useNode: Iir):
from pyGHDL.dom._Translate import GetNameFromNode
- selectedName = nodes.Get_Selected_Name(useNode)
- name = GetNameFromNode(selectedName)
+ uses = [GetNameFromNode(nodes.Get_Selected_Name(useNode))]
+ for use in utils.chain_iter(nodes.Get_Use_Clause_Chain(useNode)):
+ uses.append(GetNameFromNode(nodes.Get_Selected_Name(use)))
- return cls(useNode, name)
+ return cls(useNode, uses)
+
+
+@export
+class ContextReference(VHDLModel_ContextReference, DOMMixin):
+ def __init__(self, contextNode: Iir, names: Iterable[Name]):
+ super().__init__(names)
+ DOMMixin.__init__(self, contextNode)
+
+ @classmethod
+ def parse(cls, contextNode: Iir):
+ from pyGHDL.dom._Translate import GetNameFromNode
+
+ contexts = [GetNameFromNode(nodes.Get_Selected_Name(contextNode))]
+ for context in utils.chain_iter(nodes.Get_Context_Reference_Chain(contextNode)):
+ contexts.append(GetNameFromNode(nodes.Get_Selected_Name(context)))
+
+ return cls(contextNode, contexts)
@export
@@ -97,25 +127,34 @@ class Entity(VHDLModel_Entity, DOMMixin):
self,
node: Iir,
identifier: str,
- genericItems: List[GenericInterfaceItem] = None,
- portItems: List[PortInterfaceItem] = None,
- declaredItems: List = None,
- bodyItems: List["ConcurrentStatement"] = None,
+ contextItems: Iterable[ContextUnion] = None,
+ genericItems: Iterable[GenericInterfaceItem] = None,
+ portItems: Iterable[PortInterfaceItem] = None,
+ declaredItems: Iterable = None,
+ statements: Iterable["ConcurrentStatement"] = None,
):
- super().__init__(identifier, genericItems, portItems, declaredItems, bodyItems)
+ super().__init__(
+ identifier, contextItems, genericItems, portItems, declaredItems, statements
+ )
DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, entityNode: Iir):
+ def parse(cls, entityNode: Iir, contextItems: Iterable[ContextUnion]):
name = GetNameOfNode(entityNode)
generics = GetGenericsFromChainedNodes(nodes.Get_Generic_Chain(entityNode))
ports = GetPortsFromChainedNodes(nodes.Get_Port_Chain(entityNode))
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(entityNode), "entity", name
)
- bodyItems = []
+ statements = GetConcurrentStatementsFromChainedNodes(
+ nodes.Get_Concurrent_Statement_Chain(entityNode), "entity", name
+ )
- return cls(entityNode, name, generics, ports, declaredItems, bodyItems)
+ # FIXME: read use clauses
+
+ return cls(
+ entityNode, name, contextItems, generics, ports, declaredItems, statements
+ )
@export
@@ -125,27 +164,31 @@ class Architecture(VHDLModel_Architecture, DOMMixin):
node: Iir,
identifier: str,
entity: EntityOrSymbol,
- declaredItems: List = None,
- bodyItems: List["ConcurrentStatement"] = None,
+ contextItems: Iterable[ContextUnion] = None,
+ declaredItems: Iterable = None,
+ statements: Iterable["ConcurrentStatement"] = None,
):
- super().__init__(identifier, entity, declaredItems, bodyItems)
+ super().__init__(identifier, entity, contextItems, declaredItems, statements)
DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, architectureNode: Iir):
+ def parse(cls, architectureNode: Iir, contextItems: Iterable[ContextUnion]):
name = GetNameOfNode(architectureNode)
entityNameNode = nodes.Get_Entity_Name(architectureNode)
entityName = GetNameOfNode(entityNameNode)
- entity = EntitySymbol(entityNameNode, entityName)
+ entity = EntitySymbol(entityNameNode, SimpleName(entityNameNode, entityName))
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(architectureNode), "architecture", name
)
- bodyItems = []
+ statements = GetConcurrentStatementsFromChainedNodes(
+ nodes.Get_Concurrent_Statement_Chain(architectureNode), "architecture", name
+ )
- return cls(architectureNode, name, entity, declaredItems, bodyItems)
+ # FIXME: read use clauses
- def resolve(self):
- pass
+ return cls(
+ architectureNode, name, entity, contextItems, declaredItems, statements
+ )
@export
@@ -154,8 +197,8 @@ class Component(VHDLModel_Component, DOMMixin):
self,
node: Iir,
identifier: str,
- genericItems: List[GenericInterfaceItem] = None,
- portItems: List[PortInterfaceItem] = None,
+ genericItems: Iterable[GenericInterfaceItem] = None,
+ portItems: Iterable[PortInterfaceItem] = None,
):
super().__init__(identifier, genericItems, portItems)
DOMMixin.__init__(self, node)
@@ -175,14 +218,15 @@ class Package(VHDLModel_Package, DOMMixin):
self,
node: Iir,
identifier: str,
- genericItems: List[GenericInterfaceItem] = None,
- declaredItems: List = None,
+ contextItems: Iterable[ContextUnion] = None,
+ genericItems: Iterable[GenericInterfaceItem] = None,
+ declaredItems: Iterable = None,
):
- super().__init__(identifier, genericItems, declaredItems)
+ super().__init__(identifier, contextItems, genericItems, declaredItems)
DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, packageNode: Iir):
+ def parse(cls, packageNode: Iir, contextItems: Iterable[ContextUnion]):
name = GetNameOfNode(packageNode)
packageHeader = nodes.Get_Package_Header(packageNode)
@@ -197,7 +241,9 @@ class Package(VHDLModel_Package, DOMMixin):
nodes.Get_Declaration_Chain(packageNode), "package", name
)
- return cls(packageNode, name, generics, declaredItems)
+ # FIXME: read use clauses
+
+ return cls(packageNode, name, contextItems, generics, declaredItems)
@export
@@ -206,19 +252,22 @@ class PackageBody(VHDLModel_PackageBody, DOMMixin):
self,
node: Iir,
identifier: str,
- declaredItems: List = None,
+ contextItems: Iterable[ContextUnion] = None,
+ declaredItems: Iterable = None,
):
- super().__init__(identifier, declaredItems)
+ super().__init__(identifier, contextItems, declaredItems)
DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, packageBodyNode: Iir):
+ def parse(cls, packageBodyNode: Iir, contextItems: Iterable[ContextUnion]):
name = GetNameOfNode(packageBodyNode)
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(packageBodyNode), "package", name
)
- return cls(packageBodyNode, name, declaredItems)
+ # FIXME: read use clauses
+
+ return cls(packageBodyNode, name, contextItems, declaredItems)
@export
@@ -238,8 +287,10 @@ class PackageInstantiation(VHDLModel_PackageInstantiation, DOMMixin):
name = GetNameOfNode(packageNode)
uninstantiatedPackageName = nodes.Get_Uninstantiated_Package_Name(packageNode)
+ # FIXME: read use clauses (does it apply here too?)
# FIXME: read generics
# FIXME: read generic map
+ # genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode))
return cls(packageNode, name, uninstantiatedPackageName)
@@ -250,17 +301,40 @@ class Context(VHDLModel_Context, DOMMixin):
self,
node: Iir,
identifier: str,
+ libraryReferences: Iterable[LibraryClause] = None,
+ packageReferences: Iterable[UseClause] = None,
):
- super().__init__(identifier)
+ super().__init__(identifier, libraryReferences, packageReferences)
DOMMixin.__init__(self, node)
@classmethod
def parse(cls, contextNode: Iir):
- name = GetNameOfNode(contextNode)
+ from pyGHDL.dom._Utils import GetIirKindOfNode
- # FIXME: read use clauses
+ name = GetNameOfNode(contextNode)
- return cls(contextNode, name)
+ items = []
+ names = []
+ for item in utils.chain_iter(nodes.Get_Context_Items(contextNode)):
+ kind = GetIirKindOfNode(item)
+ if kind is nodes.Iir_Kind.Library_Clause:
+ names.append(SimpleName(item, GetNameOfNode(item)))
+ if nodes.Get_Has_Identifier_List(item):
+ continue
+
+ items.append(LibraryClause(item, names))
+ names = []
+ elif kind is nodes.Iir_Kind.Use_Clause:
+ items.append(UseClause.parse(item))
+ else:
+ pos = Position.parse(item)
+ raise DOMException(
+ "Unknown context item kind '{kind}' in context at line {line}.".format(
+ kind=kind.name, line=pos.Line
+ )
+ )
+
+ return cls(contextNode, name, items)
@export
@@ -269,14 +343,16 @@ class Configuration(VHDLModel_Configuration, DOMMixin):
self,
node: Iir,
identifier: str,
+ contextItems: Iterable[Context] = None,
):
- super().__init__(identifier)
+ super().__init__(identifier, contextItems)
DOMMixin.__init__(self, node)
@classmethod
- def parse(cls, configurationNode: Iir):
+ def parse(cls, configurationNode: Iir, contextItems: Iterable[Context]):
name = GetNameOfNode(configurationNode)
- # FIXME: needs an implementation
+ # FIXME: read use clauses
+ # FIXME: read specifications
- return cls(configurationNode, name)
+ return cls(configurationNode, name, contextItems)
diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py
index 972b86ced..ce5945d46 100644
--- a/pyGHDL/dom/Expression.py
+++ b/pyGHDL/dom/Expression.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: Interface items (e.g. generic or port)
+# Package module: DOM: Expressions.
#
# License:
# ============================================================================
@@ -34,8 +34,7 @@ from typing import List, Union
from pydecor import export
-from pyGHDL.dom import DOMMixin, DOMException
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
UnaryExpression as VHDLModel_UnaryExpression,
BinaryExpression as VHDLModel_BinaryExpression,
InverseExpression as VHDLModel_InverseExpression,
@@ -84,7 +83,7 @@ from pyVHDLModel.VHDLModel import (
SubtypeAllocation as VHDLModel_SubtypeAllocation,
QualifiedExpressionAllocation as VHDLModel_QualifiedExpressionAllocation,
Aggregate as VHDLModel_Aggregate,
- Expression,
+ ExpressionUnion,
AggregateElement,
SubtypeOrSymbol,
Symbol,
@@ -93,6 +92,7 @@ from pyVHDLModel.VHDLModel import (
from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin, DOMException, Position
from pyGHDL.dom._Utils import GetIirKindOfNode
from pyGHDL.dom.Symbol import SimpleSubtypeSymbol
from pyGHDL.dom.Aggregates import (
@@ -130,7 +130,7 @@ class _ParseBinaryExpressionMixin:
class InverseExpression(
VHDLModel_InverseExpression, DOMMixin, _ParseUnaryExpressionMixin
):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@@ -139,7 +139,7 @@ class InverseExpression(
class IdentityExpression(
VHDLModel_IdentityExpression, DOMMixin, _ParseUnaryExpressionMixin
):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@@ -148,7 +148,7 @@ class IdentityExpression(
class NegationExpression(
VHDLModel_NegationExpression, DOMMixin, _ParseUnaryExpressionMixin
):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@@ -157,7 +157,7 @@ class NegationExpression(
class AbsoluteExpression(
VHDLModel_AbsoluteExpression, DOMMixin, _ParseUnaryExpressionMixin
):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@@ -166,7 +166,7 @@ class AbsoluteExpression(
class ParenthesisExpression(
VHDLModel_ParenthesisExpression, DOMMixin, _ParseUnaryExpressionMixin
):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@@ -180,14 +180,14 @@ class ParenthesisExpression(
@export
class TypeConversion(VHDLModel_TypeConversion, DOMMixin):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__(operand)
DOMMixin.__init__(self, node)
@export
class FunctionCall(VHDLModel_FunctionCall, DOMMixin):
- def __init__(self, node: Iir, operand: Expression):
+ def __init__(self, node: Iir, operand: ExpressionUnion):
super().__init__()
DOMMixin.__init__(self, node)
@@ -211,14 +211,14 @@ class RangeExpression(VHDLModel_RangeExpression, DOMMixin):
@export
class AscendingRangeExpression(VHDLModel_AscendingRangeExpression, DOMMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class DescendingRangeExpression(VHDLModel_DescendingRangeExpression, DOMMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -227,7 +227,7 @@ class DescendingRangeExpression(VHDLModel_DescendingRangeExpression, DOMMixin):
class AdditionExpression(
VHDLModel_AdditionExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -236,7 +236,7 @@ class AdditionExpression(
class SubtractionExpression(
VHDLModel_SubtractionExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -245,7 +245,7 @@ class SubtractionExpression(
class ConcatenationExpression(
VHDLModel_ConcatenationExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -254,7 +254,7 @@ class ConcatenationExpression(
class MultiplyExpression(
VHDLModel_MultiplyExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -263,7 +263,7 @@ class MultiplyExpression(
class DivisionExpression(
VHDLModel_DivisionExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -272,7 +272,7 @@ class DivisionExpression(
class RemainderExpression(
VHDLModel_RemainderExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -281,7 +281,7 @@ class RemainderExpression(
class ModuloExpression(
VHDLModel_ModuloExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -290,56 +290,56 @@ class ModuloExpression(
class ExponentiationExpression(
VHDLModel_ExponentiationExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class AndExpression(VHDLModel_AndExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class NandExpression(VHDLModel_NandExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class OrExpression(VHDLModel_OrExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class NorExpression(VHDLModel_NorExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class XorExpression(VHDLModel_XorExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class XnorExpression(VHDLModel_XnorExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class EqualExpression(VHDLModel_EqualExpression, DOMMixin, _ParseBinaryExpressionMixin):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -348,7 +348,7 @@ class EqualExpression(VHDLModel_EqualExpression, DOMMixin, _ParseBinaryExpressio
class UnequalExpression(
VHDLModel_UnequalExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -357,7 +357,7 @@ class UnequalExpression(
class LessThanExpression(
VHDLModel_LessThanExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -366,7 +366,7 @@ class LessThanExpression(
class LessEqualExpression(
VHDLModel_LessEqualExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -375,7 +375,7 @@ class LessEqualExpression(
class GreaterThanExpression(
VHDLModel_GreaterThanExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -384,7 +384,7 @@ class GreaterThanExpression(
class GreaterEqualExpression(
VHDLModel_GreaterEqualExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -393,7 +393,7 @@ class GreaterEqualExpression(
class MatchingEqualExpression(
VHDLModel_MatchingEqualExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -402,7 +402,7 @@ class MatchingEqualExpression(
class MatchingUnequalExpression(
VHDLModel_MatchingUnequalExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -411,7 +411,7 @@ class MatchingUnequalExpression(
class MatchingLessThanExpression(
VHDLModel_MatchingLessThanExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -420,7 +420,7 @@ class MatchingLessThanExpression(
class MatchingLessEqualExpression(
VHDLModel_MatchingLessEqualExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -429,7 +429,7 @@ class MatchingLessEqualExpression(
class MatchingGreaterThanExpression(
VHDLModel_MatchingGreaterThanExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -438,7 +438,7 @@ class MatchingGreaterThanExpression(
class MatchingGreaterEqualExpression(
VHDLModel_MatchingGreaterEqualExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -447,7 +447,7 @@ class MatchingGreaterEqualExpression(
class ShiftRightLogicExpression(
VHDLModel_ShiftRightLogicExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -456,7 +456,7 @@ class ShiftRightLogicExpression(
class ShiftLeftLogicExpression(
VHDLModel_ShiftLeftLogicExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -465,7 +465,7 @@ class ShiftLeftLogicExpression(
class ShiftRightArithmeticExpression(
VHDLModel_ShiftRightArithmeticExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -474,7 +474,7 @@ class ShiftRightArithmeticExpression(
class ShiftLeftArithmeticExpression(
VHDLModel_ShiftLeftArithmeticExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -483,7 +483,7 @@ class ShiftLeftArithmeticExpression(
class RotateRightExpression(
VHDLModel_RotateRightExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@@ -492,14 +492,14 @@ class RotateRightExpression(
class RotateLeftExpression(
VHDLModel_RotateLeftExpression, DOMMixin, _ParseBinaryExpressionMixin
):
- def __init__(self, node: Iir, left: Expression, right: Expression):
+ def __init__(self, node: Iir, left: ExpressionUnion, right: ExpressionUnion):
super().__init__(left, right)
DOMMixin.__init__(self, node)
@export
class QualifiedExpression(VHDLModel_QualifiedExpression, DOMMixin):
- def __init__(self, node: Iir, subtype: SubtypeOrSymbol, operand: Expression):
+ def __init__(self, node: Iir, subtype: SubtypeOrSymbol, operand: ExpressionUnion):
super().__init__(subtype, operand)
DOMMixin.__init__(self, node)
@@ -570,8 +570,24 @@ class Aggregate(VHDLModel_Aggregate, DOMMixin):
index = GetExpressionFromNode(nodes.Get_Choice_Expression(item))
choices.append(IndexedAggregateElement(item, index, value))
elif kind == nodes.Iir_Kind.Choice_By_Range:
- r = GetRangeFromNode(nodes.Get_Choice_Range(item))
- choices.append(RangedAggregateElement(item, r, value))
+ choiceRange = nodes.Get_Choice_Range(item)
+ rangeKind = GetIirKindOfNode(choiceRange)
+ if rangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(choiceRange)
+ elif rangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(choiceRange)
+ else:
+ pos = Position.parse(item)
+ raise DOMException(
+ "Unknown discete range kind '{kind}' in for...generate statement at line {line}.".format(
+ kind=rangeKind.name, line=pos.Line
+ )
+ )
+
+ choices.append(RangedAggregateElement(item, rng, value))
elif kind == nodes.Iir_Kind.Choice_By_Name:
name = GetNameFromNode(nodes.Get_Choice_Name(item))
symbol = Symbol(item, name)
@@ -580,8 +596,8 @@ class Aggregate(VHDLModel_Aggregate, DOMMixin):
choices.append(OthersAggregateElement(item, value))
else:
raise DOMException(
- "Unknown choice kind '{kindName}'({kind}) in aggregate '{aggr}'.".format(
- kind=kind, kindName=kind.name, aggr=node
+ "Unknown choice kind '{kind}' in aggregate '{aggr}'.".format(
+ kind=kind.name, aggr=node
)
)
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index 4ebea735a..af1b681cd 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -30,9 +30,11 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from typing import List
+
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
GenericConstantInterfaceItem as VHDLModel_GenericConstantInterfaceItem,
GenericTypeInterfaceItem as VHDLModel_GenericTypeInterfaceItem,
GenericPackageInterfaceItem as VHDLModel_GenericPackageInterfaceItem,
@@ -45,7 +47,7 @@ from pyVHDLModel.VHDLModel import (
ParameterFileInterfaceItem as VHDLModel_ParameterFileInterfaceItem,
Mode,
SubtypeOrSymbol,
- Expression,
+ ExpressionUnion,
)
from pyGHDL.libghdl._types import Iir
@@ -63,12 +65,12 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMi
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
mode: Mode,
subtype: SubtypeOrSymbol,
- defaultExpression: Expression,
+ defaultExpression: ExpressionUnion,
):
- super().__init__(identifier, mode, subtype, defaultExpression)
+ super().__init__(identifiers, mode, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -79,7 +81,15 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMi
default = nodes.Get_Default_Value(genericNode)
value = GetExpressionFromNode(default) if default else None
- return cls(genericNode, name, mode, subtypeIndication, value)
+ return cls(
+ genericNode,
+ [
+ name,
+ ],
+ mode,
+ subtypeIndication,
+ value,
+ )
@export
@@ -155,12 +165,12 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin):
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
mode: Mode,
subtype: SubtypeOrSymbol,
- defaultExpression: Expression = None,
+ defaultExpression: ExpressionUnion = None,
):
- super().__init__(identifier, mode, subtype, defaultExpression)
+ super().__init__(identifiers, mode, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -176,7 +186,15 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin):
else None
)
- return cls(portNode, name, mode, subtypeIndication, value)
+ return cls(
+ portNode,
+ [
+ name,
+ ],
+ mode,
+ subtypeIndication,
+ value,
+ )
@export
@@ -186,12 +204,12 @@ class ParameterConstantInterfaceItem(
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
mode: Mode,
subtype: SubtypeOrSymbol,
- defaultExpression: Expression = None,
+ defaultExpression: ExpressionUnion = None,
):
- super().__init__(identifier, mode, subtype, defaultExpression)
+ super().__init__(identifiers, mode, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -209,7 +227,15 @@ class ParameterConstantInterfaceItem(
else None
)
- return cls(parameterNode, name, mode, subtypeIndication, value)
+ return cls(
+ parameterNode,
+ [
+ name,
+ ],
+ mode,
+ subtypeIndication,
+ value,
+ )
@export
@@ -219,12 +245,12 @@ class ParameterVariableInterfaceItem(
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
mode: Mode,
subtype: SubtypeOrSymbol,
- defaultExpression: Expression = None,
+ defaultExpression: ExpressionUnion = None,
):
- super().__init__(identifier, mode, subtype, defaultExpression)
+ super().__init__(identifiers, mode, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -242,7 +268,15 @@ class ParameterVariableInterfaceItem(
else None
)
- return cls(parameterNode, name, mode, subtypeIndication, value)
+ return cls(
+ parameterNode,
+ [
+ name,
+ ],
+ mode,
+ subtypeIndication,
+ value,
+ )
@export
@@ -250,12 +284,12 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
mode: Mode,
subtype: SubtypeOrSymbol,
- defaultExpression: Expression = None,
+ defaultExpression: ExpressionUnion = None,
):
- super().__init__(identifier, mode, subtype, defaultExpression)
+ super().__init__(identifiers, mode, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -273,7 +307,15 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi
else None
)
- return cls(parameterNode, name, mode, subtypeIndication, value)
+ return cls(
+ parameterNode,
+ [
+ name,
+ ],
+ mode,
+ subtypeIndication,
+ value,
+ )
@export
@@ -281,10 +323,10 @@ class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin)
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
subtype: SubtypeOrSymbol,
):
- super().__init__(identifier, subtype)
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
@@ -294,4 +336,10 @@ class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin)
parameterNode, "parameter", name
)
- return cls(parameterNode, name, subtypeIndication)
+ return cls(
+ parameterNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ )
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
index 784039d45..26be52ec8 100644
--- a/pyGHDL/dom/Literal.py
+++ b/pyGHDL/dom/Literal.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: Interface items (e.g. generic or port)
+# Package module: DOM: Literals.
#
# License:
# ============================================================================
@@ -32,7 +32,7 @@
# ============================================================================
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
NullLiteral as VHDLModel_NullLiteral,
EnumerationLiteral as VHDLModel_EnumerationLiteral,
IntegerLiteral as VHDLModel_IntegerLiteral,
@@ -42,7 +42,7 @@ from pyVHDLModel.VHDLModel import (
CharacterLiteral as VHDLModel_CharacterLiteral,
StringLiteral as VHDLModel_StringLiteral,
)
-from pyGHDL.libghdl import name_table
+from pyGHDL.libghdl import name_table, str_table
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom import DOMMixin
@@ -149,6 +149,10 @@ class StringLiteral(VHDLModel_StringLiteral, DOMMixin):
@classmethod
def parse(cls, literalNode: Iir) -> "StringLiteral":
- stringID = nodes.Get_String8_Id(literalNode)
- value = name_table.Get_Name_Ptr(stringID)
- return cls(literalNode, value)
+ if nodes.Get_Bit_String_Base(literalNode) is nodes.NumberBaseType.Base_None:
+ value = str_table.Get_String8_Ptr(
+ nodes.Get_String8_Id(literalNode), nodes.Get_String_Length(literalNode)
+ )
+ return cls(literalNode, value)
+ else:
+ print("[NOT IMPLEMENTED] Bit String Literal not supported yet")
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index b80c64a82..ddd31040a 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -37,12 +37,12 @@
"""
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
Alias as VHDLModel_Alias,
)
from pyGHDL.libghdl._types import Iir
-from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom import DOMMixin
+from pyGHDL.dom._Utils import GetNameOfNode
__all__ = []
diff --git a/pyGHDL/dom/Names.py b/pyGHDL/dom/Names.py
index e09294d40..acb9cd1d6 100644
--- a/pyGHDL/dom/Names.py
+++ b/pyGHDL/dom/Names.py
@@ -32,10 +32,9 @@
# ============================================================================
from typing import List
-from pyGHDL.libghdl._types import Iir
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
SimpleName as VHDLModel_SimpleName,
ParenthesisName as VHDLModel_ParenthesisName,
IndexedName as VHDLModel_IndexedName,
@@ -43,8 +42,10 @@ from pyVHDLModel.VHDLModel import (
SelectedName as VHDLModel_SelectedName,
AttributeName as VHDLModel_AttributeName,
AllName as VHDLModel_AllName,
+ OpenName as VHDLModel_OpenName,
Name,
)
+from pyGHDL.libghdl._types import Iir
from pyGHDL.dom import DOMMixin
__all__ = []
@@ -97,3 +98,10 @@ class AllName(VHDLModel_AllName, DOMMixin):
def __init__(self, node: Iir, prefix: Name):
super().__init__(prefix)
DOMMixin.__init__(self, node)
+
+
+@export
+class OpenName(VHDLModel_OpenName, DOMMixin):
+ def __init__(self, node: Iir):
+ super().__init__()
+ DOMMixin.__init__(self, node)
diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py
index bf48db900..1cd98b4fa 100644
--- a/pyGHDL/dom/NonStandard.py
+++ b/pyGHDL/dom/NonStandard.py
@@ -42,8 +42,8 @@ from typing import Any
from pydecor import export
-from pyGHDL.dom.PSL import VerificationUnit, VerificationProperty, VerificationMode
-from pyVHDLModel.VHDLModel import (
+from pyGHDL.dom.Names import SimpleName
+from pyVHDLModel.SyntaxModel import (
Design as VHDLModel_Design,
Library as VHDLModel_Library,
Document as VHDLModel_Document,
@@ -62,8 +62,8 @@ from pyGHDL.libghdl import (
files_map_editor,
)
from pyGHDL.libghdl.vhdl import nodes, sem_lib, parse
-from pyGHDL.dom import DOMException
-from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors
+from pyGHDL.dom import DOMException, Position
+from pyGHDL.dom._Utils import GetIirKindOfNode, CheckForErrors, GetNameOfNode
from pyGHDL.dom.DesignUnit import (
Entity,
Architecture,
@@ -72,7 +72,11 @@ from pyGHDL.dom.DesignUnit import (
Context,
Configuration,
PackageInstantiation,
+ LibraryClause,
+ UseClause,
+ ContextReference,
)
+from pyGHDL.dom.PSL import VerificationUnit, VerificationProperty, VerificationMode
__all__ = []
@@ -171,20 +175,45 @@ class Document(VHDLModel_Document):
libraryUnit = nodes.Get_Library_Unit(unit)
nodeKind = GetIirKindOfNode(libraryUnit)
+ contextItems = []
+ contextNames = []
+ context = nodes.Get_Context_Items(unit)
+ if context is not nodes.Null_Iir:
+ for item in utils.chain_iter(context):
+ itemKind = GetIirKindOfNode(item)
+ if itemKind is nodes.Iir_Kind.Library_Clause:
+ contextNames.append(SimpleName(item, GetNameOfNode(item)))
+ if nodes.Get_Has_Identifier_List(item):
+ continue
+
+ contextItems.append(LibraryClause(item, contextNames))
+ contextNames = []
+ elif itemKind is nodes.Iir_Kind.Use_Clause:
+ contextItems.append(UseClause.parse(item))
+ elif itemKind is nodes.Iir_Kind.Context_Reference:
+ contextItems.append(ContextReference.parse(item))
+ else:
+ pos = Position.parse(item)
+ raise DOMException(
+ "Unknown context item kind '{kind}' in context at line {line}.".format(
+ kind=itemKind.name, line=pos.Line
+ )
+ )
+
if nodeKind == nodes.Iir_Kind.Entity_Declaration:
- entity = Entity.parse(libraryUnit)
+ entity = Entity.parse(libraryUnit, contextItems)
self.Entities.append(entity)
elif nodeKind == nodes.Iir_Kind.Architecture_Body:
- architecture = Architecture.parse(libraryUnit)
+ architecture = Architecture.parse(libraryUnit, contextItems)
self.Architectures.append(architecture)
elif nodeKind == nodes.Iir_Kind.Package_Declaration:
- package = Package.parse(libraryUnit)
+ package = Package.parse(libraryUnit, contextItems)
self.Packages.append(package)
elif nodeKind == nodes.Iir_Kind.Package_Body:
- packageBody = PackageBody.parse(libraryUnit)
+ packageBody = PackageBody.parse(libraryUnit, contextItems)
self.PackageBodies.append(packageBody)
elif nodeKind == nodes.Iir_Kind.Package_Instantiation_Declaration:
@@ -196,7 +225,7 @@ class Document(VHDLModel_Document):
self.Contexts.append(context)
elif nodeKind == nodes.Iir_Kind.Configuration_Declaration:
- configuration = Configuration.parse(libraryUnit)
+ configuration = Configuration.parse(libraryUnit, contextItems)
self.Configurations.append(configuration)
elif nodeKind == nodes.Iir_Kind.Vunit_Declaration:
@@ -213,9 +242,7 @@ class Document(VHDLModel_Document):
else:
raise DOMException(
- "Unknown design unit kind '{kindName}'({kind}).".format(
- kindName=nodeKind.name, kind=nodeKind
- )
+ "Unknown design unit kind '{kind}'.".format(kind=nodeKind.name)
)
@property
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
index d25acb587..def09d50c 100644
--- a/pyGHDL/dom/Object.py
+++ b/pyGHDL/dom/Object.py
@@ -30,22 +30,22 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from typing import Union
+from typing import Union, List
-from pyGHDL.libghdl._types import Iir
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
Constant as VHDLModel_Constant,
DeferredConstant as VHDLModel_DeferredConstant,
Variable as VHDLModel_Variable,
SharedVariable as VHDLModel_SharedVariable,
Signal as VHDLModel_Signal,
File as VHDLModel_File,
- Expression,
+ ExpressionUnion,
SubtypeOrSymbol,
)
+from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode
@@ -58,11 +58,11 @@ class Constant(VHDLModel_Constant, DOMMixin):
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
subtype: SubtypeOrSymbol,
- defaultExpression: Expression,
+ defaultExpression: ExpressionUnion,
):
- super().__init__(identifier, subtype, defaultExpression)
+ super().__init__(identifiers, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -78,15 +78,28 @@ class Constant(VHDLModel_Constant, DOMMixin):
if defaultValue != nodes.Null_Iir:
defaultExpression = GetExpressionFromNode(defaultValue)
- return cls(constantNode, name, subtypeIndication, defaultExpression)
+ return cls(
+ constantNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ defaultExpression,
+ )
else:
- return DeferredConstant(constantNode, name, subtypeIndication)
+ return DeferredConstant(
+ constantNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ )
@export
class DeferredConstant(VHDLModel_DeferredConstant, DOMMixin):
- def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol):
- super().__init__(identifier, subtype)
+ def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol):
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
@@ -98,7 +111,13 @@ class DeferredConstant(VHDLModel_DeferredConstant, DOMMixin):
constantNode, "deferred constant", name
)
- return cls(constantNode, name, subtypeIndication)
+ return cls(
+ constantNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ )
@export
@@ -106,11 +125,11 @@ class Variable(VHDLModel_Variable, DOMMixin):
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
subtype: SubtypeOrSymbol,
- defaultExpression: Expression,
+ defaultExpression: ExpressionUnion,
):
- super().__init__(identifier, subtype, defaultExpression)
+ super().__init__(identifiers, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -127,13 +146,20 @@ class Variable(VHDLModel_Variable, DOMMixin):
if defaultValue != nodes.Null_Iir:
defaultExpression = GetExpressionFromNode(defaultValue)
- return cls(variableNode, name, subtypeIndication, defaultExpression)
+ return cls(
+ variableNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ defaultExpression,
+ )
@export
class SharedVariable(VHDLModel_SharedVariable, DOMMixin):
- def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol):
- super().__init__(identifier, subtype)
+ def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol):
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
@@ -143,7 +169,13 @@ class SharedVariable(VHDLModel_SharedVariable, DOMMixin):
name = GetNameOfNode(variableNode)
subtypeIndication = GetSubtypeIndicationFromNode(variableNode, "variable", name)
- return cls(variableNode, name, subtypeIndication)
+ return cls(
+ variableNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ )
@export
@@ -151,11 +183,11 @@ class Signal(VHDLModel_Signal, DOMMixin):
def __init__(
self,
node: Iir,
- identifier: str,
+ identifiers: List[str],
subtype: SubtypeOrSymbol,
- defaultExpression: Expression,
+ defaultExpression: ExpressionUnion,
):
- super().__init__(identifier, subtype, defaultExpression)
+ super().__init__(identifiers, subtype, defaultExpression)
DOMMixin.__init__(self, node)
@classmethod
@@ -170,13 +202,20 @@ class Signal(VHDLModel_Signal, DOMMixin):
default = nodes.Get_Default_Value(signalNode)
defaultExpression = GetExpressionFromNode(default) if default else None
- return cls(signalNode, name, subtypeIndication, defaultExpression)
+ return cls(
+ signalNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ defaultExpression,
+ )
@export
class File(VHDLModel_File, DOMMixin):
- def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol):
- super().__init__(identifier, subtype)
+ def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol):
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
@@ -188,4 +227,10 @@ class File(VHDLModel_File, DOMMixin):
# FIXME: handle file open stuff
- return cls(fileNode, name, subtypeIndication)
+ return cls(
+ fileNode,
+ [
+ name,
+ ],
+ subtypeIndication,
+ )
diff --git a/pyGHDL/dom/PSL.py b/pyGHDL/dom/PSL.py
index 6c4ba76b3..95ac72082 100644
--- a/pyGHDL/dom/PSL.py
+++ b/pyGHDL/dom/PSL.py
@@ -39,7 +39,6 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
-from pyGHDL.libghdl.vhdl import nodes
from pydecor import export
from pyVHDLModel.PSLModel import (
diff --git a/pyGHDL/dom/Range.py b/pyGHDL/dom/Range.py
index ce8dfbc40..f5153e67d 100644
--- a/pyGHDL/dom/Range.py
+++ b/pyGHDL/dom/Range.py
@@ -32,12 +32,7 @@
# ============================================================================
from pydecor import export
-from pyVHDLModel.VHDLModel import (
- Range as VHDLModel_Range,
- RangeExpression as VHDLModel_RangeExpression,
- Direction,
- Expression,
-)
+from pyVHDLModel.SyntaxModel import Range as VHDLModel_Range
__all__ = []
diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py
new file mode 100644
index 000000000..be4793b2a
--- /dev/null
+++ b/pyGHDL/dom/Sequential.py
@@ -0,0 +1,555 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package module: DOM: Sequential statements.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from typing import Iterable
+
+from pydecor import export
+
+from pyGHDL.dom.Concurrent import (
+ WaveformElement,
+ ParameterAssociationItem,
+) # TODO: move out from concurrent?
+from pyGHDL.dom.Range import Range
+from pyVHDLModel.SyntaxModel import (
+ IfBranch as VHDLModel_IfBranch,
+ ElsifBranch as VHDLModel_ElsifBranch,
+ ElseBranch as VHDLModel_ElseBranch,
+ IfStatement as VHDLModel_IfStatement,
+ IndexedChoice as VHDLModel_IndexedChoice,
+ RangedChoice as VHDLModel_RangedChoice,
+ OthersCase as VHDLModel_OthersCase,
+ Case as VHDLModel_Case,
+ CaseStatement as VHDLModel_CaseStatement,
+ ForLoopStatement as VHDLModel_ForLoopStatement,
+ SequentialSimpleSignalAssignment as VHDLModel_SequentialSimpleSignalAssignment,
+ SequentialProcedureCall as VHDLModel_SequentialProcedureCall,
+ SequentialAssertStatement as VHDLModel_SequentialAssertStatement,
+ SequentialReportStatement as VHDLModel_SequentialReportStatement,
+ WaitStatement as VHDLModel_WaitStatement,
+ Name,
+ SequentialStatement,
+ ExpressionUnion,
+ SequentialChoice,
+ SequentialCase,
+)
+
+
+from pyGHDL.libghdl import Iir, utils
+from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import DOMMixin, Position, DOMException
+from pyGHDL.dom._Utils import GetNameOfNode
+
+
+@export
+class IfBranch(VHDLModel_IfBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ condition: ExpressionUnion,
+ statements: Iterable[SequentialStatement] = None,
+ ):
+ super().__init__(condition, statements)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, branchNode: Iir, label: str) -> "IfBranch":
+ from pyGHDL.dom._Translate import (
+ GetSequentialStatementsFromChainedNodes,
+ GetExpressionFromNode,
+ )
+
+ condition = GetExpressionFromNode(nodes.Get_Condition(branchNode))
+ statementChain = nodes.Get_Sequential_Statement_Chain(branchNode)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "if branch", label
+ )
+
+ return cls(branchNode, condition, statements)
+
+
+@export
+class ElsifBranch(VHDLModel_ElsifBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ condition: ExpressionUnion,
+ statements: Iterable[SequentialStatement] = None,
+ ):
+ super().__init__(condition, statements)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, branchNode: Iir, condition: Iir, label: str) -> "ElsifBranch":
+ from pyGHDL.dom._Translate import (
+ GetSequentialStatementsFromChainedNodes,
+ GetExpressionFromNode,
+ )
+
+ condition = GetExpressionFromNode(condition)
+ statementChain = nodes.Get_Sequential_Statement_Chain(branchNode)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "elsif branch", label
+ )
+
+ return cls(branchNode, condition, statements)
+
+
+@export
+class ElseBranch(VHDLModel_ElseBranch):
+ def __init__(
+ self,
+ branchNode: Iir,
+ statements: Iterable[SequentialStatement] = None,
+ ):
+ super().__init__(statements)
+ DOMMixin.__init__(self, branchNode)
+
+ @classmethod
+ def parse(cls, branchNode: Iir, label: str) -> "ElseBranch":
+ from pyGHDL.dom._Translate import (
+ GetSequentialStatementsFromChainedNodes,
+ )
+
+ statementChain = nodes.Get_Sequential_Statement_Chain(branchNode)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "else branch", label
+ )
+
+ return cls(branchNode, statements)
+
+
+@export
+class IfStatement(VHDLModel_IfStatement, DOMMixin):
+ def __init__(
+ self,
+ ifNode: Iir,
+ ifBranch: IfBranch,
+ elsifBranches: Iterable[ElsifBranch] = None,
+ elseBranch: ElseBranch = None,
+ label: str = None,
+ ):
+ super().__init__(ifBranch, elsifBranches, elseBranch, label)
+ DOMMixin.__init__(self, ifNode)
+
+ @classmethod
+ def parse(cls, ifNode: Iir, label: str) -> "IfStatement":
+ ifBranch = IfBranch.parse(ifNode, label)
+ elsifBranches = []
+ elseBranch = None
+ # WORKAROUND: Python 3.8 syntax
+ # elseClause = generateNode
+ # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir:
+ elseClause = nodes.Get_Else_Clause(ifNode)
+ while elseClause != nodes.Null_Iir:
+ condition = nodes.Get_Condition(elseClause)
+ if condition != nodes.Null_Iir:
+ elsifBranches.append(ElsifBranch.parse(elseClause, condition, label))
+ else:
+ elseBranch = ElseBranch.parse(elseClause, label)
+ break
+
+ elseClause = nodes.Get_Else_Clause(elseClause)
+
+ return cls(ifNode, ifBranch, elsifBranches, elseBranch, label)
+
+
+@export
+class IndexedChoice(VHDLModel_IndexedChoice, DOMMixin):
+ def __init__(self, node: Iir, expression: ExpressionUnion):
+ super().__init__(expression)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class RangedChoice(VHDLModel_RangedChoice, DOMMixin):
+ def __init__(self, node: Iir, rng: Range):
+ super().__init__(rng)
+ DOMMixin.__init__(self, node)
+
+
+@export
+class Case(VHDLModel_Case, DOMMixin):
+ def __init__(
+ self,
+ node: Iir,
+ choices: Iterable[SequentialChoice],
+ statements: Iterable[SequentialStatement] = None,
+ ):
+ super().__init__(choices, statements)
+ DOMMixin.__init__(self, node)
+
+ @classmethod
+ def parse(
+ cls, caseNode: Iir, choices: Iterable[SequentialChoice], label: str
+ ) -> "Case":
+ from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes
+
+ statementChain = nodes.Get_Associated_Chain(caseNode)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "case", label
+ )
+
+ return cls(caseNode, choices, statements)
+
+
+@export
+class OthersCase(VHDLModel_OthersCase, DOMMixin):
+ def __init__(
+ self,
+ caseNode: Iir,
+ statements: Iterable[SequentialStatement] = None,
+ ):
+ super().__init__(statements)
+ DOMMixin.__init__(self, caseNode)
+
+ @classmethod
+ def parse(cls, caseNode: Iir, label: str = None) -> "OthersCase":
+ from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes
+
+ body = nodes.Get_Associated_Block(caseNode)
+ if body is nodes.Null_Iir:
+ return cls(caseNode)
+
+ statementChain = nodes.Get_Concurrent_Statement_Chain(body)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "case others", label
+ )
+
+ return cls(caseNode, statements)
+
+
+@export
+class CaseStatement(VHDLModel_CaseStatement, DOMMixin):
+ def __init__(
+ self,
+ caseNode: Iir,
+ label: str,
+ expression: ExpressionUnion,
+ cases: Iterable[SequentialCase],
+ ):
+ super().__init__(expression, cases, label)
+ DOMMixin.__init__(self, caseNode)
+
+ @classmethod
+ def parse(cls, caseNode: Iir, label: str) -> "CaseStatement":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+ from pyGHDL.dom._Translate import (
+ GetExpressionFromNode,
+ GetRangeFromNode,
+ GetNameFromNode,
+ )
+
+ expression = GetExpressionFromNode(nodes.Get_Expression(caseNode))
+
+ cases = []
+ choices = None
+ alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode)
+ cNode = alternative
+
+ while alternative != nodes.Null_Iir:
+ choiceKind = GetIirKindOfNode(alternative)
+ sameAlternative = nodes.Get_Same_Alternative_Flag(alternative)
+
+ if choiceKind in (
+ nodes.Iir_Kind.Choice_By_Name,
+ nodes.Iir_Kind.Choice_By_Expression,
+ ):
+ choiceExpression = GetExpressionFromNode(
+ nodes.Get_Choice_Expression(alternative)
+ )
+
+ choice = IndexedChoice(alternative, choiceExpression)
+ if sameAlternative:
+ choices.append(choice)
+ alternative = nodes.Get_Chain(alternative)
+ continue
+ elif choiceKind is nodes.Iir_Kind.Choice_By_Range:
+ choiceRange = nodes.Get_Choice_Range(alternative)
+ choiceRangeKind = GetIirKindOfNode(choiceRange)
+ if choiceRangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(choiceRange)
+ elif choiceRangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(choiceRange)
+ else:
+ pos = Position.parse(alternative)
+ raise DOMException(
+ "Unknown choice range kind '{kind}' in case statement at line {line}.".format(
+ kind=choiceRangeKind.name, line=pos.Line
+ )
+ )
+
+ choice = RangedChoice(alternative, rng)
+ if sameAlternative:
+ choices.append(choice)
+ alternative = nodes.Get_Chain(alternative)
+ continue
+ elif choiceKind is nodes.Iir_Kind.Choice_By_Others:
+ if choices is not None:
+ cases.append(Case.parse(alternative, choices, label))
+ choices = None
+ cases.append(OthersCase.parse(alternative, label))
+ alternative = nodes.Get_Chain(alternative)
+ cNode = alternative
+ continue
+ else:
+ pos = Position.parse(alternative)
+ raise DOMException(
+ "Unknown choice kind '{kind}' in case statement at line {line}.".format(
+ kind=choiceKind.name, line=pos.Line
+ )
+ )
+
+ if choices is not None:
+ cases.append(Case.parse(cNode, choices, label))
+
+ cNode = alternative
+ choices = [
+ choice,
+ ]
+
+ alternative = nodes.Get_Chain(alternative)
+
+ if choices is not None:
+ cases.append(Case.parse(cNode, choices, label))
+
+ return cls(caseNode, label, expression, cases)
+
+
+@export
+class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin):
+ def __init__(
+ self,
+ loopNode: Iir,
+ loopIndex: str,
+ rng: Range,
+ statements: Iterable[SequentialStatement] = None,
+ label: str = None,
+ ):
+ super().__init__(loopIndex, rng, statements, label)
+ DOMMixin.__init__(self, loopNode)
+
+ @classmethod
+ def parse(cls, loopNode: Iir, label: str) -> "ForLoopStatement":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+ from pyGHDL.dom._Translate import (
+ GetSequentialStatementsFromChainedNodes,
+ GetRangeFromNode,
+ GetNameFromNode,
+ )
+
+ spec = nodes.Get_Parameter_Specification(loopNode)
+ loopIndex = GetNameOfNode(spec)
+
+ discreteRange = nodes.Get_Discrete_Range(spec)
+ rangeKind = GetIirKindOfNode(discreteRange)
+ if rangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(discreteRange)
+ elif rangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(discreteRange)
+ else:
+ pos = Position.parse(loopNode)
+ raise DOMException(
+ "Unknown discete range kind '{kind}' in for...loop statement at line {line}.".format(
+ kind=rangeKind.name, line=pos.Line
+ )
+ )
+
+ statementChain = nodes.Get_Sequential_Statement_Chain(loopNode)
+ statements = GetSequentialStatementsFromChainedNodes(
+ statementChain, "for", label
+ )
+
+ return cls(loopNode, loopIndex, rng, statements, label)
+
+
+@export
+class SequentialSimpleSignalAssignment(
+ VHDLModel_SequentialSimpleSignalAssignment, DOMMixin
+):
+ def __init__(
+ self,
+ assignmentNode: Iir,
+ target: Name,
+ waveform: Iterable[WaveformElement],
+ label: str = None,
+ ):
+ super().__init__(target, waveform, label)
+ DOMMixin.__init__(self, assignmentNode)
+
+ @classmethod
+ def parse(
+ cls, assignmentNode: Iir, label: str = None
+ ) -> "SequentialSimpleSignalAssignment":
+ from pyGHDL.dom._Translate import GetNameFromNode
+
+ target = nodes.Get_Target(assignmentNode)
+ targetName = GetNameFromNode(target)
+
+ waveform = []
+ for wave in utils.chain_iter(nodes.Get_Waveform_Chain(assignmentNode)):
+ waveform.append(WaveformElement.parse(wave))
+
+ return cls(assignmentNode, targetName, waveform, label)
+
+
+@export
+class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin):
+ def __init__(
+ self,
+ callNode: Iir,
+ procedureName: Name,
+ parameterMappings: Iterable[ParameterAssociationItem],
+ label: str = None,
+ ):
+ super().__init__(procedureName, parameterMappings, label)
+ DOMMixin.__init__(self, callNode)
+
+ @classmethod
+ def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall":
+ from pyGHDL.dom._Translate import GetNameFromNode, GetParameterMapAspect
+
+ call = nodes.Get_Procedure_Call(callNode)
+
+ prefix = nodes.Get_Prefix(call)
+ procedureName = GetNameFromNode(prefix)
+ parameterAssociations = GetParameterMapAspect(
+ nodes.Get_Parameter_Association_Chain(callNode)
+ )
+
+ return cls(callNode, procedureName, parameterAssociations, label)
+
+
+@export
+class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin):
+ def __init__(
+ self,
+ assertNode: Iir,
+ condition: ExpressionUnion,
+ message: ExpressionUnion = None,
+ severity: ExpressionUnion = None,
+ label: str = None,
+ ):
+ super().__init__(condition, message, severity, label)
+ DOMMixin.__init__(self, assertNode)
+
+ @classmethod
+ def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement":
+ from pyGHDL.dom._Translate import GetExpressionFromNode
+
+ condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode))
+ messageNode = nodes.Get_Report_Expression(assertNode)
+ message = (
+ None
+ if messageNode is nodes.Null_Iir
+ else GetExpressionFromNode(messageNode)
+ )
+ severityNode = nodes.Get_Severity_Expression(assertNode)
+ severity = (
+ None
+ if severityNode is nodes.Null_Iir
+ else GetExpressionFromNode(severityNode)
+ )
+
+ return cls(assertNode, condition, message, severity, label)
+
+
+@export
+class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin):
+ def __init__(
+ self,
+ reportNode: Iir,
+ message: ExpressionUnion,
+ severity: ExpressionUnion = None,
+ label: str = None,
+ ):
+ super().__init__(message, severity, label)
+ DOMMixin.__init__(self, reportNode)
+
+ @classmethod
+ def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement":
+ from pyGHDL.dom._Translate import GetExpressionFromNode
+
+ message = GetExpressionFromNode(nodes.Get_Report_Expression(reportNode))
+ severityNode = nodes.Get_Severity_Expression(reportNode)
+ severity = (
+ None
+ if severityNode is nodes.Null_Iir
+ else GetExpressionFromNode(severityNode)
+ )
+
+ return cls(reportNode, message, severity, label)
+
+
+@export
+class WaitStatement(VHDLModel_WaitStatement, DOMMixin):
+ def __init__(
+ self,
+ waitNode: Iir,
+ sensitivityList: Iterable[Name] = None,
+ condition: ExpressionUnion = None,
+ timeout: ExpressionUnion = None,
+ label: str = None,
+ ):
+ super().__init__(sensitivityList, condition, timeout, label)
+ DOMMixin.__init__(self, waitNode)
+
+ @classmethod
+ def parse(cls, waitNode: Iir, label: str) -> "WaitStatement":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+ from pyGHDL.dom._Translate import GetExpressionFromNode
+
+ sensitivityList = None
+ sensitivityListNode = nodes.Get_Sensitivity_List(waitNode)
+ if sensitivityListNode is not nodes.Null_Iir:
+ print(GetIirKindOfNode(sensitivityListNode))
+
+ conditionNode = nodes.Get_Condition_Clause(waitNode)
+ condition = (
+ None
+ if conditionNode is nodes.Null_Iir
+ else GetExpressionFromNode(conditionNode)
+ )
+
+ timeoutNode = nodes.Get_Timeout_Clause(waitNode)
+ timeout = (
+ None
+ if timeoutNode is nodes.Null_Iir
+ else GetExpressionFromNode(timeoutNode)
+ )
+
+ return cls(waitNode, sensitivityList, condition, timeout, label)
diff --git a/pyGHDL/dom/Subprogram.py b/pyGHDL/dom/Subprogram.py
index e8e5ebbb4..32635f693 100644
--- a/pyGHDL/dom/Subprogram.py
+++ b/pyGHDL/dom/Subprogram.py
@@ -34,7 +34,7 @@ from typing import List
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
Function as VHDLModel_Function,
Procedure as VHDLModel_Procedure,
SubtypeOrSymbol,
diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py
index 3597f2572..f52afbb18 100644
--- a/pyGHDL/dom/Symbol.py
+++ b/pyGHDL/dom/Symbol.py
@@ -34,14 +34,14 @@ from typing import List, Iterator
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
EntitySymbol as VHDLModel_EntitySymbol,
SimpleSubtypeSymbol as VHDLModel_SimpleSubtypeSymbol,
ConstrainedScalarSubtypeSymbol as VHDLModel_ConstrainedScalarSubtypeSymbol,
ConstrainedCompositeSubtypeSymbol as VHDLModel_ConstrainedCompositeSubtypeSymbol,
SimpleObjectOrFunctionCallSymbol as VHDLModel_SimpleObjectOrFunctionCallSymbol,
IndexedObjectOrFunctionCallSymbol as VHDLModel_IndexedObjectOrFunctionCallSymbol,
- Constraint,
+ ConstraintUnion,
Name,
)
from pyGHDL.libghdl._types import Iir
@@ -87,7 +87,7 @@ class ConstrainedCompositeSubtypeSymbol(
VHDLModel_ConstrainedCompositeSubtypeSymbol, DOMMixin
):
def __init__(
- self, node: Iir, subtypeName: Name, constraints: List[Constraint] = None
+ self, node: Iir, subtypeName: Name, constraints: List[ConstraintUnion] = None
):
super().__init__(subtypeName, constraints)
DOMMixin.__init__(self, node)
diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py
index efe32afc2..deb315d9d 100644
--- a/pyGHDL/dom/Type.py
+++ b/pyGHDL/dom/Type.py
@@ -34,7 +34,7 @@ from typing import List, Union, Iterator, Tuple
from pydecor import export
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
AnonymousType as VHDLModel_AnonymousType,
PhysicalType as VHDLModel_PhysicalType,
IntegerType as VHDLModel_IntegerType,
@@ -52,9 +52,8 @@ from pyVHDLModel.VHDLModel import (
)
from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
-from pyGHDL.libghdl.vhdl import nodes
-from pyGHDL.dom import DOMMixin, DOMException
-from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode
+from pyGHDL.libghdl.vhdl import nodes, flists
+from pyGHDL.dom import DOMMixin, DOMException, Position
from pyGHDL.dom.Symbol import SimpleSubtypeSymbol
from pyGHDL.dom.Literal import EnumerationLiteral, PhysicalIntegerLiteral
from pyGHDL.dom.Range import Range
@@ -69,6 +68,8 @@ class IncompleteType(VHDLModel_AnonymousType, DOMMixin):
@classmethod
def parse(cls, node: Iir) -> "IncompleteType":
+ from pyGHDL.dom._Utils import GetNameOfNode
+
name = GetNameOfNode(node)
return cls(node, name)
@@ -113,9 +114,25 @@ class PhysicalType(VHDLModel_PhysicalType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "PhysicalType":
- from pyGHDL.dom._Translate import GetRangeFromNode
-
- rng = GetRangeFromNode(nodes.Get_Range_Constraint(typeDefinitionNode))
+ from pyGHDL.dom._Utils import GetIirKindOfNode, GetNameOfNode
+ from pyGHDL.dom._Translate import GetRangeFromNode, GetNameFromNode
+
+ rangeConstraint = nodes.Get_Range_Constraint(typeDefinitionNode)
+ rangeKind = GetIirKindOfNode(rangeConstraint)
+ if rangeKind == nodes.Iir_Kind.Range_Expression:
+ rng = GetRangeFromNode(rangeConstraint)
+ elif rangeKind in (
+ nodes.Iir_Kind.Attribute_Name,
+ nodes.Iir_Kind.Parenthesis_Name,
+ ):
+ rng = GetNameFromNode(rangeConstraint)
+ else:
+ pos = Position.parse(typeDefinitionNode)
+ raise DOMException(
+ "Unknown range kind '{kind}' in physical type definition at line {line}.".format(
+ kind=rangeKind.name, line=pos.Line
+ )
+ )
primaryUnit = nodes.Get_Primary_Unit(typeDefinitionNode)
primaryUnitName = GetNameOfNode(primaryUnit)
@@ -145,6 +162,7 @@ class ArrayType(VHDLModel_ArrayType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ArrayType":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
from pyGHDL.dom._Translate import (
GetSimpleTypeFromNode,
GetSubtypeIndicationFromIndicationNode,
@@ -176,12 +194,13 @@ class ArrayType(VHDLModel_ArrayType, DOMMixin):
@export
class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin):
- def __init__(self, node: Iir, identifier: str, subtype: SubtypeOrSymbol):
- super().__init__(identifier, subtype)
+ def __init__(self, node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol):
+ super().__init__(identifiers, subtype)
DOMMixin.__init__(self, node)
@classmethod
def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement":
+ from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode
elementName = GetNameOfNode(elementDeclarationNode)
@@ -189,7 +208,13 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin):
elementDeclarationNode, "record element", elementName
)
- return cls(elementDeclarationNode, elementName, elementType)
+ return cls(
+ elementDeclarationNode,
+ [
+ elementName,
+ ],
+ elementType,
+ )
@export
@@ -202,10 +227,36 @@ class RecordType(VHDLModel_RecordType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "RecordType":
+ from pyGHDL.dom._Utils import GetNameOfNode
+
elements = []
elementDeclarations = nodes.Get_Elements_Declaration_List(typeDefinitionNode)
- for elementDeclaration in utils.flist_iter(elementDeclarations):
+
+ elementCount = flists.Flast(elementDeclarations) + 1
+ index = 0
+ while index < elementCount:
+ elementDeclaration = flists.Get_Nth_Element(elementDeclarations, index)
+
element = RecordTypeElement.parse(elementDeclaration)
+
+ # Lookahead for elements with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(elementDeclaration):
+ index += 1
+ while index < elementCount:
+ nextNode: Iir = flists.Get_Nth_Element(elementDeclarations, index)
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextNode) == nodes.Null_Iir:
+ element.Identifiers.append(GetNameOfNode(nextNode))
+ else:
+ break
+ index += 1
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextNode):
+ break
+ else:
+ index += 1
+
elements.append(element)
return cls(typeDefinitionNode, typeName, elements)
@@ -221,6 +272,8 @@ class ProtectedType(VHDLModel_ProtectedType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "ProtectedType":
+ from pyGHDL.dom._Utils import GetIirKindOfNode
+
# FIXME: change this to a generator
methods = []
for item in utils.chain_iter(nodes.Get_Declaration_Chain(typeDefinitionNode)):
@@ -243,6 +296,7 @@ class ProtectedTypeBody(VHDLModel_ProtectedTypeBody, DOMMixin):
@classmethod
def parse(cls, protectedBodyNode: Iir) -> "ProtectedTypeBody":
+ from pyGHDL.dom._Utils import GetNameOfNode
from pyGHDL.dom._Translate import GetDeclaredItemsFromChainedNodes
typeName = GetNameOfNode(protectedBodyNode)
@@ -283,6 +337,7 @@ class FileType(VHDLModel_FileType, DOMMixin):
@classmethod
def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "FileType":
+ from pyGHDL.dom._Utils import GetNameOfNode
designatedSubtypeMark = nodes.Get_File_Type_Mark(typeDefinitionNode)
designatedSubtypeName = GetNameOfNode(designatedSubtypeMark)
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
index fc804caf4..43c443cc1 100644
--- a/pyGHDL/dom/_Translate.py
+++ b/pyGHDL/dom/_Translate.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: Interface items (e.g. generic or port)
+# Package module: DOM: IIR to *** translations.
#
# License:
# ============================================================================
@@ -30,17 +30,23 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
-from typing import List, Generator
+from typing import List, Generator, Type
from pydecor import export
-from pyGHDL.dom import Position, DOMException
-from pyGHDL.dom.Object import Variable
-from pyGHDL.dom.PSL import DefaultClock
-from pyVHDLModel.VHDLModel import (
- Constraint,
+from pyGHDL.dom.Sequential import (
+ IfStatement,
+ ForLoopStatement,
+ CaseStatement,
+ SequentialReportStatement,
+ SequentialAssertStatement,
+ WaitStatement,
+ SequentialSimpleSignalAssignment,
+)
+from pyVHDLModel.SyntaxModel import (
+ ConstraintUnion,
Direction,
- Expression,
+ ExpressionUnion,
SubtypeOrSymbol,
BaseType,
GenericInterfaceItem,
@@ -48,11 +54,15 @@ from pyVHDLModel.VHDLModel import (
ParameterInterfaceItem,
ModelEntity,
Name,
+ ConcurrentStatement,
+ SequentialStatement,
+ AssociationItem,
)
-from pyGHDL.libghdl import utils
+from pyGHDL.libghdl import utils, name_table
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
+from pyGHDL.dom import Position, DOMException
from pyGHDL.dom._Utils import (
GetNameOfNode,
GetIirKindOfNode,
@@ -63,6 +73,7 @@ from pyGHDL.dom.Names import (
AttributeName,
ParenthesisName,
AllName,
+ OpenName,
)
from pyGHDL.dom.Symbol import (
SimpleObjectOrFunctionCallSymbol,
@@ -94,6 +105,7 @@ from pyGHDL.dom.Literal import (
PhysicalFloatingLiteral,
NullLiteral,
)
+from pyGHDL.dom.Object import Variable
from pyGHDL.dom.Expression import (
SubtractionExpression,
AdditionExpression,
@@ -138,8 +150,24 @@ from pyGHDL.dom.Expression import (
MatchingLessEqualExpression,
MatchingGreaterThanExpression,
)
+from pyGHDL.dom.Concurrent import (
+ ConcurrentBlockStatement,
+ EntityInstantiation,
+ ConfigurationInstantiation,
+ ComponentInstantiation,
+ ProcessStatement,
+ IfGenerateStatement,
+ ForGenerateStatement,
+ CaseGenerateStatement,
+ ConcurrentSimpleSignalAssignment,
+ ConcurrentProcedureCall,
+ GenericAssociationItem,
+ PortAssociationItem,
+ ParameterAssociationItem,
+)
from pyGHDL.dom.Subprogram import Function, Procedure
from pyGHDL.dom.Misc import Alias
+from pyGHDL.dom.PSL import DefaultClock
__all__ = []
@@ -186,8 +214,8 @@ def GetAssociations(node: Iir) -> List:
associations.append(expr)
else:
raise DOMException(
- "Unknown association kind '{kindName}'({kind}) in array index/slice or function call '{node}'.".format(
- kind=kind, kindName=kind.name, node=node
+ "Unknown association kind '{kind}' in array index/slice or function call '{node}'.".format(
+ kind=kind.name, node=node
)
)
@@ -197,7 +225,7 @@ def GetAssociations(node: Iir) -> List:
@export
def GetArrayConstraintsFromSubtypeIndication(
subtypeIndication: Iir,
-) -> List[Constraint]:
+) -> List[ConstraintUnion]:
constraints = []
for constraint in utils.flist_iter(
nodes.Get_Index_Constraint_List(subtypeIndication)
@@ -266,7 +294,6 @@ def GetAnonymousTypeFromNode(node: Iir) -> BaseType:
typeName = GetNameOfNode(node)
typeDefinition = nodes.Get_Type_Definition(node)
if typeDefinition is nodes.Null_Iir:
- print(1, node, typeName)
return IncompleteType(node, typeName)
kind = GetIirKindOfNode(typeDefinition)
@@ -301,8 +328,6 @@ def GetAnonymousTypeFromNode(node: Iir) -> BaseType:
@export
def GetSubtypeIndicationFromNode(node: Iir, entity: str, name: str) -> SubtypeOrSymbol:
subtypeIndicationNode = nodes.Get_Subtype_Indication(node)
- # if subtypeIndicationNode is nodes.Null_Iir:
- # return None
return GetSubtypeIndicationFromIndicationNode(subtypeIndicationNode, entity, name)
@@ -311,12 +336,8 @@ def GetSubtypeIndicationFromIndicationNode(
subtypeIndicationNode: Iir, entity: str, name: str
) -> SubtypeOrSymbol:
if subtypeIndicationNode is nodes.Null_Iir:
- print(
- "[NOT IMPLEMENTED]: Unhandled multiple declarations for {entity} '{name}'.".format(
- entity=entity, name=name
- )
- )
- return None
+ raise ValueError("Parameter 'subtypeIndicationNode' is 'Null_Iir'.")
+
kind = GetIirKindOfNode(subtypeIndicationNode)
if kind in (
nodes.Iir_Kind.Simple_Name,
@@ -348,9 +369,10 @@ def GetScalarConstrainedSubtypeFromNode(
) -> ConstrainedScalarSubtypeSymbol:
typeMark = nodes.Get_Subtype_Type_Mark(subtypeIndicationNode)
typeMarkName = GetNameOfNode(typeMark)
+ simpleTypeMark = SimpleName(typeMark, typeMarkName)
rangeConstraint = nodes.Get_Range_Constraint(subtypeIndicationNode)
r = GetRangeFromNode(rangeConstraint)
- return ConstrainedScalarSubtypeSymbol(subtypeIndicationNode, typeMarkName, r)
+ return ConstrainedScalarSubtypeSymbol(subtypeIndicationNode, simpleTypeMark, r)
@export
@@ -359,10 +381,11 @@ def GetCompositeConstrainedSubtypeFromNode(
) -> ConstrainedCompositeSubtypeSymbol:
typeMark = nodes.Get_Subtype_Type_Mark(subtypeIndicationNode)
typeMarkName = GetNameOfNode(typeMark)
+ simpleTypeMark = SimpleName(typeMark, typeMarkName)
constraints = GetArrayConstraintsFromSubtypeIndication(subtypeIndicationNode)
return ConstrainedCompositeSubtypeSymbol(
- subtypeIndicationNode, typeMarkName, constraints
+ subtypeIndicationNode, simpleTypeMark, constraints
)
@@ -423,7 +446,7 @@ __EXPRESSION_TRANSLATION = {
nodes.Iir_Kind.Less_Than_Operator: LessThanExpression,
nodes.Iir_Kind.Less_Than_Or_Equal_Operator: LessEqualExpression,
nodes.Iir_Kind.Greater_Than_Operator: GreaterThanExpression,
- nodes.Iir_Kind.Greater_Than_Or_Equal_Operator: MatchingGreaterEqualExpression,
+ nodes.Iir_Kind.Greater_Than_Or_Equal_Operator: GreaterEqualExpression,
nodes.Iir_Kind.Match_Equality_Operator: MatchingEqualExpression,
nodes.Iir_Kind.Match_Inequality_Operator: MatchingUnequalExpression,
nodes.Iir_Kind.Match_Less_Than_Operator: MatchingLessThanExpression,
@@ -444,7 +467,7 @@ __EXPRESSION_TRANSLATION = {
@export
-def GetExpressionFromNode(node: Iir) -> Expression:
+def GetExpressionFromNode(node: Iir) -> ExpressionUnion:
kind = GetIirKindOfNode(node)
try:
@@ -475,52 +498,100 @@ def GetGenericsFromChainedNodes(
GenericFunctionInterfaceItem,
)
- for generic in utils.chain_iter(nodeChain):
+ generic = nodeChain
+ while generic != nodes.Null_Iir:
kind = GetIirKindOfNode(generic)
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
from pyGHDL.dom.InterfaceItem import GenericConstantInterfaceItem
- yield GenericConstantInterfaceItem.parse(generic)
- elif kind == nodes.Iir_Kind.Interface_Type_Declaration:
- yield GenericTypeInterfaceItem.parse(generic)
- elif kind == nodes.Iir_Kind.Interface_Package_Declaration:
- yield GenericPackageInterfaceItem.parse(generic)
- elif kind == nodes.Iir_Kind.Interface_Procedure_Declaration:
- yield GenericProcedureInterfaceItem.parse(generic)
- elif kind == nodes.Iir_Kind.Interface_Function_Declaration:
- yield GenericFunctionInterfaceItem.parse(generic)
+ genericConstant = GenericConstantInterfaceItem.parse(generic)
+
+ # Lookahead for generics with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(generic):
+ nextNode = nodes.Get_Chain(generic)
+ for nextGeneric in utils.chain_iter(nextNode):
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextGeneric) == nodes.Null_Iir:
+ genericConstant.Identifiers.append(GetNameOfNode(nextGeneric))
+ else:
+ generic = nextGeneric
+ break
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextGeneric):
+ generic = nodes.Get_Chain(nextGeneric)
+ break
+ else:
+ generic = nodes.Null_Iir
+ else:
+ generic = nodes.Get_Chain(generic)
+
+ yield genericConstant
+ continue
else:
- position = Position.parse(generic)
- raise DOMException(
- "Unknown generic kind '{kindName}'({kind}) in generic '{generic}' at {file}:{line}:{column}.".format(
- kind=kind,
- kindName=kind.name,
- generic=generic,
- file=position.Filename,
- line=position.Line,
- column=position.Column,
+ if kind == nodes.Iir_Kind.Interface_Type_Declaration:
+ yield GenericTypeInterfaceItem.parse(generic)
+ elif kind == nodes.Iir_Kind.Interface_Package_Declaration:
+ yield GenericPackageInterfaceItem.parse(generic)
+ elif kind == nodes.Iir_Kind.Interface_Procedure_Declaration:
+ yield GenericProcedureInterfaceItem.parse(generic)
+ elif kind == nodes.Iir_Kind.Interface_Function_Declaration:
+ yield GenericFunctionInterfaceItem.parse(generic)
+ else:
+ position = Position.parse(generic)
+ raise DOMException(
+ "Unknown generic kind '{kind}' in generic '{generic}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
+ generic=generic,
+ file=position.Filename,
+ line=position.Line,
+ column=position.Column,
+ )
)
- )
+
+ generic = nodes.Get_Chain(generic)
@export
def GetPortsFromChainedNodes(
nodeChain: Iir,
) -> Generator[PortInterfaceItem, None, None]:
- for port in utils.chain_iter(nodeChain):
+
+ port = nodeChain
+ while port != nodes.Null_Iir:
kind = GetIirKindOfNode(port)
if kind == nodes.Iir_Kind.Interface_Signal_Declaration:
from pyGHDL.dom.InterfaceItem import PortSignalInterfaceItem
portSignal = PortSignalInterfaceItem.parse(port)
+ # Lookahead for ports with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(port):
+ nextNode = nodes.Get_Chain(port)
+ for nextPort in utils.chain_iter(nextNode):
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextPort) == nodes.Null_Iir:
+ portSignal.Identifiers.append(GetNameOfNode(nextPort))
+ else:
+ port = nextPort
+ break
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextPort):
+ port = nodes.Get_Chain(nextPort)
+ break
+ else:
+ port = nodes.Null_Iir
+ else:
+ port = nodes.Get_Chain(port)
+
yield portSignal
+ continue
else:
position = Position.parse(port)
raise DOMException(
- "Unknown port kind '{kindName}'({kind}) in port '{port}' at {file}:{line}:{column}.".format(
- kind=kind,
- kindName=kind.name,
+ "Unknown port kind '{kind}' in port '{port}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
port=port,
file=position.Filename,
line=position.Line,
@@ -533,30 +604,31 @@ def GetPortsFromChainedNodes(
def GetParameterFromChainedNodes(
nodeChain: Iir,
) -> Generator[ParameterInterfaceItem, None, None]:
- for parameter in utils.chain_iter(nodeChain):
+
+ parameter = nodeChain
+ while parameter != nodes.Null_Iir:
kind = GetIirKindOfNode(parameter)
if kind == nodes.Iir_Kind.Interface_Constant_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterConstantInterfaceItem
- yield ParameterConstantInterfaceItem.parse(parameter)
+ param = ParameterConstantInterfaceItem.parse(parameter)
elif kind == nodes.Iir_Kind.Interface_Variable_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterVariableInterfaceItem
- yield ParameterVariableInterfaceItem.parse(parameter)
+ param = ParameterVariableInterfaceItem.parse(parameter)
elif kind == nodes.Iir_Kind.Interface_Signal_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterSignalInterfaceItem
- yield ParameterSignalInterfaceItem.parse(parameter)
+ param = ParameterSignalInterfaceItem.parse(parameter)
elif kind == nodes.Iir_Kind.Interface_File_Declaration:
from pyGHDL.dom.InterfaceItem import ParameterFileInterfaceItem
- yield ParameterFileInterfaceItem.parse(parameter)
+ param = ParameterFileInterfaceItem.parse(parameter)
else:
position = Position.parse(parameter)
raise DOMException(
- "Unknown parameter kind '{kindName}'({kind}) in parameter '{param}' at {file}:{line}:{column}.".format(
- kind=kind,
- kindName=kind.name,
+ "Unknown parameter kind '{kind}' in parameter '{param}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
param=parameter,
file=position.Filename,
line=position.Line,
@@ -564,111 +636,385 @@ def GetParameterFromChainedNodes(
)
)
+ # Lookahead for parameters with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(parameter):
+ nextNode = nodes.Get_Chain(parameter)
+ for nextParameter in utils.chain_iter(nextNode):
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextParameter) == nodes.Null_Iir:
+ param.Identifiers.append(GetNameOfNode(nextParameter))
+ else:
+ parameter = nextParameter
+ break
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextParameter):
+ parameter = nodes.Get_Chain(nextParameter)
+ break
+ else:
+ parameter = nodes.Null_Iir
+ else:
+ parameter = nodes.Get_Chain(parameter)
+
+ yield param
+
+
+def GetMapAspect(
+ mapAspect: Iir, cls: Type, entity: str
+) -> Generator[AssociationItem, None, None]:
+ for generic in utils.chain_iter(mapAspect):
+ kind = GetIirKindOfNode(generic)
+ if kind is nodes.Iir_Kind.Association_Element_By_Expression:
+ formalNode = nodes.Get_Formal(generic)
+ if formalNode is nodes.Null_Iir:
+ formal = None
+ else:
+ formal = GetNameFromNode(formalNode)
+
+ actual = GetExpressionFromNode(nodes.Get_Actual(generic))
+
+ yield cls(generic, actual, formal)
+ elif kind is nodes.Iir_Kind.Association_Element_Open:
+ formalNode = nodes.Get_Formal(generic)
+ if formalNode is nodes.Null_Iir:
+ formal = None
+ else:
+ formal = GetNameFromNode(formalNode)
+
+ yield cls(generic, OpenName(generic), formal)
+ else:
+ pos = Position.parse(generic)
+ raise DOMException(
+ "Unknown association kind '{kind}' in {entity} map at line {line}.".format(
+ kind=kind.name, entity=entity, line=pos.Line
+ )
+ )
+
+
+def GetGenericMapAspect(
+ genericMapAspect: Iir,
+) -> Generator[GenericAssociationItem, None, None]:
+ return GetMapAspect(genericMapAspect, GenericAssociationItem, "generic")
+
+
+def GetPortMapAspect(portMapAspect: Iir) -> Generator[PortAssociationItem, None, None]:
+ return GetMapAspect(portMapAspect, PortAssociationItem, "port")
+
+
+def GetParameterMapAspect(
+ parameterMapAspect: Iir,
+) -> Generator[ParameterAssociationItem, None, None]:
+ return GetMapAspect(parameterMapAspect, ParameterAssociationItem, "parameter")
+
def GetDeclaredItemsFromChainedNodes(
nodeChain: Iir, entity: str, name: str
) -> Generator[ModelEntity, None, None]:
- for item in utils.chain_iter(nodeChain):
+ item = nodeChain
+ lastKind = None
+ while item != nodes.Null_Iir:
kind = GetIirKindOfNode(item)
if kind == nodes.Iir_Kind.Constant_Declaration:
from pyGHDL.dom.Object import Constant
- yield Constant.parse(item)
+ obj = Constant.parse(item)
elif kind == nodes.Iir_Kind.Variable_Declaration:
from pyGHDL.dom.Object import SharedVariable
if nodes.Get_Shared_Flag(item):
- yield SharedVariable.parse(item)
+ obj = SharedVariable.parse(item)
else:
- yield Variable.parse(item)
- # raise DOMException("Found non-shared variable.")
+ obj = Variable.parse(item)
elif kind == nodes.Iir_Kind.Signal_Declaration:
from pyGHDL.dom.Object import Signal
- yield Signal.parse(item)
+ obj = Signal.parse(item)
elif kind == nodes.Iir_Kind.File_Declaration:
from pyGHDL.dom.Object import File
- yield File.parse(item)
- elif kind == nodes.Iir_Kind.Type_Declaration:
- yield GetTypeFromNode(item)
-
- elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
- yield GetAnonymousTypeFromNode(item)
-
- elif kind == nodes.Iir_Kind.Subtype_Declaration:
- yield GetSubtypeFromNode(item)
-
- elif kind == nodes.Iir_Kind.Function_Declaration:
- yield Function.parse(item)
-
- elif kind == nodes.Iir_Kind.Function_Body:
- # procedureName = NodeToName(item)
- print("found function body '{name}'".format(name="????"))
- elif kind == nodes.Iir_Kind.Procedure_Declaration:
- yield Procedure.parse(item)
- elif kind == nodes.Iir_Kind.Procedure_Body:
- # procedureName = NodeToName(item)
- print("found procedure body '{name}'".format(name="????"))
- elif kind == nodes.Iir_Kind.Protected_Type_Body:
- yield ProtectedTypeBody.parse(item)
- elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
- yield GetAliasFromNode(item)
- elif kind == nodes.Iir_Kind.Component_Declaration:
- from pyGHDL.dom.DesignUnit import Component
-
- yield Component.parse(item)
- elif kind == nodes.Iir_Kind.Attribute_Declaration:
- from pyGHDL.dom.Attribute import Attribute
-
- yield Attribute.parse(item)
- elif kind == nodes.Iir_Kind.Attribute_Specification:
- from pyGHDL.dom.Attribute import AttributeSpecification
-
- yield AttributeSpecification.parse(item)
- elif kind == nodes.Iir_Kind.Use_Clause:
- from pyGHDL.dom.DesignUnit import UseClause
-
- yield UseClause.parse(item)
- elif kind == nodes.Iir_Kind.Package_Declaration:
- from pyGHDL.dom.DesignUnit import Package
-
- yield Package.parse(item)
- elif kind == nodes.Iir_Kind.Package_Instantiation_Declaration:
- from pyGHDL.dom.DesignUnit import PackageInstantiation
-
- yield PackageInstantiation.parse(item)
- elif kind == nodes.Iir_Kind.Configuration_Specification:
+ obj = File.parse(item)
+ else:
+ if kind == nodes.Iir_Kind.Type_Declaration:
+ yield GetTypeFromNode(item)
+
+ elif kind == nodes.Iir_Kind.Anonymous_Type_Declaration:
+ yield GetAnonymousTypeFromNode(item)
+
+ elif kind == nodes.Iir_Kind.Subtype_Declaration:
+ yield GetSubtypeFromNode(item)
+
+ elif kind == nodes.Iir_Kind.Function_Declaration:
+ if nodes.Get_Has_Body(item):
+ yield Function.parse(item)
+ else:
+ print("[NOT IMPLEMENTED] function declaration without body")
+
+ lastKind = kind
+ item = nodes.Get_Chain(item)
+ continue
+ elif kind == nodes.Iir_Kind.Function_Body:
+ if lastKind is nodes.Iir_Kind.Function_Declaration:
+ pass
+ else:
+ position = Position.parse(item)
+ raise DOMException(
+ "Found unexpected function body '{functionName}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ functionName=GetNameOfNode(item),
+ entity=entity,
+ name=name,
+ file=position.Filename,
+ line=position.Line,
+ column=position.Column,
+ )
+ )
+ elif kind == nodes.Iir_Kind.Procedure_Declaration:
+ if nodes.Get_Has_Body(item):
+ yield Procedure.parse(item)
+ else:
+ print("[NOT IMPLEMENTED] procedure declaration without body")
+
+ lastKind = kind
+ item = nodes.Get_Chain(item)
+ continue
+ elif kind == nodes.Iir_Kind.Procedure_Body:
+ if lastKind is nodes.Iir_Kind.Procedure_Declaration:
+ pass
+ else:
+ position = Position.parse(item)
+ raise DOMException(
+ "Found unexpected procedure body '{functionName}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ functionName=GetNameOfNode(item),
+ entity=entity,
+ name=name,
+ file=position.Filename,
+ line=position.Line,
+ column=position.Column,
+ )
+ )
+ elif kind == nodes.Iir_Kind.Protected_Type_Body:
+ yield ProtectedTypeBody.parse(item)
+ elif kind == nodes.Iir_Kind.Object_Alias_Declaration:
+ yield GetAliasFromNode(item)
+ elif kind == nodes.Iir_Kind.Component_Declaration:
+ from pyGHDL.dom.DesignUnit import Component
+
+ yield Component.parse(item)
+ elif kind == nodes.Iir_Kind.Attribute_Declaration:
+ from pyGHDL.dom.Attribute import Attribute
+
+ yield Attribute.parse(item)
+ elif kind == nodes.Iir_Kind.Attribute_Specification:
+ from pyGHDL.dom.Attribute import AttributeSpecification
+
+ yield AttributeSpecification.parse(item)
+ elif kind == nodes.Iir_Kind.Use_Clause:
+ from pyGHDL.dom.DesignUnit import UseClause
+
+ yield UseClause.parse(item)
+ elif kind == nodes.Iir_Kind.Package_Declaration:
+ from pyGHDL.dom.DesignUnit import Package
+
+ yield Package.parse(item, None) # TODO: Can it have a context?
+ elif kind == nodes.Iir_Kind.Package_Instantiation_Declaration:
+ from pyGHDL.dom.DesignUnit import PackageInstantiation
+
+ yield PackageInstantiation.parse(item)
+ elif kind == nodes.Iir_Kind.Configuration_Specification:
+ print(
+ "[NOT IMPLEMENTED] Configuration specification in {name}".format(
+ name=name
+ )
+ )
+ elif kind == nodes.Iir_Kind.Psl_Default_Clock:
+ yield DefaultClock.parse(item)
+ elif kind == nodes.Iir_Kind.Group_Declaration:
+ print("[NOT IMPLEMENTED] Group declaration in {name}".format(name=name))
+ elif kind == nodes.Iir_Kind.Group_Template_Declaration:
+ print(
+ "[NOT IMPLEMENTED] Group template declaration in {name}".format(
+ name=name
+ )
+ )
+ elif kind == nodes.Iir_Kind.Disconnection_Specification:
+ print(
+ "[NOT IMPLEMENTED] Disconnect specification in {name}".format(
+ name=name
+ )
+ )
+ else:
+ position = Position.parse(item)
+ raise DOMException(
+ "Unknown declared item kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
+ entity=entity,
+ name=name,
+ file=position.Filename,
+ line=position.Line,
+ column=position.Column,
+ )
+ )
+
+ lastKind = None
+ item = nodes.Get_Chain(item)
+ continue
+
+ # Lookahead for objects with multiple identifiers at once
+ if nodes.Get_Has_Identifier_List(item):
+ nextNode = nodes.Get_Chain(item)
+ for nextItem in utils.chain_iter(nextNode):
+ # Consecutive identifiers are found, if the subtype indication is Null
+ if nodes.Get_Subtype_Indication(nextItem) == nodes.Null_Iir:
+ obj.Identifiers.append(GetNameOfNode(nextItem))
+ else:
+ item = nextItem
+ break
+
+ # The last consecutive identifiers has no Identifier_List flag
+ if not nodes.Get_Has_Identifier_List(nextItem):
+ item = nodes.Get_Chain(nextItem)
+ break
+ else:
+ item = nodes.Null_Iir
+ else:
+ item = nodes.Get_Chain(item)
+
+ yield obj
+
+
+def GetConcurrentStatementsFromChainedNodes(
+ nodeChain: Iir, entity: str, name: str
+) -> Generator[ConcurrentStatement, None, None]:
+ for statement in utils.chain_iter(nodeChain):
+ label = nodes.Get_Label(statement)
+ label = name_table.Get_Name_Ptr(label) if label != nodes.Null_Iir else None
+
+ pos = Position.parse(statement)
+
+ kind = GetIirKindOfNode(statement)
+ if kind == nodes.Iir_Kind.Sensitized_Process_Statement:
+ yield ProcessStatement.parse(statement, label, True)
+
+ elif kind == nodes.Iir_Kind.Process_Statement:
+ yield ProcessStatement.parse(statement, label, False)
+
+ elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment:
+ yield ConcurrentSimpleSignalAssignment.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Concurrent_Conditional_Signal_Assignment:
+ print(
+ "[NOT IMPLEMENTED] Concurrent (conditional) signal assignment (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
+ )
+ )
+ elif kind == nodes.Iir_Kind.Concurrent_Selected_Signal_Assignment:
+ print(
+ "[NOT IMPLEMENTED] Concurrent (selected) signal assignment (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
+ )
+ )
+ elif kind == nodes.Iir_Kind.Concurrent_Procedure_Call_Statement:
+ yield ConcurrentProcedureCall.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Component_Instantiation_Statement:
+ instantiatedUnit = nodes.Get_Instantiated_Unit(statement)
+ instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit)
+ if instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Entity:
+ yield EntityInstantiation.parse(statement, instantiatedUnit, label)
+ elif instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Configuration:
+ yield ConfigurationInstantiation.parse(
+ statement, instantiatedUnit, label
+ )
+ elif instantiatedUnitKind == nodes.Iir_Kind.Simple_Name:
+ yield ComponentInstantiation.parse(statement, instantiatedUnit, label)
+ else:
+ raise DOMException(
+ "Unknown instantiation kind '{kind}' in instantiation of label {label} at {file}:{line}:{column}.".format(
+ kind=instantiatedUnitKind.name,
+ label=label,
+ file=pos.Filename,
+ line=pos.Line,
+ column=pos.Column,
+ )
+ )
+ elif kind == nodes.Iir_Kind.Block_Statement:
+ yield ConcurrentBlockStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.If_Generate_Statement:
+ yield IfGenerateStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Case_Generate_Statement:
+ yield CaseGenerateStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.For_Generate_Statement:
+ yield ForGenerateStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Psl_Assert_Directive:
+ print(
+ "[NOT IMPLEMENTED] PSL assert directive (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
+ )
+ )
+ else:
+ raise DOMException(
+ "Unknown statement of kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ kind=kind.name,
+ entity=entity,
+ name=name,
+ file=pos.Filename,
+ line=pos.Line,
+ column=pos.Column,
+ )
+ )
+
+
+def GetSequentialStatementsFromChainedNodes(
+ nodeChain: Iir, entity: str, name: str
+) -> Generator[SequentialStatement, None, None]:
+ for statement in utils.chain_iter(nodeChain):
+ label = nodes.Get_Label(statement)
+ label = name_table.Get_Name_Ptr(label) if label != nodes.Null_Iir else None
+
+ pos = Position.parse(statement)
+ kind = GetIirKindOfNode(statement)
+ if kind == nodes.Iir_Kind.If_Statement:
+ yield IfStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.For_Loop_Statement:
+ yield ForLoopStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Case_Statement:
+ yield CaseStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Simple_Signal_Assignment_Statement:
+ yield SequentialSimpleSignalAssignment.parse(statement, label)
+ elif kind in (
+ nodes.Iir_Kind.Variable_Assignment_Statement,
+ nodes.Iir_Kind.Conditional_Variable_Assignment_Statement,
+ ):
print(
- "[NOT IMPLEMENTED] Configuration specification in {name}".format(
- name=name
+ "[NOT IMPLEMENTED] Variable assignment (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
)
)
- elif kind == nodes.Iir_Kind.Psl_Default_Clock:
- yield DefaultClock.parse(item)
- elif kind == nodes.Iir_Kind.Group_Declaration:
- print("[NOT IMPLEMENTED] Group declaration in {name}".format(name=name))
- elif kind == nodes.Iir_Kind.Group_Template_Declaration:
+ elif kind == nodes.Iir_Kind.Wait_Statement:
+ yield WaitStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Procedure_Call_Statement:
print(
- "[NOT IMPLEMENTED] Group template declaration in {name}".format(
- name=name
+ "[NOT IMPLEMENTED] Procedure call (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
)
)
- elif kind == nodes.Iir_Kind.Disconnection_Specification:
+ elif kind == nodes.Iir_Kind.Report_Statement:
+ yield SequentialReportStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Assertion_Statement:
+ yield SequentialAssertStatement.parse(statement, label)
+ elif kind == nodes.Iir_Kind.Null_Statement:
print(
- "[NOT IMPLEMENTED] Disconnect specification in {name}".format(name=name)
+ "[NOT IMPLEMENTED] null statement (label: '{label}') at line {line}".format(
+ label=label, line=pos.Line
+ )
)
else:
- position = Position.parse(item)
raise DOMException(
- "Unknown declared item kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
+ "Unknown statement of kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format(
kind=kind.name,
entity=entity,
name=name,
- file=position.Filename,
- line=position.Line,
- column=position.Column,
+ file=pos.Filename,
+ line=pos.Line,
+ column=pos.Column,
)
)
diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py
index 2b17d98ab..dbb39f43d 100644
--- a/pyGHDL/dom/_Utils.py
+++ b/pyGHDL/dom/_Utils.py
@@ -9,7 +9,7 @@
# Authors:
# Patrick Lehmann
#
-# Package module: DOM: Interface items (e.g. generic or port)
+# Package module: DOM: IIR helper functions
#
# License:
# ============================================================================
@@ -32,12 +32,12 @@
# ============================================================================
from pydecor import export
-from pyVHDLModel.VHDLModel import Mode
+from pyVHDLModel.SyntaxModel import Mode
-from pyGHDL.libghdl import LibGHDLException, name_table, files_map, errorout_memory
+from pyGHDL.libghdl import LibGHDLException, name_table, errorout_memory
+from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.libghdl.vhdl.nodes import Null_Iir
-from pyGHDL.libghdl._types import Iir
from pyGHDL.dom import DOMException
__all__ = []
diff --git a/pyGHDL/dom/formatting/__init__.py b/pyGHDL/dom/formatting/__init__.py
index e69de29bb..828756001 100644
--- a/pyGHDL/dom/formatting/__init__.py
+++ b/pyGHDL/dom/formatting/__init__.py
@@ -0,0 +1,32 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package package: A package for formatters.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
index 4d6e5dccb..6c0f06061 100644
--- a/pyGHDL/dom/formatting/prettyprint.py
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -1,25 +1,51 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Package module: A pretty printer to format the DOM as a tree in text form.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
from typing import List, Union
from pydecor import export
-from pyGHDL.dom.Attribute import Attribute, AttributeSpecification
-from pyGHDL.dom.Misc import Alias
-from pyGHDL.dom.PSL import DefaultClock
-from pyGHDL.dom.Subprogram import Procedure
-from pyGHDL.dom.Type import (
- IntegerType,
- Subtype,
- ArrayType,
- RecordType,
- AccessType,
- EnumeratedType,
- FileType,
- ProtectedType,
- ProtectedTypeBody,
- PhysicalType,
- IncompleteType,
+from pyGHDL.dom.Concurrent import (
+ ConcurrentBlockStatement,
+ ProcessStatement,
+ IfGenerateStatement,
+ CaseGenerateStatement,
+ ForGenerateStatement,
+ ComponentInstantiation,
+ ConfigurationInstantiation,
+ EntityInstantiation,
+ ConcurrentProcedureCall,
)
-from pyVHDLModel.VHDLModel import (
+from pyVHDLModel.SyntaxModel import (
GenericInterfaceItem,
NamedEntity,
PortInterfaceItem,
@@ -27,6 +53,8 @@ from pyVHDLModel.VHDLModel import (
Function,
BaseType,
FullType,
+ BaseConstant,
+ ConcurrentStatement,
)
from pyGHDL import GHDLBaseException
@@ -42,16 +70,33 @@ from pyGHDL.dom.DesignUnit import (
UseClause,
PackageInstantiation,
)
-from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File
+from pyGHDL.dom.Symbol import (
+ SimpleSubtypeSymbol,
+ ConstrainedCompositeSubtypeSymbol,
+)
+from pyGHDL.dom.Type import (
+ IntegerType,
+ Subtype,
+ ArrayType,
+ RecordType,
+ AccessType,
+ EnumeratedType,
+ FileType,
+ ProtectedType,
+ ProtectedTypeBody,
+ PhysicalType,
+ IncompleteType,
+)
from pyGHDL.dom.InterfaceItem import (
GenericConstantInterfaceItem,
PortSignalInterfaceItem,
GenericTypeInterfaceItem,
)
-from pyGHDL.dom.Symbol import (
- SimpleSubtypeSymbol,
- ConstrainedCompositeSubtypeSymbol,
-)
+from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File
+from pyGHDL.dom.Attribute import Attribute, AttributeSpecification
+from pyGHDL.dom.Subprogram import Procedure
+from pyGHDL.dom.Misc import Alias
+from pyGHDL.dom.PSL import DefaultClock
StringBuffer = List[str]
@@ -74,14 +119,19 @@ class PrettyPrint:
prefix = " " * level
buffer.append("{prefix}Libraries:".format(prefix=prefix))
for library in design.Libraries.values():
- for line in self.formatLibrary(library, level + 1):
+ buffer.append(
+ "{prefix} - Name: {name}".format(
+ prefix=prefix, name=library.Identifier
+ )
+ )
+ for line in self.formatLibrary(library, level + 2):
buffer.append(line)
buffer.append("{prefix}Documents:".format(prefix=prefix))
for document in design.Documents:
buffer.append(
- "{prefix}- Path: '{doc!s}':".format(doc=document.Path, prefix=prefix)
+ "{prefix} - Path: '{doc!s}':".format(doc=document.Path, prefix=prefix)
)
- for line in self.formatDocument(document, level + 1):
+ for line in self.formatDocument(document, level + 2):
buffer.append(line)
return buffer
@@ -91,33 +141,41 @@ class PrettyPrint:
prefix = " " * level
buffer.append("{prefix}Entities:".format(prefix=prefix))
for entity in library.Entities:
- for line in self.formatEntity(entity, level + 1):
- buffer.append(line)
- # buffer.append("{prefix}Architectures:".format(prefix=prefix))
- # for architecture in library.Architectures:
- # for line in self.formatArchitecture(architecture, level + 1):
- # buffer.append(line)
+ buffer.append(
+ "{prefix} - {name}({architectures})".format(
+ prefix=prefix,
+ name=entity.Identifier,
+ architectures=", ".join(
+ [a.Identifier for a in entity.Architectures]
+ ),
+ )
+ )
buffer.append("{prefix}Packages:".format(prefix=prefix))
for package in library.Packages:
if isinstance(package, Package):
- gen = self.formatPackage
- else:
- gen = self.formatPackageInstance
-
- for line in gen(package, level + 1):
- buffer.append(line)
- # buffer.append("{prefix}PackageBodies:".format(prefix=prefix))
- # for packageBodies in library.PackageBodies:
- # for line in self.formatPackageBody(packageBodies, level + 1):
- # buffer.append(line)
+ buffer.append(
+ "{prefix} - {name}".format(prefix=prefix, name=package.Identifier)
+ )
+ elif isinstance(package, PackageInstantiation):
+ buffer.append(
+ "{prefix} - {name} instantiate from {package}".format(
+ prefix=prefix,
+ name=package.Identifier,
+ package=package.PackageReference,
+ )
+ )
buffer.append("{prefix}Configurations:".format(prefix=prefix))
for configuration in library.Configurations:
- for line in self.formatConfiguration(configuration, level + 1):
- buffer.append(line)
+ buffer.append(
+ "{prefix} - {name}".format(
+ prefix=prefix, name=configuration.Identifier
+ )
+ )
buffer.append("{prefix}Contexts:".format(prefix=prefix))
for context in library.Contexts:
- for line in self.formatContext(context, level + 1):
- buffer.append(line)
+ buffer.append(
+ "{prefix} - {name}".format(prefix=prefix, name=context.Identifier)
+ )
return buffer
@@ -160,7 +218,7 @@ class PrettyPrint:
buffer = []
prefix = " " * level
buffer.append(
- "{prefix}- Name: {name} at {file}:{line}:{column}".format(
+ "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".format(
name=entity.Identifier,
prefix=prefix,
file=entity.Position.Filename.name,
@@ -180,6 +238,14 @@ class PrettyPrint:
for item in entity.DeclaredItems:
for line in self.formatDeclaredItems(item, level + 1):
buffer.append(line)
+ buffer.append("{prefix} Statements:".format(prefix=prefix))
+ for item in entity.Statements:
+ buffer.append("{prefix} ...".format(prefix=prefix))
+ buffer.append("{prefix} Architecures:".format(prefix=prefix))
+ for item in entity.Architectures:
+ buffer.append(
+ "{prefix} - {name}".format(prefix=prefix, name=item.Identifier)
+ )
return buffer
@@ -189,7 +255,7 @@ class PrettyPrint:
buffer = []
prefix = " " * level
buffer.append(
- "{prefix}- Name: {name} at {file}:{line}:{column}".format(
+ "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".format(
name=architecture.Identifier,
prefix=prefix,
file=architecture.Position.Filename.name,
@@ -206,6 +272,15 @@ class PrettyPrint:
for item in architecture.DeclaredItems:
for line in self.formatDeclaredItems(item, level + 2):
buffer.append(line)
+ buffer.append("{prefix} Hierarchy:".format(prefix=prefix))
+ for item in architecture.Statements:
+ for line in self.formatHierarchy(item, level + 2):
+ buffer.append(line)
+ buffer.append("{prefix} Statements:".format(prefix=prefix))
+ for item in architecture.Statements:
+ buffer.append("{prefix} ...".format(prefix=prefix))
+ # for line in self.formatStatements(item, level + 2):
+ # buffer.append(line)
return buffer
@@ -232,7 +307,13 @@ class PrettyPrint:
buffer = []
prefix = " " * level
buffer.append(
- "{prefix}- Name: {name}".format(name=package.Identifier, prefix=prefix)
+ "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".format(
+ name=package.Identifier,
+ prefix=prefix,
+ file=package.Position.Filename.name,
+ line=package.Position.Line,
+ column=package.Position.Column,
+ )
)
buffer.append("{prefix} Declared:".format(prefix=prefix))
for item in package.DeclaredItems:
@@ -307,8 +388,8 @@ class PrettyPrint:
return self.formatGenericType(generic, level)
else:
raise PrettyPrintException(
- "Unhandled generic kind for generic '{name}'.".format(
- name=generic.Identifier
+ "Unhandled generic kind '{kind}' for generic '{name}'.".format(
+ kind=generic.__class__.__name__, name=generic.Identifiers[0]
)
)
@@ -319,7 +400,9 @@ class PrettyPrint:
return self.formatPortSignal(port, level)
else:
raise PrettyPrintException(
- "Unhandled port kind for port '{name}'.".format(name=port.Identifier)
+ "Unhandled port kind '{kind}' for port '{name}'.".format(
+ kind=port.__class__.__name__, name=port.Identifiers[0]
+ )
)
def formatGenericConstant(
@@ -331,10 +414,10 @@ class PrettyPrint:
buffer.append(
"{prefix} - {name} : {mode!s} {subtypeindication}{initialValue}".format(
prefix=prefix,
- name=generic.Identifier,
+ name=", ".join(generic.Identifiers),
mode=generic.Mode,
subtypeindication=self.formatSubtypeIndication(
- generic.Subtype, "generic", generic.Identifier
+ generic.Subtype, "generic", generic.Identifiers[0]
),
initialValue=self.formatInitialValue(generic),
)
@@ -366,10 +449,10 @@ class PrettyPrint:
buffer.append(
"{prefix} - {name} : {mode!s} {subtypeindication}{initialValue}".format(
prefix=prefix,
- name=port.Identifier,
+ name=", ".join(port.Identifiers),
mode=port.Mode,
subtypeindication=self.formatSubtypeIndication(
- port.Subtype, "port", port.Identifier
+ port.Subtype, "port", port.Identifiers[0]
),
initialValue=self.formatInitialValue(port),
)
@@ -381,24 +464,29 @@ class PrettyPrint:
buffer = []
prefix = " " * level
- if isinstance(item, Constant):
+ if isinstance(item, BaseConstant):
+ if isinstance(item, Constant):
+ default = " := {expr}".format(expr=str(item.DefaultExpression))
+ else:
+ default = ""
+
buffer.append(
- "{prefix}- constant {name} : {subtype} := {expr}".format(
+ "{prefix}- constant {name} : {subtype}{default}".format(
prefix=prefix,
- name=item.Identifier,
+ name=", ".join(item.Identifiers),
subtype=self.formatSubtypeIndication(
- item.Subtype, "constant", item.Identifier
+ item.Subtype, "constant", item.Identifiers[0]
),
- expr=str(item.DefaultExpression),
+ default=default,
)
)
elif isinstance(item, SharedVariable):
buffer.append(
"{prefix}- shared variable {name} : {subtype}".format(
prefix=prefix,
- name=item.Identifier,
+ name=", ".join(item.Identifiers),
subtype=self.formatSubtypeIndication(
- item.Subtype, "shared variable", item.Identifier
+ item.Subtype, "shared variable", item.Identifiers[0]
),
)
)
@@ -406,9 +494,9 @@ class PrettyPrint:
buffer.append(
"{prefix}- signal {name} : {subtype}{initValue}".format(
prefix=prefix,
- name=item.Identifier,
+ name=", ".join(item.Identifiers),
subtype=self.formatSubtypeIndication(
- item.Subtype, "signal", item.Identifier
+ item.Subtype, "signal", item.Identifiers[0]
),
initValue=" := {expr}".format(expr=str(item.DefaultExpression))
if item.DefaultExpression is not None
@@ -419,9 +507,9 @@ class PrettyPrint:
buffer.append(
"{prefix}- File {name} : {subtype}".format(
prefix=prefix,
- name=item.Identifier,
+ name=", ".join(item.Identifiers),
subtype=self.formatSubtypeIndication(
- item.Subtype, "file", item.Identifier
+ item.Subtype, "file", item.Identifiers[0]
),
)
)
@@ -477,7 +565,9 @@ class PrettyPrint:
)
elif isinstance(item, UseClause):
buffer.append(
- "{prefix}- use {name!s}".format(prefix=prefix, name=item.Item)
+ "{prefix}- use {names}".format(
+ prefix=prefix, names=", ".join([str(n) for n in item.Names])
+ )
)
elif isinstance(item, Package):
buffer.append(
@@ -558,3 +648,109 @@ class PrettyPrint:
return ""
return " := {expr!s}".format(expr=item.DefaultExpression)
+
+ def formatHierarchy(
+ self, statement: ConcurrentStatement, level: int = 0
+ ) -> StringBuffer:
+ buffer = []
+ prefix = " " * level
+
+ if isinstance(statement, ProcessStatement):
+ buffer.append(
+ "{prefix}- {label}: process(...)".format(
+ prefix=prefix, label=statement.Label
+ )
+ )
+ elif isinstance(statement, EntityInstantiation):
+ buffer.append(
+ "{prefix}- {label}: entity {name}".format(
+ prefix=prefix, label=statement.Label, name=statement.Entity
+ )
+ )
+ elif isinstance(statement, ComponentInstantiation):
+ buffer.append(
+ "{prefix}- {label}: component {name}".format(
+ prefix=prefix, label=statement.Label, name=statement.Component
+ )
+ )
+ elif isinstance(statement, ConfigurationInstantiation):
+ buffer.append(
+ "{prefix}- {label}: configuration {name}".format(
+ prefix=prefix, label=statement.Label, name=statement.Configuration
+ )
+ )
+ elif isinstance(statement, ConcurrentBlockStatement):
+ buffer.append(
+ "{prefix}- {label}: block".format(prefix=prefix, label=statement.Label)
+ )
+ for stmt in statement.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ elif isinstance(statement, IfGenerateStatement):
+ buffer.append(
+ "{prefix}- {label}: if {condition} generate".format(
+ prefix=prefix,
+ label=statement.Label,
+ condition=statement.IfBranch.Condition,
+ )
+ )
+ for stmt in statement.IfBranch.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ for elsifBranch in statement.ElsifBranches:
+ buffer.append(
+ "{prefix} {label}: elsif {condition} generate".format(
+ prefix=prefix,
+ label=statement.Label,
+ condition=elsifBranch.Condition,
+ )
+ )
+ for stmt in elsifBranch.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ if statement.ElseBranch is not None:
+ buffer.append(
+ "{prefix} {label}: else generate".format(
+ prefix=prefix, label=statement.Label
+ )
+ )
+ for stmt in statement.ElseBranch.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ elif isinstance(statement, CaseGenerateStatement):
+ buffer.append(
+ "{prefix}- {label}: case {expression} generate".format(
+ prefix=prefix,
+ label=statement.Label,
+ expression=statement.SelectExpression,
+ )
+ )
+ for case in statement.Cases:
+ buffer.append(
+ "{prefix} {case!s}".format(
+ prefix=prefix, label=case.Label, case=case
+ )
+ )
+ for stmt in case.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ elif isinstance(statement, ForGenerateStatement):
+ buffer.append(
+ "{prefix}- {label}: for {index} in {range} generate".format(
+ prefix=prefix,
+ label=statement.Label,
+ index=statement.LoopIndex,
+ range=statement.Range,
+ )
+ )
+ for stmt in statement.Statements:
+ for line in self.formatHierarchy(stmt, level + 2):
+ buffer.append(line)
+ elif isinstance(statement, ConcurrentProcedureCall):
+ buffer.append(
+ "{prefix}- {label}: {name!s}(...)".format(
+ prefix=prefix, label=statement.Label, name=statement.Procedure
+ )
+ )
+
+ return buffer
diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt
index 66e3025ae..d296f0e96 100644
--- a/pyGHDL/dom/requirements.txt
+++ b/pyGHDL/dom/requirements.txt
@@ -1,4 +1,4 @@
-r ../libghdl/requirements.txt
-pyVHDLModel==0.11.1
+pyVHDLModel==0.11.5
#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel