From ca39821dc013a877a8dbdfabbc3b861eb4d4d2e3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 00:13:11 +0200 Subject: Adjusted to renaming in pyVHDLModel. --- pyGHDL/cli/requirements.txt | 6 +-- pyGHDL/dom/Aggregates.py | 4 +- pyGHDL/dom/Attribute.py | 4 +- pyGHDL/dom/DesignUnit.py | 2 +- pyGHDL/dom/Expression.py | 6 +-- pyGHDL/dom/InterfaceItem.py | 2 +- pyGHDL/dom/Literal.py | 4 +- pyGHDL/dom/Misc.py | 4 +- pyGHDL/dom/Names.py | 4 +- pyGHDL/dom/NonStandard.py | 4 +- pyGHDL/dom/Object.py | 4 +- pyGHDL/dom/PSL.py | 1 - pyGHDL/dom/Range.py | 7 +--- pyGHDL/dom/Subprogram.py | 2 +- pyGHDL/dom/Symbol.py | 2 +- pyGHDL/dom/Type.py | 2 +- pyGHDL/dom/_Translate.py | 10 ++--- pyGHDL/dom/_Utils.py | 8 ++-- pyGHDL/dom/formatting/__init__.py | 32 +++++++++++++++ pyGHDL/dom/formatting/prettyprint.py | 78 +++++++++++++++++++++++++----------- pyGHDL/dom/requirements.txt | 4 +- 21 files changed, 124 insertions(+), 66 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/cli/requirements.txt b/pyGHDL/cli/requirements.txt index 4ea0fb1fd..30f22625c 100644 --- a/pyGHDL/cli/requirements.txt +++ b/pyGHDL/cli/requirements.txt @@ -1,5 +1,5 @@ -r ../dom/requirements.txt -pyAttributes==2.1.0 -pyMetaClasses==1.2.1 -pyTerminalUI==1.3.4 +pyAttributes==2.2.1 +pyMetaClasses==1.3.1 +pyTerminalUI==1.4.1 diff --git a/pyGHDL/dom/Aggregates.py b/pyGHDL/dom/Aggregates.py index 87bc44360..6ca0734e7 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,7 +41,7 @@ This module contains all DOM classes for VHDL's design units (:class:`context . +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ============================================================================ diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 4d6e5dccb..949935b3f 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -1,25 +1,40 @@ +# ============================================================================= +# ____ _ _ ____ _ _ +# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___ +# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \ +# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | | +# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_| +# |_| |___/ +# ============================================================================= +# 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 . +# +# 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 pyVHDLModel.VHDLModel import ( +from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, NamedEntity, PortInterfaceItem, @@ -42,16 +57,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] diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt index 66e3025ae..ca2a796ac 100644 --- a/pyGHDL/dom/requirements.txt +++ b/pyGHDL/dom/requirements.txt @@ -1,4 +1,4 @@ -r ../libghdl/requirements.txt -pyVHDLModel==0.11.1 -#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel +#pyVHDLModel==0.11.2 +https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel -- cgit v1.2.3 From 587ec3d1822b34875c12d7daf79bbc3dfcb13533 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 00:39:26 +0200 Subject: Wrap typeMarks in a SimpleName. --- pyGHDL/dom/_Translate.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 46cb352c7..2cceec4e3 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -348,9 +348,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 +360,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 ) -- cgit v1.2.3 From 7d1f39e542f9ca00bd56b96337fcf82314de538f Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 00:40:36 +0200 Subject: Fixed typo in IIR translation of Greater_Than_Or_Equal_Operator: should be GreaterEqualExpression. --- pyGHDL/dom/_Translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 2cceec4e3..cbe707319 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -425,7 +425,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, -- cgit v1.2.3 From c9e31a5915ad223d35b19a565539eaa586681938 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 00:42:12 +0200 Subject: Adjust DOM to a change in pyVHDLModel: some Identifiers being now a list of identifiers. --- pyGHDL/dom/formatting/prettyprint.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 949935b3f..524ae9ab9 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -363,10 +363,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), ) @@ -398,10 +398,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), ) @@ -428,9 +428,9 @@ class PrettyPrint: 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] ), ) ) @@ -438,9 +438,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 @@ -451,9 +451,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] ), ) ) -- cgit v1.2.3 From 5fae449cbac688b5779f0ef2ec2052bb3f9bed00 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 01:21:36 +0200 Subject: Needed for changes in prettyprint for the Identifier(s) change in pyVHDLModel. --- pyGHDL/dom/_Translate.py | 2 -- pyGHDL/dom/formatting/prettyprint.py | 10 ++++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index cbe707319..adff02041 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -301,8 +301,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) diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 524ae9ab9..20355db24 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -340,7 +340,7 @@ class PrettyPrint: else: raise PrettyPrintException( "Unhandled generic kind for generic '{name}'.".format( - name=generic.Identifier + name=generic.Identifiers[0] ) ) @@ -351,7 +351,9 @@ class PrettyPrint: return self.formatPortSignal(port, level) else: raise PrettyPrintException( - "Unhandled port kind for port '{name}'.".format(name=port.Identifier) + "Unhandled port kind for port '{name}'.".format( + name=port.Identifiers[0] + ) ) def formatGenericConstant( @@ -417,9 +419,9 @@ class PrettyPrint: buffer.append( "{prefix}- constant {name} : {subtype} := {expr}".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), ) -- cgit v1.2.3 From 1a67eb54fc54601dd4945d75d53da87b8e152053 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 02:36:23 +0200 Subject: Handle declarations with multiple identifiers. --- pyGHDL/dom/InterfaceItem.py | 38 ++++++++-------- pyGHDL/dom/_Translate.py | 106 ++++++++++++++++++++++++++++++-------------- 2 files changed, 93 insertions(+), 51 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py index 9f4d1c5e2..fc4e6e5a9 100644 --- a/pyGHDL/dom/InterfaceItem.py +++ b/pyGHDL/dom/InterfaceItem.py @@ -30,6 +30,8 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ +from typing import List + from pydecor import export from pyVHDLModel.SyntaxModel import ( @@ -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, ): - super().__init__(identifier, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @classmethod @@ -79,7 +81,7 @@ 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 +157,12 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): def __init__( self, node: Iir, - identifier: str, + identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: Expression = None, ): - super().__init__(identifier, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @classmethod @@ -176,7 +178,7 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): else None ) - return cls(portNode, name, mode, subtypeIndication, value) + return cls(portNode, [name, ], mode, subtypeIndication, value) @export @@ -186,12 +188,12 @@ class ParameterConstantInterfaceItem( def __init__( self, node: Iir, - identifier: str, + identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: Expression = None, ): - super().__init__(identifier, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @classmethod @@ -209,7 +211,7 @@ class ParameterConstantInterfaceItem( else None ) - return cls(parameterNode, name, mode, subtypeIndication, value) + return cls(parameterNode, [name, ], mode, subtypeIndication, value) @export @@ -219,12 +221,12 @@ class ParameterVariableInterfaceItem( def __init__( self, node: Iir, - identifier: str, + identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: Expression = None, ): - super().__init__(identifier, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @classmethod @@ -242,7 +244,7 @@ class ParameterVariableInterfaceItem( else None ) - return cls(parameterNode, name, mode, subtypeIndication, value) + return cls(parameterNode, [name, ], mode, subtypeIndication, value) @export @@ -250,12 +252,12 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi def __init__( self, node: Iir, - identifier: str, + identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, defaultExpression: Expression = None, ): - super().__init__(identifier, mode, subtype, defaultExpression) + super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @classmethod @@ -273,7 +275,7 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi else None ) - return cls(parameterNode, name, mode, subtypeIndication, value) + return cls(parameterNode, [name, ], mode, subtypeIndication, value) @export @@ -281,10 +283,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 +296,4 @@ class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin) parameterNode, "parameter", name ) - return cls(parameterNode, name, subtypeIndication) + return cls(parameterNode, [name, ], subtypeIndication) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index adff02041..3a10eba3b 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -266,7 +266,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) @@ -309,12 +308,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, @@ -475,45 +470,75 @@ 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) + + if nodes.Get_Has_Identifier_List(generic): + nextNode = nodes.Get_Chain(generic) + for nextGeneric in utils.chain_iter(nextNode): + if nodes.Get_Subtype_Indication(nextGeneric) == nodes.Null_Iir: + genericConstant.Identifiers.append(GetNameOfNode(nextGeneric)) + else: + generic = nextGeneric + break + else: + generic = nodes.Get_Chain(generic) + + yield genericConstant 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 '{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, + ) ) - ) + + 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) + if nodes.Get_Has_Identifier_List(port): + nextNode = nodes.Get_Chain(port) + for nextPort in utils.chain_iter(nextNode): + if nodes.Get_Subtype_Indication(nextPort) == nodes.Null_Iir: + portSignal.Identifiers.append(GetNameOfNode(nextPort)) + else: + port = nextPort + break + else: + port = nodes.Get_Chain(port) + yield portSignal else: position = Position.parse(port) @@ -533,24 +558,26 @@ 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( @@ -564,6 +591,19 @@ def GetParameterFromChainedNodes( ) ) + if nodes.Get_Has_Identifier_List(parameter): + nextNode = nodes.Get_Chain(parameter) + for nextParameter in utils.chain_iter(nextNode): + if nodes.Get_Subtype_Indication(nextParameter) == nodes.Null_Iir: + param.Identifiers.append(GetNameOfNode(nextParameter)) + else: + parameter = nextParameter + break + else: + parameter = nodes.Get_Chain(parameter) + + yield param + def GetDeclaredItemsFromChainedNodes( nodeChain: Iir, entity: str, name: str -- cgit v1.2.3 From 77f969a11ea5ac38f007dbf3aab986dcf10125b0 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 03:11:03 +0200 Subject: Also handle multiple identifiers in signal, variable, object and file declarations. --- pyGHDL/dom/InterfaceItem.py | 58 ++++++++++++-- pyGHDL/dom/Object.py | 85 +++++++++++++++----- pyGHDL/dom/_Translate.py | 190 ++++++++++++++++++++++++-------------------- 3 files changed, 223 insertions(+), 110 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py index fc4e6e5a9..2396ff0c8 100644 --- a/pyGHDL/dom/InterfaceItem.py +++ b/pyGHDL/dom/InterfaceItem.py @@ -81,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, + list( + name, + ), + mode, + subtypeIndication, + value, + ) @export @@ -178,7 +186,15 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): else None ) - return cls(portNode, [name, ], mode, subtypeIndication, value) + return cls( + portNode, + list( + name, + ), + mode, + subtypeIndication, + value, + ) @export @@ -211,7 +227,15 @@ class ParameterConstantInterfaceItem( else None ) - return cls(parameterNode, [name, ], mode, subtypeIndication, value) + return cls( + parameterNode, + list( + name, + ), + mode, + subtypeIndication, + value, + ) @export @@ -244,7 +268,15 @@ class ParameterVariableInterfaceItem( else None ) - return cls(parameterNode, [name, ], mode, subtypeIndication, value) + return cls( + parameterNode, + list( + name, + ), + mode, + subtypeIndication, + value, + ) @export @@ -275,7 +307,15 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi else None ) - return cls(parameterNode, [name, ], mode, subtypeIndication, value) + return cls( + parameterNode, + list( + name, + ), + mode, + subtypeIndication, + value, + ) @export @@ -296,4 +336,10 @@ class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin) parameterNode, "parameter", name ) - return cls(parameterNode, [name, ], subtypeIndication) + return cls( + parameterNode, + list( + name, + ), + subtypeIndication, + ) diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py index 623917661..b14d0094c 100644 --- a/pyGHDL/dom/Object.py +++ b/pyGHDL/dom/Object.py @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from typing import Union +from typing import Union, List from pydecor import export @@ -58,11 +58,11 @@ class Constant(VHDLModel_Constant, DOMMixin): def __init__( self, node: Iir, - identifier: str, + identifiers: List[str], subtype: SubtypeOrSymbol, defaultExpression: Expression, ): - 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, + list( + name, + ), + subtypeIndication, + defaultExpression, + ) else: - return DeferredConstant(constantNode, name, subtypeIndication) + return DeferredConstant( + constantNode, + list( + 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, + list( + 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, ): - 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, + list( + 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, + list( + 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, ): - 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, + list( + 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, + list( + name, + ), + subtypeIndication, + ) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 3a10eba3b..740c613b6 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -490,6 +490,7 @@ def GetGenericsFromChainedNodes( generic = nodes.Get_Chain(generic) yield genericConstant + continue else: if kind == nodes.Iir_Kind.Interface_Type_Declaration: yield GenericTypeInterfaceItem.parse(generic) @@ -512,7 +513,7 @@ def GetGenericsFromChainedNodes( ) ) - generic = nodes.Get_Chain(generic) + generic = nodes.Get_Chain(generic) @export @@ -540,6 +541,7 @@ def GetPortsFromChainedNodes( port = nodes.Get_Chain(port) yield portSignal + continue else: position = Position.parse(port) raise DOMException( @@ -608,109 +610,129 @@ def GetParameterFromChainedNodes( def GetDeclaredItemsFromChainedNodes( nodeChain: Iir, entity: str, name: str ) -> Generator[ModelEntity, None, None]: - for item in utils.chain_iter(nodeChain): + item = nodeChain + 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) + obj = Variable.parse(item) # raise DOMException("Found non-shared variable.") 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: - print( - "[NOT IMPLEMENTED] Configuration specification in {name}".format( - name=name + 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: + 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: + 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.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, + 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, + ) + ) + + item = nodes.Get_Chain(item) + continue + + if nodes.Get_Has_Identifier_List(item): + nextNode = nodes.Get_Chain(item) + for nextItem in utils.chain_iter(nextNode): + if nodes.Get_Subtype_Indication(nextItem) == nodes.Null_Iir: + obj.Identifiers.append(GetNameOfNode(nextItem)) + else: + item = nextItem + break + else: + item = nodes.Get_Chain(item) + + yield obj def GetAliasFromNode(aliasNode: Iir): -- cgit v1.2.3 From 47ec53b54ce661a806f371734754483ef906c563 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 26 Jul 2021 21:38:43 +0200 Subject: Also handle multiple identifiers in record elements. --- pyGHDL/dom/InterfaceItem.py | 24 ++++++++++++------------ pyGHDL/dom/Type.py | 36 +++++++++++++++++++++++++++++++----- pyGHDL/dom/_Translate.py | 8 ++++++++ 3 files changed, 51 insertions(+), 17 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py index 2396ff0c8..3a9c7238f 100644 --- a/pyGHDL/dom/InterfaceItem.py +++ b/pyGHDL/dom/InterfaceItem.py @@ -83,9 +83,9 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMi return cls( genericNode, - list( + [ name, - ), + ], mode, subtypeIndication, value, @@ -188,9 +188,9 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): return cls( portNode, - list( + [ name, - ), + ], mode, subtypeIndication, value, @@ -229,9 +229,9 @@ class ParameterConstantInterfaceItem( return cls( parameterNode, - list( + [ name, - ), + ], mode, subtypeIndication, value, @@ -270,9 +270,9 @@ class ParameterVariableInterfaceItem( return cls( parameterNode, - list( + [ name, - ), + ], mode, subtypeIndication, value, @@ -309,9 +309,9 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi return cls( parameterNode, - list( + [ name, - ), + ], mode, subtypeIndication, value, @@ -338,8 +338,8 @@ class ParameterFileInterfaceItem(VHDLModel_ParameterFileInterfaceItem, DOMMixin) return cls( parameterNode, - list( + [ name, - ), + ], subtypeIndication, ) diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index 64039c147..98b92b3f0 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -52,7 +52,7 @@ from pyVHDLModel.SyntaxModel import ( ) from pyGHDL.libghdl import utils from pyGHDL.libghdl._types import Iir -from pyGHDL.libghdl.vhdl import nodes +from pyGHDL.libghdl.vhdl import nodes, flists from pyGHDL.dom import DOMMixin, DOMException from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode from pyGHDL.dom.Symbol import SimpleSubtypeSymbol @@ -176,8 +176,8 @@ 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 @@ -189,7 +189,13 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin): elementDeclarationNode, "record element", elementName ) - return cls(elementDeclarationNode, elementName, elementType) + return cls( + elementDeclarationNode, + [ + elementName, + ], + elementType, + ) @export @@ -204,8 +210,28 @@ class RecordType(VHDLModel_RecordType, DOMMixin): def parse(cls, typeName: str, typeDefinitionNode: Iir) -> "RecordType": 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 + else: + index += 1 + elements.append(element) return cls(typeDefinitionNode, typeName, elements) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 740c613b6..916f0c8df 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -478,9 +478,11 @@ def GetGenericsFromChainedNodes( 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: @@ -529,9 +531,11 @@ def GetPortsFromChainedNodes( 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: @@ -593,9 +597,11 @@ 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: @@ -721,9 +727,11 @@ def GetDeclaredItemsFromChainedNodes( 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: -- cgit v1.2.3 From de44ee29acb01edfb429eb88d96f0bb904adefd0 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 27 Jul 2021 18:48:08 +0200 Subject: Changed List to Iterable. Parse instantiations. Some SimpleName fixes. --- pyGHDL/dom/Concurrent.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++ pyGHDL/dom/DesignUnit.py | 38 ++++++++------- pyGHDL/dom/_Translate.py | 93 ++++++++++++++++++++++++++++++++++++- 3 files changed, 232 insertions(+), 17 deletions(-) create mode 100644 pyGHDL/dom/Concurrent.py (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py new file mode 100644 index 000000000..80417c07b --- /dev/null +++ b/pyGHDL/dom/Concurrent.py @@ -0,0 +1,118 @@ +# ============================================================================= +# ____ _ _ ____ _ _ +# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___ +# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \ +# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | | +# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_| +# |_| |___/ +# ============================================================================= +# 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 . +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ============================================================================ +from typing import Iterable + +from pydecor import export + +from pyVHDLModel.SyntaxModel import ( + ConcurrentBlockStatement as VHDLModel_ConcurrentBlockStatement, + ComponentInstantiation as VHDLModel_ComponentInstantiation, + EntityInstantiation as VHDLModel_EntityInstantiation, + ConfigurationInstantiation as VHDLModel_ConfigurationInstantiation, + PortInterfaceItem, + ConcurrentStatement, +) + +from pyGHDL.libghdl import Iir +from pyGHDL.libghdl.vhdl import nodes +from pyGHDL.dom import DOMMixin +from pyGHDL.dom.Symbol import EntitySymbol + + +@export +class ComponentInstantiation(VHDLModel_ComponentInstantiation, DOMMixin): + def __init__(self, node: Iir, componentName: str): + super().__init__(componentName) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, instantiationNode: Iir) -> "ComponentInstantiation": + componentName = "" + + return cls(instantiationNode, componentName) + + +@export +class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): + def __init__(self, node: Iir, entityName: EntitySymbol): + super().__init__(entityName) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, instantiationNode: Iir) -> "EntityInstantiation": + entityName = "" + + return cls(instantiationNode, entityName) + + +@export +class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin): + def __init__(self, node: Iir, configurationName: str): + super().__init__(configurationName) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, instantiationNode: Iir) -> "ConfigurationInstantiation": + configurationName = "" + + return cls(instantiationNode, configurationName) + + +@export +class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): + def __init__( + self, + node: Iir, + label: str, + # portItems: Iterable[PortInterfaceItem] = None, + declaredItems: Iterable = None, + bodyItems: Iterable["ConcurrentStatement"] = None, + ): + super().__init__(label, None, declaredItems, bodyItems) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, blockNode: Iir, label: str) -> "ConcurrentBlockStatement": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + ) + + declaredItems = GetDeclaredItemsFromChainedNodes( + nodes.Get_Declaration_Chain(blockNode), "block", label + ) + bodyItems = GetStatementsFromChainedNodes( + nodes.Get_Concurrent_Statement_Chain(blockNode), "block", label + ) + + return cls(blockNode, label, declaredItems, bodyItems) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index 13e197075..d8e816635 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -39,7 +39,7 @@ This module contains all DOM classes for VHDL's design units (:class:`context Generator[ConcurrentStatement, None, None]: + for statement in utils.chain_iter(nodeChain): + label = nodes.Get_Label(statement) + if label != nodes.Null_Iir: + label = name_table.Get_Name_Ptr(label) + + pos = Position.parse(statement) + + kind = GetIirKindOfNode(statement) + if kind == nodes.Iir_Kind.Sensitized_Process_Statement: + print( + "[NOT IMPLEMENTED] Process (label: '{label}') with sensitivity list at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: + print( + "[NOT IMPLEMENTED] Concurrent (simple) signal assignment (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + 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: + entityId = nodes.Get_Entity_Name(instantiatedUnit) + entityName = GetNameFromNode(entityId) + + architectureName = "" + architectureId = nodes.Get_Architecture(instantiatedUnit) + if architectureId != nodes.Null_Iir: + architectureName = GetNameOfNode(architectureId) + + print( + "Instance of '{component!s}({architecture})' with label '{label}' at line {line}".format( + component=entityName, + architecture=architectureName, + label=label, + line=pos.Line, + ) + ) + elif instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Configuration: + configurationId = nodes.Get_Configuration_Name(instantiatedUnit) + configurationName = GetNameFromNode(configurationId) + + print( + "Instance of '{configuration}' with label '{label}' at line {line}".format( + configuration=configurationName, label=label, line=pos.Line + ) + ) + elif instantiatedUnitKind in ( + nodes.Iir_Kind.Simple_Name, + nodes.Iir_Kind.Parenthesis_Name, + ): + componentName = GetNameFromNode(instantiatedUnit) + + print( + "Component '{component}' instantiated with label '{label}' at line {line}".format( + component=componentName, label=label, line=pos.Line + ) + ) + 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) + 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 GetAliasFromNode(aliasNode: Iir): aliasName = GetNameOfNode(aliasNode) -- cgit v1.2.3 From ee933a5fc78353e7a87fe64616b25387fdc12b2b Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 27 Jul 2021 19:02:10 +0200 Subject: Handle more concurrent statements and report as not implemented yet. --- pyGHDL/dom/_Translate.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index eac5476c9..84b99a4a3 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -762,12 +762,36 @@ def GetStatementsFromChainedNodes( label=label, line=pos.Line ) ) + elif kind == nodes.Iir_Kind.Process_Statement: + print( + "[NOT IMPLEMENTED] Process (label: '{label}') without sensitivity list at line {line}".format( + label=label, line=pos.Line + ) + ) elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: print( "[NOT IMPLEMENTED] Concurrent (simple) signal assignment (label: '{label}') at line {line}".format( label=label, line=pos.Line ) ) + 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: + print( + "[NOT IMPLEMENTED] Concurrent procedure call (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) elif kind == nodes.Iir_Kind.Component_Instantiation_Statement: instantiatedUnit = nodes.Get_Instantiated_Unit(statement) instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit) @@ -818,9 +842,32 @@ def GetStatementsFromChainedNodes( column=pos.Column, ) ) - elif kind == nodes.Iir_Kind.Block_Statement: yield ConcurrentBlockStatement.parse(statement, label) + elif kind == nodes.Iir_Kind.If_Generate_Statement: + print( + "[NOT IMPLEMENTED] If-generate statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.For_Generate_Statement: + print( + "[NOT IMPLEMENTED] For-generate statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Case_Generate_Statement: + print( + "[NOT IMPLEMENTED] Case-generate statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + 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( -- cgit v1.2.3 From 20b636decb9c502891fbf5f9a15cf8e7126904a5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 28 Jul 2021 09:00:03 +0200 Subject: Handle instantiations 1/2. --- pyGHDL/dom/Concurrent.py | 48 ++++++++++++++++++++++++++++++------------------ pyGHDL/dom/_Translate.py | 34 ++++++++++++---------------------- 2 files changed, 42 insertions(+), 40 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 80417c07b..2698054e5 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -39,53 +39,65 @@ from pyVHDLModel.SyntaxModel import ( ComponentInstantiation as VHDLModel_ComponentInstantiation, EntityInstantiation as VHDLModel_EntityInstantiation, ConfigurationInstantiation as VHDLModel_ConfigurationInstantiation, - PortInterfaceItem, - ConcurrentStatement, + ConcurrentStatement, Name, ) from pyGHDL.libghdl import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom.Symbol import EntitySymbol +from pyGHDL.dom._Utils import GetNameOfNode @export class ComponentInstantiation(VHDLModel_ComponentInstantiation, DOMMixin): - def __init__(self, node: Iir, componentName: str): - super().__init__(componentName) + def __init__(self, node: Iir, label: str, componentName: Name): + super().__init__(label, componentName) DOMMixin.__init__(self, node) @classmethod - def parse(cls, instantiationNode: Iir) -> "ComponentInstantiation": - componentName = "" + def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ComponentInstantiation": + from pyGHDL.dom._Translate import GetNameFromNode - return cls(instantiationNode, componentName) + componentName = GetNameFromNode(instantiatedUnit) + + return cls(instantiationNode, label, componentName) @export class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): - def __init__(self, node: Iir, entityName: EntitySymbol): - super().__init__(entityName) + def __init__(self, node: Iir, label: str, entityName: Name, architectureName: Name = None): + super().__init__(label, entityName, architectureName) DOMMixin.__init__(self, node) @classmethod - def parse(cls, instantiationNode: Iir) -> "EntityInstantiation": - entityName = "" + def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "EntityInstantiation": + from pyGHDL.dom._Translate import GetNameFromNode + + entityId = nodes.Get_Entity_Name(instantiatedUnit) + entityName = GetNameFromNode(entityId) - return cls(instantiationNode, entityName) + architectureName = None + architectureId = nodes.Get_Architecture(instantiatedUnit) + if architectureId != nodes.Null_Iir: + architectureName = GetNameOfNode(architectureId) + + return cls(instantiationNode, label, entityName, architectureName) @export class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin): - def __init__(self, node: Iir, configurationName: str): - super().__init__(configurationName) + def __init__(self, node: Iir, label: str, configurationName: Name): + super().__init__(label, configurationName) DOMMixin.__init__(self, node) @classmethod - def parse(cls, instantiationNode: Iir) -> "ConfigurationInstantiation": - configurationName = "" + def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ConfigurationInstantiation": + from pyGHDL.dom._Translate import GetNameFromNode + + configurationId = nodes.Get_Configuration_Name(instantiatedUnit) + configurationName = GetNameFromNode(configurationId) - return cls(instantiationNode, configurationName) + return cls(instantiationNode, label, configurationName) @export diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 84b99a4a3..b7e8f5ab9 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -138,7 +138,7 @@ from pyGHDL.dom.Expression import ( MatchingLessEqualExpression, MatchingGreaterThanExpression, ) -from pyGHDL.dom.Concurrent import ConcurrentBlockStatement +from pyGHDL.dom.Concurrent import ConcurrentBlockStatement, EntityInstantiation, ConfigurationInstantiation, ComponentInstantiation from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias from pyGHDL.dom.PSL import DefaultClock @@ -796,40 +796,30 @@ def GetStatementsFromChainedNodes( instantiatedUnit = nodes.Get_Instantiated_Unit(statement) instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit) if instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Entity: - entityId = nodes.Get_Entity_Name(instantiatedUnit) - entityName = GetNameFromNode(entityId) - - architectureName = "" - architectureId = nodes.Get_Architecture(instantiatedUnit) - if architectureId != nodes.Null_Iir: - architectureName = GetNameOfNode(architectureId) + entityInstance = EntityInstantiation.parse(statement, instantiatedUnit, label) print( - "Instance of '{component!s}({architecture})' with label '{label}' at line {line}".format( - component=entityName, - architecture=architectureName, - label=label, + "Entity '{entity!s}({architecture})' instantiated with label '{label}' at line {line}".format( + entity=entityInstance.Entity, + architecture=entityInstance.Architecture, + label=entityInstance.Label, line=pos.Line, ) ) elif instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Configuration: - configurationId = nodes.Get_Configuration_Name(instantiatedUnit) - configurationName = GetNameFromNode(configurationId) + configurationInstance = ConfigurationInstantiation.parse(statement, instantiatedUnit, label) print( - "Instance of '{configuration}' with label '{label}' at line {line}".format( - configuration=configurationName, label=label, line=pos.Line + "Configuration '{configuration}' instantiated with label '{label}' at line {line}".format( + configuration=configurationInstance.Configuration, label=configurationInstance.Label, line=pos.Line ) ) - elif instantiatedUnitKind in ( - nodes.Iir_Kind.Simple_Name, - nodes.Iir_Kind.Parenthesis_Name, - ): - componentName = GetNameFromNode(instantiatedUnit) + elif instantiatedUnitKind == nodes.Iir_Kind.Simple_Name: + configurationInstance = ComponentInstantiation.parse(statement, instantiatedUnit, label) print( "Component '{component}' instantiated with label '{label}' at line {line}".format( - component=componentName, label=label, line=pos.Line + component=configurationInstance.Component, label=label, line=pos.Line ) ) else: -- cgit v1.2.3 From 50f65e4255f62e662d781d01f395c029426c1529 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 28 Jul 2021 23:52:31 +0200 Subject: More handling of concurrent statements. --- pyGHDL/dom/Concurrent.py | 171 ++++++++++++++++++++++++++++++++++++++++++----- pyGHDL/dom/_Translate.py | 72 ++++++-------------- 2 files changed, 178 insertions(+), 65 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 2698054e5..d4e7cf6ff 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -35,42 +35,63 @@ from typing import Iterable from pydecor import export from pyVHDLModel.SyntaxModel import ( - ConcurrentBlockStatement as VHDLModel_ConcurrentBlockStatement, ComponentInstantiation as VHDLModel_ComponentInstantiation, EntityInstantiation as VHDLModel_EntityInstantiation, ConfigurationInstantiation as VHDLModel_ConfigurationInstantiation, - ConcurrentStatement, Name, + ConcurrentBlockStatement as VHDLModel_ConcurrentBlockStatement, + ProcessStatement as VHDLModel_ProcessStatement, + IfGenerateBranch as VHDLModel_IfGenerateBranch, + IfGenerateStatement as VHDLModel_IfGenerateStatement, + CaseGenerateStatement as VHDLModel_CaseGenerateStatement, + ForGenerateStatement as VHDLModel_ForGenerateStatement, + ConcurrentStatement, + Name, + SequentialStatement, + IfGenerateBranch, ) from pyGHDL.libghdl import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode @export class ComponentInstantiation(VHDLModel_ComponentInstantiation, DOMMixin): - def __init__(self, node: Iir, label: str, componentName: Name): + def __init__(self, instantiationNode: Iir, label: str, componentName: Name): super().__init__(label, componentName) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, instantiationNode) @classmethod - def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ComponentInstantiation": + def parse( + cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str + ) -> "ComponentInstantiation": from pyGHDL.dom._Translate import GetNameFromNode componentName = GetNameFromNode(instantiatedUnit) + # TODO: get mapped generics + # TODO: get mapped ports + return cls(instantiationNode, label, componentName) @export class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): - def __init__(self, node: Iir, label: str, entityName: Name, architectureName: Name = None): + def __init__( + self, + instantiationNode: Iir, + label: str, + entityName: Name, + architectureName: Name = None, + ): super().__init__(label, entityName, architectureName) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, instantiationNode) @classmethod - def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "EntityInstantiation": + def parse( + cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str + ) -> "EntityInstantiation": from pyGHDL.dom._Translate import GetNameFromNode entityId = nodes.Get_Entity_Name(instantiatedUnit) @@ -81,22 +102,30 @@ class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): if architectureId != nodes.Null_Iir: architectureName = GetNameOfNode(architectureId) + # TODO: get mapped generics + # TODO: get mapped ports + return cls(instantiationNode, label, entityName, architectureName) @export class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin): - def __init__(self, node: Iir, label: str, configurationName: Name): + def __init__(self, instantiationNode: Iir, label: str, configurationName: Name): super().__init__(label, configurationName) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, instantiationNode) @classmethod - def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ConfigurationInstantiation": + def parse( + cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str + ) -> "ConfigurationInstantiation": from pyGHDL.dom._Translate import GetNameFromNode configurationId = nodes.Get_Configuration_Name(instantiatedUnit) configurationName = GetNameFromNode(configurationId) + # TODO: get mapped generics + # TODO: get mapped ports + return cls(instantiationNode, label, configurationName) @@ -104,14 +133,13 @@ class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin) class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): def __init__( self, - node: Iir, + blockNode: Iir, label: str, - # portItems: Iterable[PortInterfaceItem] = None, declaredItems: Iterable = None, bodyItems: Iterable["ConcurrentStatement"] = None, ): super().__init__(label, None, declaredItems, bodyItems) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, blockNode) @classmethod def parse(cls, blockNode: Iir, label: str) -> "ConcurrentBlockStatement": @@ -128,3 +156,116 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): ) return cls(blockNode, label, declaredItems, bodyItems) + + +@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, + GetStatementsFromChainedNodes, + ) + + # TODO: get sensitivity list + # TODO: get declared items + # TODO: get sequential statements + + declaredItems = None + statements = None + sensitivityList = None + + if hasSensitivityList: + pass + + return cls(processNode, label, declaredItems, statements, sensitivityList) + + +@export +class IfGenerateBranch(VHDLModel_IfGenerateBranch): + def __init__( + self, + branchNode: Iir, + alternativeLabel: str = None, + declaredItems: Iterable = None, + statements: Iterable[ConcurrentStatement] = None, + ): + super().__init__(declaredItems, statements) + DOMMixin.__init__(self, branchNode) + + +@export +class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): + def __init__(self, generateNode: Iir, label: str, ifBranch: IfGenerateBranch): + super().__init__(label, ifBranch) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "IfGenerateStatement": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + ) + + # TODO: get branches + # TODO: get declared items + # TODO: get concurrent statements + + body = nodes.Get_Generate_Statement_Body(generateNode) + alternativeLabelId = nodes.Get_Alternative_Label(body) + alternativeLabel = "" + + declarationChain = nodes.Get_Declaration_Chain(body) + declaredItems = GetDeclaredItemsFromChainedNodes( + declarationChain, "if-generate", label + ) + + statementChain = nodes.Get_Concurrent_Statement_Chain(body) + statements = GetStatementsFromChainedNodes(statementChain, "if-generate", label) + + ifBranch = IfGenerateBranch(body, alternativeLabel, declaredItems, statements) + + return cls(generateNode, label, ifBranch) + + +@export +class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): + def __init__(self, generateNode: Iir, label: str): + super().__init__(label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement": + # TODO: get choices + # TODO: get declared items + # TODO: get concurrent statements + + return cls(generateNode, label) + + +@export +class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): + def __init__(self, generateNode: Iir, label: str): + super().__init__(label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "ForGenerateStatement": + # TODO: get index and range + # TODO: get declared items + # TODO: get concurrent statements + + return cls(generateNode, label) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index b7e8f5ab9..bb96cf8c6 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -138,7 +138,16 @@ from pyGHDL.dom.Expression import ( MatchingLessEqualExpression, MatchingGreaterThanExpression, ) -from pyGHDL.dom.Concurrent import ConcurrentBlockStatement, EntityInstantiation, ConfigurationInstantiation, ComponentInstantiation +from pyGHDL.dom.Concurrent import ( + ConcurrentBlockStatement, + EntityInstantiation, + ConfigurationInstantiation, + ComponentInstantiation, + ProcessStatement, + IfGenerateStatement, + ForGenerateStatement, + CaseGenerateStatement, +) from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias from pyGHDL.dom.PSL import DefaultClock @@ -757,17 +766,11 @@ def GetStatementsFromChainedNodes( kind = GetIirKindOfNode(statement) if kind == nodes.Iir_Kind.Sensitized_Process_Statement: - print( - "[NOT IMPLEMENTED] Process (label: '{label}') with sensitivity list at line {line}".format( - label=label, line=pos.Line - ) - ) + yield ProcessStatement.parse(statement, label, True) + elif kind == nodes.Iir_Kind.Process_Statement: - print( - "[NOT IMPLEMENTED] Process (label: '{label}') without sensitivity list at line {line}".format( - label=label, line=pos.Line - ) - ) + yield ProcessStatement.parse(statement, label, False) + elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: print( "[NOT IMPLEMENTED] Concurrent (simple) signal assignment (label: '{label}') at line {line}".format( @@ -796,32 +799,13 @@ def GetStatementsFromChainedNodes( instantiatedUnit = nodes.Get_Instantiated_Unit(statement) instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit) if instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Entity: - entityInstance = EntityInstantiation.parse(statement, instantiatedUnit, label) - - print( - "Entity '{entity!s}({architecture})' instantiated with label '{label}' at line {line}".format( - entity=entityInstance.Entity, - architecture=entityInstance.Architecture, - label=entityInstance.Label, - line=pos.Line, - ) - ) + yield EntityInstantiation.parse(statement, instantiatedUnit, label) elif instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Configuration: - configurationInstance = ConfigurationInstantiation.parse(statement, instantiatedUnit, label) - - print( - "Configuration '{configuration}' instantiated with label '{label}' at line {line}".format( - configuration=configurationInstance.Configuration, label=configurationInstance.Label, line=pos.Line - ) + yield ConfigurationInstantiation.parse( + statement, instantiatedUnit, label ) elif instantiatedUnitKind == nodes.Iir_Kind.Simple_Name: - configurationInstance = ComponentInstantiation.parse(statement, instantiatedUnit, label) - - print( - "Component '{component}' instantiated with label '{label}' at line {line}".format( - component=configurationInstance.Component, label=label, line=pos.Line - ) - ) + yield ComponentInstantiation.parse(statement, instantiatedUnit, label) else: raise DOMException( "Unknown instantiation kind '{kind}' in instantiation of label {label} at {file}:{line}:{column}.".format( @@ -835,23 +819,11 @@ def GetStatementsFromChainedNodes( elif kind == nodes.Iir_Kind.Block_Statement: yield ConcurrentBlockStatement.parse(statement, label) elif kind == nodes.Iir_Kind.If_Generate_Statement: - print( - "[NOT IMPLEMENTED] If-generate statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) - elif kind == nodes.Iir_Kind.For_Generate_Statement: - print( - "[NOT IMPLEMENTED] For-generate statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield IfGenerateStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Case_Generate_Statement: - print( - "[NOT IMPLEMENTED] Case-generate statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + 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( -- cgit v1.2.3 From cfd625ab0a3d4df24bae77ed6143c44a53f26f49 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 29 Jul 2021 09:00:11 +0200 Subject: Moved parsing into IfGenerateBranch. --- pyGHDL/dom/Concurrent.py | 50 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index d4e7cf6ff..c9a67f1e1 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -48,6 +48,7 @@ from pyVHDLModel.SyntaxModel import ( Name, SequentialStatement, IfGenerateBranch, + Expression, ) from pyGHDL.libghdl import Iir @@ -199,13 +200,40 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): def __init__( self, branchNode: Iir, + condition: Expression, alternativeLabel: str = None, declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, ): - super().__init__(declaredItems, statements) + super().__init__(condition, declaredItems, statements) DOMMixin.__init__(self, branchNode) + @classmethod + def parse(cls, generateNode: Iir) -> "IfGenerateBranch": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) + body = nodes.Get_Generate_Statement_Body(generateNode) + + 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 = GetStatementsFromChainedNodes( + statementChain, "if-generate branch", alternativeLabel + ) + + return cls(body, condition, alternativeLabel, declaredItems, statements) + @export class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): @@ -218,25 +246,21 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetStatementsFromChainedNodes, + GetExpressionFromNode, ) # TODO: get branches # TODO: get declared items # TODO: get concurrent statements - body = nodes.Get_Generate_Statement_Body(generateNode) - alternativeLabelId = nodes.Get_Alternative_Label(body) - alternativeLabel = "" - - declarationChain = nodes.Get_Declaration_Chain(body) - declaredItems = GetDeclaredItemsFromChainedNodes( - declarationChain, "if-generate", label - ) - - statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes(statementChain, "if-generate", label) + print(generateNode, GetIirKindOfNode(generateNode)) + ifBranch = IfGenerateBranch.parse(generateNode) - ifBranch = IfGenerateBranch(body, alternativeLabel, declaredItems, statements) + elseClause = generateNode + while ( + elseClause := nodes.Get_Generate_Else_Clause(elseClause) + ) != nodes.Null_Iir: + print(elseClause, GetIirKindOfNode(elseClause)) return cls(generateNode, label, ifBranch) -- cgit v1.2.3 From 31eb230938730059254bc4778bf1eff14015221f Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 30 Jul 2021 02:14:33 +0200 Subject: Fixed handling of declarations with multiple identifiers, if this is the last item in the chain. --- pyGHDL/dom/_Translate.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index bb96cf8c6..8a76f8a4f 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -499,6 +499,8 @@ def GetGenericsFromChainedNodes( else: generic = nextGeneric break + else: + generic = nodes.Null_Iir else: generic = nodes.Get_Chain(generic) @@ -552,6 +554,8 @@ def GetPortsFromChainedNodes( else: port = nextPort break + else: + port = nodes.Null_Iir else: port = nodes.Get_Chain(port) @@ -618,6 +622,8 @@ def GetParameterFromChainedNodes( else: parameter = nextParameter break + else: + parameter = nodes.Null_Iir else: parameter = nodes.Get_Chain(parameter) @@ -748,6 +754,8 @@ def GetDeclaredItemsFromChainedNodes( else: item = nextItem break + else: + item = nodes.Null_Iir else: item = nodes.Get_Chain(item) -- cgit v1.2.3 From ee6a244880f2d4fff429118ccbce043b342fae4d Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 30 Jul 2021 09:00:16 +0200 Subject: PrettyPrint deferred constants. --- pyGHDL/dom/formatting/prettyprint.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 20355db24..8ab854212 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -41,7 +41,7 @@ from pyVHDLModel.SyntaxModel import ( WithDefaultExpressionMixin, Function, BaseType, - FullType, + FullType, BaseConstant, ) from pyGHDL import GHDLBaseException @@ -79,7 +79,7 @@ from pyGHDL.dom.InterfaceItem import ( PortSignalInterfaceItem, GenericTypeInterfaceItem, ) -from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File +from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File, DeferredConstant from pyGHDL.dom.Attribute import Attribute, AttributeSpecification from pyGHDL.dom.Subprogram import Procedure from pyGHDL.dom.Misc import Alias @@ -415,15 +415,20 @@ 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=", ".join(item.Identifiers), subtype=self.formatSubtypeIndication( item.Subtype, "constant", item.Identifiers[0] ), - expr=str(item.DefaultExpression), + default=default, ) ) elif isinstance(item, SharedVariable): -- cgit v1.2.3 From 7ad5199fef58f8966121adaeda0440b10840ccdd Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 30 Jul 2021 09:00:38 +0200 Subject: Handle parameter '-D' in ghdl-dom. --- pyGHDL/cli/dom.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py index 2d0e85ea9..83ef7c42e 100755 --- a/pyGHDL/cli/dom.py +++ b/pyGHDL/cli/dom.py @@ -296,6 +296,26 @@ class Application(LineTerminal, ArgParseMixin): document.DOMTranslationTime * 10 ** 6, ) ) + elif args.Directory is not None: + d : Path = args.Directory + if not d.exists(): + self.WriteError("Directory '{0!s}' does not exist.".format(d)) + + for file in d.glob("**/*.vhd?"): + self.WriteNormal("Parsing file '{!s}'".format(file)) + document = self.addFile(file, "pretty") + self.WriteInfo( + dedent( + """\ + libghdl processing time: {: 5.3f} us + DOM translation time: {:5.3f} us + """ + ).format( + document.LibGHDLProcessingTime * 10**6, + document.DOMTranslationTime * 10**6, + ) + ) + PP = PrettyPrint() -- cgit v1.2.3 From 8a71357337e46c256f9a243fb574dd78dcec67bc Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 30 Jul 2021 22:42:40 +0200 Subject: Trying to provide a binding for str_table. --- pyGHDL/dom/Literal.py | 4 +-- pyGHDL/libghdl/str_table.py | 60 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 pyGHDL/libghdl/str_table.py (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py index 435563793..5fb31f0e7 100644 --- a/pyGHDL/dom/Literal.py +++ b/pyGHDL/dom/Literal.py @@ -42,7 +42,7 @@ from pyVHDLModel.SyntaxModel 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 @@ -150,5 +150,5 @@ 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) + value = str_table.Get_String8_Ptr(stringID) return cls(literalNode, value) diff --git a/pyGHDL/libghdl/str_table.py b/pyGHDL/libghdl/str_table.py new file mode 100644 index 000000000..4cd138f44 --- /dev/null +++ b/pyGHDL/libghdl/str_table.py @@ -0,0 +1,60 @@ +# ============================================================================= +# ____ _ _ ____ _ _ _ _ _ _ _ +# _ __ _ _ / ___| | | | _ \| | | (_) |__ __ _| |__ __| | | +# | '_ \| | | | | _| |_| | | | | | | | | '_ \ / _` | '_ \ / _` | | +# | |_) | |_| | |_| | _ | |_| | |___ _| | | |_) | (_| | | | | (_| | | +# | .__/ \__, |\____|_| |_|____/|_____(_)_|_|_.__/ \__, |_| |_|\__,_|_| +# |_| |___/ |___/ +# ============================================================================= +# Authors: +# Tristan Gingold +# Patrick Lehmann +# +# Package package: Python binding and low-level API for shared library 'libghdl'. +# +# 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 . +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ============================================================================ +# +from ctypes import c_char_p + +from pydecor import export + +from pyGHDL.libghdl._types import String8Id +from pyGHDL.libghdl._decorator import BindToLibGHDL + + +@export +@BindToLibGHDL("str_table__string8_address") +def _String8_Address(Id: String8Id) -> c_char_p: + """""" + return "" + + +@export +def Get_String8_Ptr(Id: String8Id) -> str: + """ + Get the address of string8 ID. Note that as soon as a character is appended + (using Append_String8) or a string8 is resized (using Resize_String8), an + address previously returned is not valid anymore. + + :param Id: String8Id for the string to query. + :return: String8 as string. + """ + return _String8_Address(Id).decode("utf-8") -- cgit v1.2.3 From 5314281f0b8090f820ae64b652e40c300c2bdec2 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 30 Jul 2021 23:55:18 +0200 Subject: Fixes. --- pyGHDL/cli/dom.py | 7 +++---- pyGHDL/dom/Object.py | 28 ++++++++++++++-------------- pyGHDL/dom/formatting/prettyprint.py | 3 ++- 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py index 83ef7c42e..63350d729 100755 --- a/pyGHDL/cli/dom.py +++ b/pyGHDL/cli/dom.py @@ -297,7 +297,7 @@ class Application(LineTerminal, ArgParseMixin): ) ) elif args.Directory is not None: - d : Path = args.Directory + d: Path = args.Directory if not d.exists(): self.WriteError("Directory '{0!s}' does not exist.".format(d)) @@ -311,12 +311,11 @@ class Application(LineTerminal, ArgParseMixin): DOM translation time: {:5.3f} us """ ).format( - document.LibGHDLProcessingTime * 10**6, - document.DOMTranslationTime * 10**6, + document.LibGHDLProcessingTime * 10 ** 6, + document.DOMTranslationTime * 10 ** 6, ) ) - PP = PrettyPrint() buffer = [] diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py index b14d0094c..b83f352a4 100644 --- a/pyGHDL/dom/Object.py +++ b/pyGHDL/dom/Object.py @@ -80,18 +80,18 @@ class Constant(VHDLModel_Constant, DOMMixin): return cls( constantNode, - list( + [ name, - ), + ], subtypeIndication, defaultExpression, ) else: return DeferredConstant( constantNode, - list( + [ name, - ), + ], subtypeIndication, ) @@ -113,9 +113,9 @@ class DeferredConstant(VHDLModel_DeferredConstant, DOMMixin): return cls( constantNode, - list( + [ name, - ), + ], subtypeIndication, ) @@ -148,9 +148,9 @@ class Variable(VHDLModel_Variable, DOMMixin): return cls( variableNode, - list( + [ name, - ), + ], subtypeIndication, defaultExpression, ) @@ -171,9 +171,9 @@ class SharedVariable(VHDLModel_SharedVariable, DOMMixin): return cls( variableNode, - list( + [ name, - ), + ], subtypeIndication, ) @@ -204,9 +204,9 @@ class Signal(VHDLModel_Signal, DOMMixin): return cls( signalNode, - list( + [ name, - ), + ], subtypeIndication, defaultExpression, ) @@ -229,8 +229,8 @@ class File(VHDLModel_File, DOMMixin): return cls( fileNode, - list( + [ name, - ), + ], subtypeIndication, ) diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 8ab854212..a30258443 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -41,7 +41,8 @@ from pyVHDLModel.SyntaxModel import ( WithDefaultExpressionMixin, Function, BaseType, - FullType, BaseConstant, + FullType, + BaseConstant, ) from pyGHDL import GHDLBaseException -- cgit v1.2.3 From 9e612ed4cacdc6bd1e24b41747c49a3fd9b1f24e Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 1 Aug 2021 20:44:16 +0200 Subject: Another fix for consecutive identifiers. --- pyGHDL/dom/Type.py | 4 ++++ pyGHDL/dom/_Translate.py | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index 98b92b3f0..969ec5643 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -229,6 +229,10 @@ class RecordType(VHDLModel_RecordType, DOMMixin): 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 diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 8a76f8a4f..44915c026 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -499,6 +499,11 @@ def GetGenericsFromChainedNodes( 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: @@ -554,6 +559,11 @@ def GetPortsFromChainedNodes( 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: @@ -622,6 +632,11 @@ def GetParameterFromChainedNodes( 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: @@ -754,6 +769,11 @@ def GetDeclaredItemsFromChainedNodes( 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: -- cgit v1.2.3 From c7f774ff0ade8efe292c00dd6ceb31c42d631278 Mon Sep 17 00:00:00 2001 From: umarcor Date: Mon, 2 Aug 2021 02:04:17 +0200 Subject: FIX pass the length to probably unterminated string extraction (cherry picked from commit afee8309e4b644e0e94c1938c0f4e211ae3038fa) --- pyGHDL/dom/Literal.py | 10 +++++++--- pyGHDL/libghdl/str_table.py | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py index 5fb31f0e7..26be52ec8 100644 --- a/pyGHDL/dom/Literal.py +++ b/pyGHDL/dom/Literal.py @@ -149,6 +149,10 @@ class StringLiteral(VHDLModel_StringLiteral, DOMMixin): @classmethod def parse(cls, literalNode: Iir) -> "StringLiteral": - stringID = nodes.Get_String8_Id(literalNode) - value = str_table.Get_String8_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/libghdl/str_table.py b/pyGHDL/libghdl/str_table.py index 4cd138f44..f87e9db8b 100644 --- a/pyGHDL/libghdl/str_table.py +++ b/pyGHDL/libghdl/str_table.py @@ -48,7 +48,7 @@ def _String8_Address(Id: String8Id) -> c_char_p: @export -def Get_String8_Ptr(Id: String8Id) -> str: +def Get_String8_Ptr(Id: String8Id, Length: int) -> str: """ Get the address of string8 ID. Note that as soon as a character is appended (using Append_String8) or a string8 is resized (using Resize_String8), an @@ -57,4 +57,4 @@ def Get_String8_Ptr(Id: String8Id) -> str: :param Id: String8Id for the string to query. :return: String8 as string. """ - return _String8_Address(Id).decode("utf-8") + return _String8_Address(Id)[:Length].decode("utf-8") -- cgit v1.2.3 From 2a571db9fecf39cc593b0a5666a540ef5cdc39fc Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 2 Aug 2021 03:30:53 +0200 Subject: Disabled Python 3.8 syntax. --- pyGHDL/dom/Concurrent.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index c9a67f1e1..6b07ff3ae 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -44,10 +44,9 @@ from pyVHDLModel.SyntaxModel import ( IfGenerateStatement as VHDLModel_IfGenerateStatement, CaseGenerateStatement as VHDLModel_CaseGenerateStatement, ForGenerateStatement as VHDLModel_ForGenerateStatement, - ConcurrentStatement, Name, + ConcurrentStatement, SequentialStatement, - IfGenerateBranch, Expression, ) @@ -256,12 +255,15 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): print(generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) - elseClause = generateNode - while ( - elseClause := nodes.Get_Generate_Else_Clause(elseClause) - ) != nodes.Null_Iir: +# 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: print(elseClause, GetIirKindOfNode(elseClause)) + elseClause = nodes.Get_Generate_Else_Clause(elseClause) + return cls(generateNode, label, ifBranch) -- cgit v1.2.3 From 407f07a7b3100020bb9f5dbe5863c0b8b45cdd9d Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 2 Aug 2021 11:52:48 +0200 Subject: Added handling of simple concurrent statements. --- pyGHDL/dom/Concurrent.py | 38 +++++++++++++++++++++++++++++++++++--- pyGHDL/dom/_Translate.py | 7 ++----- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 6b07ff3ae..f57f4fa49 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -44,6 +44,7 @@ from pyVHDLModel.SyntaxModel import ( IfGenerateStatement as VHDLModel_IfGenerateStatement, CaseGenerateStatement as VHDLModel_CaseGenerateStatement, ForGenerateStatement as VHDLModel_ForGenerateStatement, + ConcurrentSignalAssignment as VHDLModel_ConcurrentSignalAssignment, Name, ConcurrentStatement, SequentialStatement, @@ -255,9 +256,9 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): print(generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) -# Python 3.8 syntax -# elseClause = generateNode -# while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: + # 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: print(elseClause, GetIirKindOfNode(elseClause)) @@ -295,3 +296,34 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): # TODO: get concurrent statements return cls(generateNode, label) + + +@export +class ConcurrentSimpleSignalAssignment( + VHDLModel_ConcurrentSimpleSignalAssignment, DOMMixin +): + def __init__( + self, + assignmentNode: Iir, + target: Name, + expression: Expression, + label: str = None, + ): + super().__init__(target, expression, label) + 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 = nodes.Get_Waveform_Chain(assignmentNode) + + # TODO: translate waveforms to series of "expressions". + expression = None + + return cls(assignmentNode, targetName, expression, label) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 44915c026..32e2c45f7 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -147,6 +147,7 @@ from pyGHDL.dom.Concurrent import ( IfGenerateStatement, ForGenerateStatement, CaseGenerateStatement, + ConcurrentSignalAssignment, ) from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias @@ -800,11 +801,7 @@ def GetStatementsFromChainedNodes( yield ProcessStatement.parse(statement, label, False) elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: - print( - "[NOT IMPLEMENTED] Concurrent (simple) signal assignment (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield ConcurrentSignalAssignment.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( -- cgit v1.2.3 From c80c2e02dda356e3eb00ae6a097ff62c0f08fc79 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 6 Aug 2021 20:11:33 +0200 Subject: Renamed to ConcurrentSimpleSignalAssignment. --- pyGHDL/dom/Concurrent.py | 2 +- pyGHDL/dom/_Translate.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index f57f4fa49..ab30f9176 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -44,7 +44,7 @@ from pyVHDLModel.SyntaxModel import ( IfGenerateStatement as VHDLModel_IfGenerateStatement, CaseGenerateStatement as VHDLModel_CaseGenerateStatement, ForGenerateStatement as VHDLModel_ForGenerateStatement, - ConcurrentSignalAssignment as VHDLModel_ConcurrentSignalAssignment, + ConcurrentSimpleSignalAssignment as VHDLModel_ConcurrentSimpleSignalAssignment, Name, ConcurrentStatement, SequentialStatement, diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 32e2c45f7..b53b7976e 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -147,7 +147,7 @@ from pyGHDL.dom.Concurrent import ( IfGenerateStatement, ForGenerateStatement, CaseGenerateStatement, - ConcurrentSignalAssignment, + ConcurrentSimpleSignalAssignment, ) from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias @@ -801,7 +801,7 @@ def GetStatementsFromChainedNodes( yield ProcessStatement.parse(statement, label, False) elif kind == nodes.Iir_Kind.Concurrent_Simple_Signal_Assignment: - yield ConcurrentSignalAssignment.parse(statement, label) + 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( -- cgit v1.2.3 From 91392f7951f9a60f50d20c594e3b9c978a4104bc Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 00:39:05 +0200 Subject: Renamed BodyItems to Statements. --- pyGHDL/dom/Concurrent.py | 8 ++++---- pyGHDL/dom/DesignUnit.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index ab30f9176..76ebd12a4 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -137,9 +137,9 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): blockNode: Iir, label: str, declaredItems: Iterable = None, - bodyItems: Iterable["ConcurrentStatement"] = None, + statements: Iterable["ConcurrentStatement"] = None, ): - super().__init__(label, None, declaredItems, bodyItems) + super().__init__(label, None, declaredItems, statements) DOMMixin.__init__(self, blockNode) @classmethod @@ -152,11 +152,11 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(blockNode), "block", label ) - bodyItems = GetStatementsFromChainedNodes( + statements = GetStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(blockNode), "block", label ) - return cls(blockNode, label, declaredItems, bodyItems) + return cls(blockNode, label, declaredItems, statements) @export diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index d8e816635..9c083679d 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -102,9 +102,9 @@ class Entity(VHDLModel_Entity, DOMMixin): genericItems: Iterable[GenericInterfaceItem] = None, portItems: Iterable[PortInterfaceItem] = None, declaredItems: Iterable = None, - bodyItems: Iterable["ConcurrentStatement"] = None, + statements: Iterable["ConcurrentStatement"] = None, ): - super().__init__(identifier, genericItems, portItems, declaredItems, bodyItems) + super().__init__(identifier, genericItems, portItems, declaredItems, statements) DOMMixin.__init__(self, node) @classmethod @@ -115,11 +115,11 @@ class Entity(VHDLModel_Entity, DOMMixin): declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(entityNode), "entity", name ) - bodyItems = GetStatementsFromChainedNodes( + statements = GetStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(entityNode), "entity", name ) - return cls(entityNode, name, generics, ports, declaredItems, bodyItems) + return cls(entityNode, name, generics, ports, declaredItems, statements) @export @@ -130,9 +130,9 @@ class Architecture(VHDLModel_Architecture, DOMMixin): identifier: str, entity: EntityOrSymbol, declaredItems: Iterable = None, - bodyItems: Iterable["ConcurrentStatement"] = None, + statements: Iterable["ConcurrentStatement"] = None, ): - super().__init__(identifier, entity, declaredItems, bodyItems) + super().__init__(identifier, entity, declaredItems, statements) DOMMixin.__init__(self, node) @classmethod @@ -144,11 +144,11 @@ class Architecture(VHDLModel_Architecture, DOMMixin): declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(architectureNode), "architecture", name ) - bodyItems = GetStatementsFromChainedNodes( + statements = GetStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(architectureNode), "architecture", name ) - return cls(architectureNode, name, entity, declaredItems, bodyItems) + return cls(architectureNode, name, entity, declaredItems, statements) def resolve(self): pass -- cgit v1.2.3 From c5411e01a4ca454e8ffbe0a1d92b7bfd2c7d2217 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 00:40:16 +0200 Subject: More for generate statements. --- pyGHDL/dom/Concurrent.py | 91 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 76ebd12a4..4e4240dbf 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -41,6 +41,8 @@ from pyVHDLModel.SyntaxModel import ( ConcurrentBlockStatement as VHDLModel_ConcurrentBlockStatement, ProcessStatement as VHDLModel_ProcessStatement, IfGenerateBranch as VHDLModel_IfGenerateBranch, + ElsifGenerateBranch as VHDLModel_ElsifGenerateBranch, + ElseGenerateBranch as VHDLModel_ElseGenerateBranch, IfGenerateStatement as VHDLModel_IfGenerateStatement, CaseGenerateStatement as VHDLModel_CaseGenerateStatement, ForGenerateStatement as VHDLModel_ForGenerateStatement, @@ -201,11 +203,11 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): self, branchNode: Iir, condition: Expression, - alternativeLabel: str = None, declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, + alternativeLabel: str = None, ): - super().__init__(condition, declaredItems, statements) + super().__init__(condition, declaredItems, statements, alternativeLabel) DOMMixin.__init__(self, branchNode) @classmethod @@ -232,7 +234,85 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): statementChain, "if-generate branch", alternativeLabel ) - return cls(body, condition, alternativeLabel, declaredItems, statements) + return cls(body, condition, declaredItems, statements, alternativeLabel) + + +@export +class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): + def __init__( + self, + branchNode: Iir, + condition: Expression, + 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) -> "ElsifGenerateBranch": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) + body = nodes.Get_Generate_Statement_Body(generateNode) + + 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 = GetStatementsFromChainedNodes( + statementChain, "if-generate branch", alternativeLabel + ) + + return cls(body, 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, + GetStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + body = nodes.Get_Generate_Statement_Body(generateNode) + + 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 = GetStatementsFromChainedNodes( + statementChain, "if-generate branch", alternativeLabel + ) + + return cls(body, declaredItems, statements, alternativeLabel) @export @@ -253,7 +333,7 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): # TODO: get declared items # TODO: get concurrent statements - print(generateNode, GetIirKindOfNode(generateNode)) + print("if branch", generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) # Python 3.8 syntax @@ -261,7 +341,8 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: elseClause = nodes.Get_Generate_Else_Clause(generateNode) while elseClause != nodes.Null_Iir: - print(elseClause, GetIirKindOfNode(elseClause)) + print("els(if) branch", elseClause, GetIirKindOfNode(elseClause)) + ifBranch = ElsifGenerateBranch.parse(generateNode) elseClause = nodes.Get_Generate_Else_Clause(elseClause) -- cgit v1.2.3 From 92c3b2d6cf5835e0aa048a12dcc1e80b36990a4b Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 00:40:45 +0200 Subject: Handle assignments (target and kind). --- pyGHDL/dom/Concurrent.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 4e4240dbf..990fc32c7 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -46,6 +46,7 @@ from pyVHDLModel.SyntaxModel import ( IfGenerateStatement as VHDLModel_IfGenerateStatement, CaseGenerateStatement as VHDLModel_CaseGenerateStatement, ForGenerateStatement as VHDLModel_ForGenerateStatement, + WaveformElement as VHDLModel_WaveformElement, ConcurrentSimpleSignalAssignment as VHDLModel_ConcurrentSimpleSignalAssignment, Name, ConcurrentStatement, @@ -379,6 +380,19 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): return cls(generateNode, label) +@export +class WaveformElement( + VHDLModel_WaveformElement, DOMMixin +): + def __init__( + self, + waveformNode: Iir, + expression: Expression, + after: Expression + ): + super().__init__(expression, after) + DOMMixin.__init__(self, waveformNode) + @export class ConcurrentSimpleSignalAssignment( VHDLModel_ConcurrentSimpleSignalAssignment, DOMMixin @@ -386,11 +400,11 @@ class ConcurrentSimpleSignalAssignment( def __init__( self, assignmentNode: Iir, + label: str, target: Name, - expression: Expression, - label: str = None, + waveform: Iterable[WaveformElement], ): - super().__init__(target, expression, label) + super().__init__(label, target, waveform) DOMMixin.__init__(self, assignmentNode) @classmethod @@ -405,6 +419,6 @@ class ConcurrentSimpleSignalAssignment( waveform = nodes.Get_Waveform_Chain(assignmentNode) # TODO: translate waveforms to series of "expressions". - expression = None + expression = [None] - return cls(assignmentNode, targetName, expression, label) + return cls(assignmentNode, label, targetName, expression) -- cgit v1.2.3 From b543ae7178207a3100e1ae85d5d57b16952165a3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 00:41:15 +0200 Subject: Resolve entity names in architectures to entities. --- pyGHDL/cli/dom.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py index 63350d729..4a9fd0b3c 100755 --- a/pyGHDL/cli/dom.py +++ b/pyGHDL/cli/dom.py @@ -316,6 +316,14 @@ class Application(LineTerminal, ArgParseMixin): ) ) + for library in self._design.Libraries.values(): + for entityName, architectures in library.Architectures.items(): + for entity in library.Entities: + if entity.Identifier == str(entityName): + for architecture in architectures: + entity.Architectures.append(architecture) + + PP = PrettyPrint() buffer = [] -- cgit v1.2.3 From 63cd71d89d9e389299cfb1c2faca35463d6502ee Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 00:41:28 +0200 Subject: Reworked pretty printing. --- pyGHDL/dom/formatting/prettyprint.py | 71 ++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index a30258443..4d6fbb19a 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -34,6 +34,7 @@ from typing import List, Union from pydecor import export +from pyGHDL.dom.Concurrent import ConcurrentBlockStatement, ProcessStatement from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, NamedEntity, @@ -42,7 +43,7 @@ from pyVHDLModel.SyntaxModel import ( Function, BaseType, FullType, - BaseConstant, + BaseConstant, ConcurrentStatement, ) from pyGHDL import GHDLBaseException @@ -107,14 +108,15 @@ 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 @@ -124,33 +126,19 @@ 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 @@ -193,7 +181,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, @@ -213,6 +201,12 @@ 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 @@ -222,7 +216,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, @@ -239,6 +233,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 @@ -265,7 +268,10 @@ 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: @@ -598,3 +604,14 @@ 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, ConcurrentBlockStatement): + buffer.append("{prefix}{label}: block".format(prefix=prefix, label=statement.Label)) + + return buffer -- cgit v1.2.3 From 3f31acc7304b03996f045f39b9e1130a4ffdc330 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 02:55:48 +0200 Subject: Improved pretty-printing for hierarchy. --- pyGHDL/cli/dom.py | 1 - pyGHDL/dom/Concurrent.py | 30 ++++---- pyGHDL/dom/formatting/prettyprint.py | 144 +++++++++++++++++++++++++++++++---- 3 files changed, 144 insertions(+), 31 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py index 4a9fd0b3c..69a0b92ec 100755 --- a/pyGHDL/cli/dom.py +++ b/pyGHDL/cli/dom.py @@ -323,7 +323,6 @@ class Application(LineTerminal, ArgParseMixin): for architecture in architectures: entity.Architectures.append(architecture) - PP = PrettyPrint() buffer = [] diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 990fc32c7..69ae8bdea 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -318,8 +318,15 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): @export class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): - def __init__(self, generateNode: Iir, label: str, ifBranch: IfGenerateBranch): - super().__init__(label, ifBranch) + 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 @@ -337,17 +344,18 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): print("if branch", generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) + elsifBranches = [] + elseBranch = None # 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: - print("els(if) branch", elseClause, GetIirKindOfNode(elseClause)) - ifBranch = ElsifGenerateBranch.parse(generateNode) + elsifBranches.append(ElsifGenerateBranch.parse(generateNode)) elseClause = nodes.Get_Generate_Else_Clause(elseClause) - return cls(generateNode, label, ifBranch) + return cls(generateNode, label, ifBranch, elsifBranches, elseBranch) @export @@ -381,18 +389,12 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @export -class WaveformElement( - VHDLModel_WaveformElement, DOMMixin -): - def __init__( - self, - waveformNode: Iir, - expression: Expression, - after: Expression - ): +class WaveformElement(VHDLModel_WaveformElement, DOMMixin): + def __init__(self, waveformNode: Iir, expression: Expression, after: Expression): super().__init__(expression, after) DOMMixin.__init__(self, waveformNode) + @export class ConcurrentSimpleSignalAssignment( VHDLModel_ConcurrentSimpleSignalAssignment, DOMMixin diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 4d6fbb19a..1aefb570d 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -34,7 +34,16 @@ from typing import List, Union from pydecor import export -from pyGHDL.dom.Concurrent import ConcurrentBlockStatement, ProcessStatement +from pyGHDL.dom.Concurrent import ( + ConcurrentBlockStatement, + ProcessStatement, + IfGenerateStatement, + CaseGenerateStatement, + ForGenerateStatement, + ComponentInstantiation, + ConfigurationInstantiation, + EntityInstantiation, +) from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, NamedEntity, @@ -43,7 +52,8 @@ from pyVHDLModel.SyntaxModel import ( Function, BaseType, FullType, - BaseConstant, ConcurrentStatement, + BaseConstant, + ConcurrentStatement, ) from pyGHDL import GHDLBaseException @@ -108,7 +118,11 @@ class PrettyPrint: prefix = " " * level buffer.append("{prefix}Libraries:".format(prefix=prefix)) for library in design.Libraries.values(): - buffer.append("{prefix} - Name: {name}".format(prefix=prefix, name=library.Identifier)) + 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)) @@ -126,19 +140,41 @@ class PrettyPrint: prefix = " " * level buffer.append("{prefix}Entities:".format(prefix=prefix)) for entity in library.Entities: - buffer.append("{prefix} - {name}({architectures})".format(prefix=prefix, name=entity.Identifier, architectures=", ".join([a.Identifier for a in entity.Architectures]))) + 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): - buffer.append("{prefix} - {name}".format(prefix=prefix, name=package.Identifier)) + 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} - {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: - buffer.append("{prefix} - {name}".format(prefix=prefix, name=configuration.Identifier)) + buffer.append( + "{prefix} - {name}".format( + prefix=prefix, name=configuration.Identifier + ) + ) buffer.append("{prefix}Contexts:".format(prefix=prefix)) for context in library.Contexts: - buffer.append("{prefix} - {name}".format(prefix=prefix, name=context.Identifier)) + buffer.append( + "{prefix} - {name}".format(prefix=prefix, name=context.Identifier) + ) return buffer @@ -206,7 +242,9 @@ class PrettyPrint: 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)) + buffer.append( + "{prefix} - {name}".format(prefix=prefix, name=item.Identifier) + ) return buffer @@ -240,8 +278,8 @@ class PrettyPrint: 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) + # for line in self.formatStatements(item, level + 2): + # buffer.append(line) return buffer @@ -268,10 +306,13 @@ class PrettyPrint: buffer = [] prefix = " " * level buffer.append( - "{prefix}- Name: {name}\n{prefix} File: {file}\n{prefix} Position: {line}:{column}".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,) + column=package.Position.Column, + ) ) buffer.append("{prefix} Declared:".format(prefix=prefix)) for item in package.DeclaredItems: @@ -605,13 +646,84 @@ class PrettyPrint: return " := {expr!s}".format(expr=item.DefaultExpression) - def formatHierarchy(self, statement: ConcurrentStatement, level: int = 0) -> StringBuffer: + 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)) + 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)) + 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 ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + 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 ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + 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 ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + elif isinstance(statement, ForGenerateStatement): + buffer.append( + "{prefix}- {label}: for ... generate".format( + prefix=prefix, label=statement.Label + ) + ) + for stmt in statement.Statements: + for line in self.formatHierarchy(stmt, level + 2): + buffer.append(line) return buffer -- cgit v1.2.3 From 3abbfe34b529af865d6549bb3e6ed47ea1ab1e37 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 03:34:54 +0200 Subject: Improved handling of generate statements and pretty-printing of hierarchy. --- pyGHDL/dom/Concurrent.py | 86 +++++++++++++++++++++--------------- pyGHDL/dom/formatting/prettyprint.py | 19 +++++--- 2 files changed, 64 insertions(+), 41 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 69ae8bdea..6448a748d 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -34,6 +34,7 @@ from typing import Iterable from pydecor import export +from pyGHDL.dom.Range import Range from pyVHDLModel.SyntaxModel import ( ComponentInstantiation as VHDLModel_ComponentInstantiation, EntityInstantiation as VHDLModel_EntityInstantiation, @@ -57,7 +58,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl import Iir from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin -from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode +from pyGHDL.dom._Utils import GetNameOfNode @export @@ -235,7 +236,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): statementChain, "if-generate branch", alternativeLabel ) - return cls(body, condition, declaredItems, statements, alternativeLabel) + return cls(generateNode, condition, declaredItems, statements, alternativeLabel) @export @@ -252,14 +253,14 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir) -> "ElsifGenerateBranch": + def parse(cls, generateNode: Iir, condition: Iir) -> "ElsifGenerateBranch": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetStatementsFromChainedNodes, GetExpressionFromNode, ) - condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) + condition = GetExpressionFromNode(condition) body = nodes.Get_Generate_Statement_Body(generateNode) alternativeLabelId = nodes.Get_Alternative_Label(body) @@ -267,15 +268,15 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): declarationChain = nodes.Get_Declaration_Chain(body) declaredItems = GetDeclaredItemsFromChainedNodes( - declarationChain, "if-generate branch", alternativeLabel + declarationChain, "elsif-generate branch", alternativeLabel ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) statements = GetStatementsFromChainedNodes( - statementChain, "if-generate branch", alternativeLabel + statementChain, "elsif-generate branch", alternativeLabel ) - return cls(body, condition, declaredItems, statements, alternativeLabel) + return cls(generateNode, condition, declaredItems, statements, alternativeLabel) @export @@ -295,7 +296,6 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetStatementsFromChainedNodes, - GetExpressionFromNode, ) body = nodes.Get_Generate_Statement_Body(generateNode) @@ -305,15 +305,15 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): declarationChain = nodes.Get_Declaration_Chain(body) declaredItems = GetDeclaredItemsFromChainedNodes( - declarationChain, "if-generate branch", alternativeLabel + declarationChain, "else-generate branch", alternativeLabel ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) statements = GetStatementsFromChainedNodes( - statementChain, "if-generate branch", alternativeLabel + statementChain, "else-generate branch", alternativeLabel ) - return cls(body, declaredItems, statements, alternativeLabel) + return cls(generateNode, declaredItems, statements, alternativeLabel) @export @@ -331,27 +331,20 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "IfGenerateStatement": - from pyGHDL.dom._Translate import ( - GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, - GetExpressionFromNode, - ) - - # TODO: get branches - # TODO: get declared items - # TODO: get concurrent statements - - print("if branch", generateNode, GetIirKindOfNode(generateNode)) ifBranch = IfGenerateBranch.parse(generateNode) - elsifBranches = [] elseBranch = None - # Python 3.8 syntax - # elseClause = generateNode - # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: + # 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: - elsifBranches.append(ElsifGenerateBranch.parse(generateNode)) + 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) @@ -367,25 +360,48 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement": # TODO: get choices - # TODO: get declared items - # TODO: get concurrent statements return cls(generateNode, label) @export class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): - def __init__(self, generateNode: Iir, label: str): - super().__init__(label) + def __init__( + self, + generateNode: Iir, + label: str, + loopIndex: str, + range: Range, + declaredItems: Iterable = None, + statements: Iterable[ConcurrentStatement] = None, + ): + super().__init__(label, loopIndex, range, declaredItems, statements) DOMMixin.__init__(self, generateNode) @classmethod def parse(cls, generateNode: Iir, label: str) -> "ForGenerateStatement": - # TODO: get index and range - # TODO: get declared items - # TODO: get concurrent statements + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + GetRangeFromNode, + ) - return cls(generateNode, label) + spec = nodes.Get_Parameter_Specification(generateNode) + loopIndex = GetNameOfNode(spec) + rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + 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 = GetStatementsFromChainedNodes( + statementChain, "for-generate", label + ) + + return cls(generateNode, label, loopIndex, rng, declaredItems, statements) @export diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 1aefb570d..d7d5af2f9 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -685,8 +685,10 @@ class PrettyPrint: buffer.append(line) elif isinstance(statement, IfGenerateStatement): buffer.append( - "{prefix}- {label}: if ... generate".format( - prefix=prefix, label=statement.Label + "{prefix}- {label}: if {condition} generate".format( + prefix=prefix, + label=statement.Label, + condition=statement.IfBranch.Condition, ) ) for stmt in statement.IfBranch.Statements: @@ -694,8 +696,10 @@ class PrettyPrint: buffer.append(line) for elsifBranch in statement.ElsifBranches: buffer.append( - "{prefix} {label}: elsif ... generate".format( - prefix=prefix, label=statement.Label + "{prefix} {label}: elsif {condition} generate".format( + prefix=prefix, + label=statement.Label, + condition=elsifBranch.Condition, ) ) for stmt in elsifBranch.Statements: @@ -718,8 +722,11 @@ class PrettyPrint: ) elif isinstance(statement, ForGenerateStatement): buffer.append( - "{prefix}- {label}: for ... generate".format( - prefix=prefix, label=statement.Label + "{prefix}- {label}: for {index} in {range} generate".format( + prefix=prefix, + label=statement.Label, + index=statement.LoopIndex, + range=statement.Range, ) ) for stmt in statement.Statements: -- cgit v1.2.3 From b34f3e885407693a2839771fd469af4ce2b40978 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 11:48:00 +0200 Subject: Improvements for case generate statements. --- pyGHDL/dom/Concurrent.py | 132 +++++++++++++++++++++++++++++++++-- pyGHDL/dom/formatting/prettyprint.py | 13 +++- 2 files changed, 139 insertions(+), 6 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 6448a748d..f493a4c69 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -45,6 +45,10 @@ from pyVHDLModel.SyntaxModel import ( 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, @@ -53,9 +57,10 @@ from pyVHDLModel.SyntaxModel import ( ConcurrentStatement, SequentialStatement, Expression, + ConcurrentChoice, ) -from pyGHDL.libghdl import Iir +from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin from pyGHDL.dom._Utils import GetNameOfNode @@ -351,17 +356,136 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): return cls(generateNode, label, ifBranch, elsifBranches, elseBranch) +@export +class IndexedGenerateChoice(VHDLModel_IndexedGenerateChoice, DOMMixin): + def __init__(self, node: Iir, expression: Expression): + 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]): + super().__init__(choices) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, caseNode: Iir) -> "GenerateCase": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetStatementsFromChainedNodes, + ) + + body = nodes.Get_Generate_Statement_Body(caseNode) + + 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 = GetStatementsFromChainedNodes( + statementChain, "else-generate branch", alternativeLabel + ) + + return cls(caseNode, 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, + GetStatementsFromChainedNodes, + ) + + # body = nodes.Get_Generate_Statement_Body(caseNode) + # + # 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 = GetStatementsFromChainedNodes( + # statementChain, "else-generate branch", alternativeLabel + # ) + + # return cls(caseNode, declaredItems, statements, alternativeLabel) + return cls(caseNode, [], [], "") + + @export class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): - def __init__(self, generateNode: Iir, label: str): - super().__init__(label) + def __init__( + self, generateNode: Iir, label: str, expression: Expression, cases: Iterable + ): + super().__init__(label, expression, cases) DOMMixin.__init__(self, generateNode) @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement": + from pyGHDL.dom._Translate import ( + GetExpressionFromNode, + GetIirKindOfNode, + GetRangeFromNode, + ) + # TODO: get choices - return cls(generateNode, label) + expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) + + cases = [] + choices = [] + alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + for alternative in utils.chain_iter(alternatives): + choiceKind = GetIirKindOfNode(alternative) + + if choiceKind in ( + nodes.Iir_Kind.Choice_By_Name, + nodes.Iir_Kind.Choice_By_Expression, + ): + choiceExpression = GetExpressionFromNode( + nodes.Get_Choice_Expression(alternative) + ) + choices.append(IndexedGenerateChoice(alternative, choiceExpression)) + cases.append(GenerateCase(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Range: + rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + choices.append(RangedGenerateChoice(alternative, rng)) + cases.append(GenerateCase(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Others: + cases.append(OthersGenerateCase.parse(alternative)) + else: + print(choiceKind) + + return cls(generateNode, label, expression, cases) @export diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index d7d5af2f9..bc6744fe8 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -43,6 +43,7 @@ from pyGHDL.dom.Concurrent import ( ComponentInstantiation, ConfigurationInstantiation, EntityInstantiation, + OthersGenerateCase, ) from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, @@ -716,10 +717,18 @@ class PrettyPrint: buffer.append(line) elif isinstance(statement, CaseGenerateStatement): buffer.append( - "{prefix}- {label}: case ... generate".format( - prefix=prefix, label=statement.Label + "{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 + ) + ) elif isinstance(statement, ForGenerateStatement): buffer.append( "{prefix}- {label}: for {index} in {range} generate".format( -- cgit v1.2.3 From bc09bbf10599436e1efdb0432886b2bb8b4bf890 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 11 Aug 2021 15:49:39 +0200 Subject: Support for concurrent procedure call. --- pyGHDL/dom/Concurrent.py | 28 ++++++++++++++++++++++++++++ pyGHDL/dom/_Translate.py | 7 ++----- pyGHDL/dom/formatting/prettyprint.py | 7 +++++++ 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index f493a4c69..afff56747 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -53,6 +53,7 @@ from pyVHDLModel.SyntaxModel import ( ForGenerateStatement as VHDLModel_ForGenerateStatement, WaveformElement as VHDLModel_WaveformElement, ConcurrentSimpleSignalAssignment as VHDLModel_ConcurrentSimpleSignalAssignment, + ConcurrentProcedureCall as VHDLModel_ConcurrentProcedureCall, Name, ConcurrentStatement, SequentialStatement, @@ -564,3 +565,30 @@ class ConcurrentSimpleSignalAssignment( expression = [None] return cls(assignmentNode, label, targetName, expression) + + +@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, callNode: Iir, label: str) -> "ConcurrentProcedureCall": + from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + + call = nodes.Get_Procedure_Call(callNode) + prefix = nodes.Get_Prefix(call) + + procedureName = GetNameFromNode(prefix) + + # TODO: parameter mappings + parameterMappings = [] + + return cls(callNode, label, procedureName, parameterMappings) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index b53b7976e..c8b34ba8c 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -148,6 +148,7 @@ from pyGHDL.dom.Concurrent import ( ForGenerateStatement, CaseGenerateStatement, ConcurrentSimpleSignalAssignment, + ConcurrentProcedureCall, ) from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias @@ -815,11 +816,7 @@ def GetStatementsFromChainedNodes( ) ) elif kind == nodes.Iir_Kind.Concurrent_Procedure_Call_Statement: - print( - "[NOT IMPLEMENTED] Concurrent procedure call (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield ConcurrentProcedureCall.parse(statement, label) elif kind == nodes.Iir_Kind.Component_Instantiation_Statement: instantiatedUnit = nodes.Get_Instantiated_Unit(statement) instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit) diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index bc6744fe8..7fa49389d 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -44,6 +44,7 @@ from pyGHDL.dom.Concurrent import ( ConfigurationInstantiation, EntityInstantiation, OthersGenerateCase, + ConcurrentProcedureCall, ) from pyVHDLModel.SyntaxModel import ( GenericInterfaceItem, @@ -741,5 +742,11 @@ class PrettyPrint: 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 -- cgit v1.2.3 From 357cb9746c53e3f32fc9c2f28686c25e388918c3 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 12 Aug 2021 13:06:11 +0200 Subject: Preparations for sequential statements. --- pyGHDL/dom/Concurrent.py | 59 +++---- pyGHDL/dom/DesignUnit.py | 6 +- pyGHDL/dom/Sequential.py | 388 +++++++++++++++++++++++++++++++++++++++++++++++ pyGHDL/dom/_Translate.py | 50 +++++- 4 files changed, 468 insertions(+), 35 deletions(-) create mode 100644 pyGHDL/dom/Sequential.py (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index afff56747..a23bb8cf6 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -58,7 +58,7 @@ from pyVHDLModel.SyntaxModel import ( ConcurrentStatement, SequentialStatement, Expression, - ConcurrentChoice, + ConcurrentChoice, ConcurrentCase, ) from pyGHDL.libghdl import Iir, utils @@ -156,13 +156,13 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): def parse(cls, blockNode: Iir, label: str) -> "ConcurrentBlockStatement": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, ) declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(blockNode), "block", label ) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(blockNode), "block", label ) @@ -188,19 +188,17 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): ) -> "ProcessStatement": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetSequentialStatementsFromChainedNodes, + GetIirKindOfNode ) - # TODO: get sensitivity list - # TODO: get declared items - # TODO: get sequential statements - - declaredItems = None - statements = None sensitivityList = None - if hasSensitivityList: - pass + 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) @@ -222,7 +220,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): def parse(cls, generateNode: Iir) -> "IfGenerateBranch": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, GetExpressionFromNode, ) @@ -238,7 +236,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( statementChain, "if-generate branch", alternativeLabel ) @@ -262,7 +260,7 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): def parse(cls, generateNode: Iir, condition: Iir) -> "ElsifGenerateBranch": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, GetExpressionFromNode, ) @@ -278,7 +276,7 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( statementChain, "elsif-generate branch", alternativeLabel ) @@ -301,7 +299,7 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): def parse(cls, generateNode: Iir) -> "ElseGenerateBranch": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, ) body = nodes.Get_Generate_Statement_Body(generateNode) @@ -315,7 +313,7 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( statementChain, "else-generate branch", alternativeLabel ) @@ -373,7 +371,10 @@ class RangedGenerateChoice(VHDLModel_RangedGenerateChoice, DOMMixin): @export class GenerateCase(VHDLModel_GenerateCase, DOMMixin): - def __init__(self, node: Iir, choices: Iterable[ConcurrentChoice]): + def __init__(self, node: Iir, choices: Iterable[ConcurrentChoice], + declaredItems: Iterable = None, + statements: Iterable[ConcurrentStatement] = None, + alternativeLabel: str = None,): super().__init__(choices) DOMMixin.__init__(self, node) @@ -381,7 +382,7 @@ class GenerateCase(VHDLModel_GenerateCase, DOMMixin): def parse(cls, caseNode: Iir) -> "GenerateCase": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, ) body = nodes.Get_Generate_Statement_Body(caseNode) @@ -389,17 +390,19 @@ class GenerateCase(VHDLModel_GenerateCase, DOMMixin): alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" + choices = [] + declarationChain = nodes.Get_Declaration_Chain(body) declaredItems = GetDeclaredItemsFromChainedNodes( - declarationChain, "else-generate branch", alternativeLabel + declarationChain, "generate case", alternativeLabel ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes( - statementChain, "else-generate branch", alternativeLabel + statements = GetConcurrentStatementsFromChainedNodes( + statementChain, "generate case", alternativeLabel ) - return cls(caseNode, declaredItems, statements, alternativeLabel) + return cls(caseNode, choices, declaredItems, statements, alternativeLabel) @export @@ -418,7 +421,7 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): def parse(cls, caseNode: Iir) -> "OthersGenerateCase": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, ) # body = nodes.Get_Generate_Statement_Body(caseNode) @@ -443,7 +446,7 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): @export class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): def __init__( - self, generateNode: Iir, label: str, expression: Expression, cases: Iterable + self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[ConcurrentCase] ): super().__init__(label, expression, cases) DOMMixin.__init__(self, generateNode) @@ -507,7 +510,7 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): def parse(cls, generateNode: Iir, label: str) -> "ForGenerateStatement": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, GetRangeFromNode, ) @@ -522,7 +525,7 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): ) statementChain = nodes.Get_Concurrent_Statement_Chain(body) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( statementChain, "for-generate", label ) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index 9c083679d..b7d8ec339 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -68,7 +68,7 @@ from pyGHDL.dom._Translate import ( GetGenericsFromChainedNodes, GetPortsFromChainedNodes, GetDeclaredItemsFromChainedNodes, - GetStatementsFromChainedNodes, + GetConcurrentStatementsFromChainedNodes, ) from pyGHDL.dom.Names import SimpleName from pyGHDL.dom.Symbol import EntitySymbol @@ -115,7 +115,7 @@ class Entity(VHDLModel_Entity, DOMMixin): declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(entityNode), "entity", name ) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(entityNode), "entity", name ) @@ -144,7 +144,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin): declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(architectureNode), "architecture", name ) - statements = GetStatementsFromChainedNodes( + statements = GetConcurrentStatementsFromChainedNodes( nodes.Get_Concurrent_Statement_Chain(architectureNode), "architecture", name ) diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py new file mode 100644 index 000000000..896b09544 --- /dev/null +++ b/pyGHDL/dom/Sequential.py @@ -0,0 +1,388 @@ +# ============================================================================= +# ____ _ _ ____ _ _ +# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___ +# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \ +# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | | +# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_| +# |_| |___/ +# ============================================================================= +# 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 . +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ============================================================================ +from typing import Iterable + +from pydecor import export + +from pyGHDL.dom.Concurrent import WaveformElement # 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, + Name, + SequentialStatement, + Expression, + SequentialChoice, SequentialCase, +) + + +from pyGHDL.libghdl import Iir, utils +from pyGHDL.libghdl.vhdl import nodes +from pyGHDL.dom import DOMMixin +from pyGHDL.dom._Utils import GetNameOfNode + + +@export +class IfBranch(VHDLModel_IfBranch): + def __init__( + self, + branchNode: Iir, + condition: Expression, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(condition, statements) + DOMMixin.__init__(self, branchNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "IfBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "if branch", label + ) + + return cls(generateNode, condition, statements) + + +@export +class ElsifBranch(VHDLModel_ElsifBranch): + def __init__( + self, + branchNode: Iir, + condition: Expression, + statements: Iterable[SequentialStatement] = None, + ): + super().__init__(condition, statements) + DOMMixin.__init__(self, branchNode) + + @classmethod + def parse(cls, generateNode: Iir, condition: Iir, label: str) -> "ElsifBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetExpressionFromNode, + ) + + condition = GetExpressionFromNode(condition) + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "elsif branch", label + ) + + return cls(generateNode, 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, generateNode: Iir, label: str) -> "ElseBranch": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + ) + + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "else branch", label + ) + + return cls(generateNode, statements) + + +@export +class IfStatement(VHDLModel_IfStatement, DOMMixin): + def __init__( + self, + generateNode: Iir, + ifBranch: IfBranch, + elsifBranches: Iterable[ElsifBranch] = None, + elseBranch: ElseBranch = None, + label: str = None, + ): + super().__init__(ifBranch, elsifBranches, elseBranch, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "IfStatement": + ifBranch = IfBranch.parse(generateNode, 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_Generate_Else_Clause(generateNode) + 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_Generate_Else_Clause(elseClause) + + return cls(generateNode, ifBranch, elsifBranches, elseBranch, label) + + +@export +class IndexedChoice(VHDLModel_IndexedChoice, DOMMixin): + def __init__(self, node: Iir, expression: Expression): + 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]): + super().__init__(choices, statements) + DOMMixin.__init__(self, node) + + @classmethod + def parse(cls, caseNode: Iir, label: str) -> "Case": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + ) + + body = nodes.Get_Generate_Statement_Body(caseNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "case", label + ) + + choices = [] + + 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) -> "OthersCase": + from pyGHDL.dom._Translate import ( + GetDeclaredItemsFromChainedNodes, + GetSequentialStatementsFromChainedNodes, + ) + + # body = nodes.Get_Generate_Statement_Body(caseNode) + # + # statementChain = nodes.Get_Sequential_Statement_Chain(body) + # statements = GetStatementsFromChainedNodes( + # statementChain, "else branch", alternativeLabel + # ) + + # return cls(caseNode, declaredItems, statements, alternativeLabel) + return cls(caseNode, [], [], "") + + +@export +class CaseStatement(VHDLModel_CaseStatement, DOMMixin): + def __init__( + self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase] + ): + super().__init__(expression, cases, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + from pyGHDL.dom._Translate import ( + GetExpressionFromNode, + GetIirKindOfNode, + GetRangeFromNode, + ) + + # TODO: get choices + + expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) + + cases = [] + choices = [] + alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + for alternative in utils.chain_iter(alternatives): + choiceKind = GetIirKindOfNode(alternative) + + if choiceKind in ( + nodes.Iir_Kind.Choice_By_Name, + nodes.Iir_Kind.Choice_By_Expression, + ): + choiceExpression = GetExpressionFromNode( + nodes.Get_Choice_Expression(alternative) + ) + choices.append(IndexedChoice(alternative, choiceExpression)) + cases.append(Case(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Range: + rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + choices.append(RangedChoice(alternative, rng)) + cases.append(Case(alternative, choices)) + choices = [] + elif choiceKind is nodes.Iir_Kind.Choice_By_Others: + cases.append(OthersCase.parse(alternative)) + else: + print(choiceKind) + + return cls(generateNode, label, expression, cases) + + +@export +class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): + def __init__( + self, + generateNode: Iir, + loopIndex: str, + range: Range, + statements: Iterable[SequentialStatement] = None, + label: str = None, + ): + super().__init__(loopIndex, range, statements, label) + DOMMixin.__init__(self, generateNode) + + @classmethod + def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + from pyGHDL.dom._Translate import ( + GetSequentialStatementsFromChainedNodes, + GetRangeFromNode, + ) + + spec = nodes.Get_Parameter_Specification(generateNode) + loopIndex = GetNameOfNode(spec) + rng = GetRangeFromNode(nodes.Get_Discrete_Range(spec)) + + body = nodes.Get_Generate_Statement_Body(generateNode) + + statementChain = nodes.Get_Sequential_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "for", label + ) + + return cls(generateNode, 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 = nodes.Get_Waveform_Chain(assignmentNode) + + # TODO: translate waveforms to series of "expressions". + expression = [None] + + return cls(assignmentNode, targetName, expression, label) + + +@export +class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, 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, callNode: Iir, label: str) -> "SequentialProcedureCall": + from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + + call = nodes.Get_Procedure_Call(callNode) + prefix = nodes.Get_Prefix(call) + + procedureName = GetNameFromNode(prefix) + + # TODO: parameter mappings + parameterMappings = [] + + return cls(callNode, label, procedureName, parameterMappings) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index c8b34ba8c..2103064a4 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -45,7 +45,7 @@ from pyVHDLModel.SyntaxModel import ( ParameterInterfaceItem, ModelEntity, Name, - ConcurrentStatement, + ConcurrentStatement, SequentialStatement, ) from pyGHDL.libghdl import utils, name_table @@ -784,13 +784,12 @@ def GetDeclaredItemsFromChainedNodes( yield obj -def GetStatementsFromChainedNodes( +def GetConcurrentStatementsFromChainedNodes( nodeChain: Iir, entity: str, name: str ) -> Generator[ConcurrentStatement, None, None]: for statement in utils.chain_iter(nodeChain): label = nodes.Get_Label(statement) - if label != nodes.Null_Iir: - label = name_table.Get_Name_Ptr(label) + label = name_table.Get_Name_Ptr(label) if label != nodes.Null_Iir else None pos = Position.parse(statement) @@ -865,6 +864,49 @@ def GetStatementsFromChainedNodes( ) +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.Sensitized_Process_Statement: +# yield ProcessStatement.parse(statement, label, True) + if kind == nodes.Iir_Kind.If_Statement: + print( + "[NOT IMPLEMENTED] If statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.For_Loop_Statement: + print( + "[NOT IMPLEMENTED] For-loop statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Case_Statement: + print( + "[NOT IMPLEMENTED] For-loop statement (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 GetAliasFromNode(aliasNode: Iir): aliasName = GetNameOfNode(aliasNode) -- cgit v1.2.3 From c4326161ce97d3286e8dffe31d0c168e05f3f9ea Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 22:21:04 +0200 Subject: Improved handling of ranges (e.g. via attribute names). --- pyGHDL/dom/Concurrent.py | 50 ++++++++++++++++++++++++++++++++++++++++------- pyGHDL/dom/Expression.py | 17 ++++++++++++++++ pyGHDL/dom/Sequential.py | 51 +++++++++++++++++++++++++++++++++++++++++------- pyGHDL/dom/Type.py | 35 ++++++++++++++++++++++++++++----- pyGHDL/dom/_Translate.py | 3 ++- 5 files changed, 136 insertions(+), 20 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index a23bb8cf6..de4e70539 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -58,12 +58,13 @@ from pyVHDLModel.SyntaxModel import ( ConcurrentStatement, SequentialStatement, Expression, - ConcurrentChoice, ConcurrentCase, + ConcurrentChoice, + ConcurrentCase, ) from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes -from pyGHDL.dom import DOMMixin +from pyGHDL.dom import DOMMixin, DOMException, Position from pyGHDL.dom._Utils import GetNameOfNode @@ -186,10 +187,10 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): def parse( cls, processNode: Iir, label: str, hasSensitivityList: bool ) -> "ProcessStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetSequentialStatementsFromChainedNodes, - GetIirKindOfNode ) sensitivityList = None @@ -453,10 +454,11 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseGenerateStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, - GetIirKindOfNode, GetRangeFromNode, + GetNameFromNode, ) # TODO: get choices @@ -480,7 +482,23 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): cases.append(GenerateCase(alternative, choices)) choices = [] elif choiceKind is nodes.Iir_Kind.Choice_By_Range: - rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + 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(generateNode) + raise DOMException( + "Unknown choice range kind '{kind}' in case...generate statement at line {line}.".format( + kind=choiceRangeKind.name, line=pos.Line + ) + ) + choices.append(RangedGenerateChoice(alternative, rng)) cases.append(GenerateCase(alternative, choices)) choices = [] @@ -508,15 +526,33 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @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) - rng = GetRangeFromNode(nodes.Get_Discrete_Range(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) @@ -584,7 +620,7 @@ class ConcurrentProcedureCall(VHDLModel_ConcurrentProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "ConcurrentProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + from pyGHDL.dom._Translate import GetNameFromNode call = nodes.Get_Procedure_Call(callNode) prefix = nodes.Get_Prefix(call) diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py index 83a3f65df..3b871f7dd 100644 --- a/pyGHDL/dom/Expression.py +++ b/pyGHDL/dom/Expression.py @@ -571,6 +571,23 @@ class Aggregate(VHDLModel_Aggregate, DOMMixin): choices.append(IndexedAggregateElement(item, index, value)) elif kind == nodes.Iir_Kind.Choice_By_Range: r = GetRangeFromNode(nodes.Get_Choice_Range(item)) + + 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 + ) + ) + choices.append(RangedAggregateElement(item, r, value)) elif kind == nodes.Iir_Kind.Choice_By_Name: name = GetNameFromNode(nodes.Get_Choice_Name(item)) diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 896b09544..cc5a58d15 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -34,7 +34,7 @@ from typing import Iterable from pydecor import export -from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? +from pyGHDL.dom.Concurrent import WaveformElement # TODO: move out from concurrent? from pyGHDL.dom.Range import Range from pyVHDLModel.SyntaxModel import ( IfBranch as VHDLModel_IfBranch, @@ -52,13 +52,14 @@ from pyVHDLModel.SyntaxModel import ( Name, SequentialStatement, Expression, - SequentialChoice, SequentialCase, + SequentialChoice, + SequentialCase, ) from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes -from pyGHDL.dom import DOMMixin +from pyGHDL.dom import DOMMixin, Position, DOMException from pyGHDL.dom._Utils import GetNameOfNode @@ -257,10 +258,11 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, - GetIirKindOfNode, GetRangeFromNode, + GetNameFromNode, ) # TODO: get choices @@ -284,7 +286,23 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): cases.append(Case(alternative, choices)) choices = [] elif choiceKind is nodes.Iir_Kind.Choice_By_Range: - rng = GetRangeFromNode(nodes.Get_Choice_Range(alternative)) + 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(generateNode) + raise DOMException( + "Unknown choice range kind '{kind}' in case statement at line {line}.".format( + kind=choiceRangeKind.name, line=pos.Line + ) + ) + choices.append(RangedChoice(alternative, rng)) cases.append(Case(alternative, choices)) choices = [] @@ -311,14 +329,32 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): @classmethod def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetRangeFromNode, + GetNameFromNode, ) spec = nodes.Get_Parameter_Specification(generateNode) loopIndex = GetNameOfNode(spec) - rng = GetRangeFromNode(nodes.Get_Discrete_Range(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...loop statement at line {line}.".format( + kind=rangeKind.name, line=pos.Line + ) + ) body = nodes.Get_Generate_Statement_Body(generateNode) @@ -375,7 +411,8 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode, GetIirKindOfNode + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetNameFromNode call = nodes.Get_Procedure_Call(callNode) prefix = nodes.Get_Prefix(call) diff --git a/pyGHDL/dom/Type.py b/pyGHDL/dom/Type.py index 969ec5643..deb315d9d 100644 --- a/pyGHDL/dom/Type.py +++ b/pyGHDL/dom/Type.py @@ -53,8 +53,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl import utils from pyGHDL.libghdl._types import Iir from pyGHDL.libghdl.vhdl import nodes, flists -from pyGHDL.dom import DOMMixin, DOMException -from pyGHDL.dom._Utils import GetNameOfNode, GetIirKindOfNode +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, @@ -182,6 +200,7 @@ class RecordTypeElement(VHDLModel_RecordTypeElement, DOMMixin): @classmethod def parse(cls, elementDeclarationNode: Iir) -> "RecordTypeElement": + from pyGHDL.dom._Utils import GetNameOfNode from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode elementName = GetNameOfNode(elementDeclarationNode) @@ -208,6 +227,8 @@ 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) @@ -251,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)): @@ -273,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) @@ -313,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 2103064a4..6e3a95ea7 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -45,7 +45,8 @@ from pyVHDLModel.SyntaxModel import ( ParameterInterfaceItem, ModelEntity, Name, - ConcurrentStatement, SequentialStatement, + ConcurrentStatement, + SequentialStatement, ) from pyGHDL.libghdl import utils, name_table -- cgit v1.2.3 From edd59b8997c30c8a559d4d7d433631ef03c19546 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 22:36:41 +0200 Subject: Black formatting. --- pyGHDL/dom/Concurrent.py | 24 ++++++++++++++++++------ pyGHDL/dom/Expression.py | 4 ++-- pyGHDL/dom/NonStandard.py | 4 +--- pyGHDL/dom/Sequential.py | 13 +++++++++++-- pyGHDL/dom/_Translate.py | 19 ++++++++----------- 5 files changed, 40 insertions(+), 24 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index de4e70539..685d02287 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -196,10 +196,14 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): sensitivityList = None if hasSensitivityList: sensitivityListNode = nodes.Get_Sensitivity_List(processNode) - print("sensi", GetIirKindOfNode(sensitivityListNode)) + # print("sensi", GetIirKindOfNode(sensitivityListNode)) - declaredItems = GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(processNode), "process", label) - statements = GetSequentialStatementsFromChainedNodes(nodes.Get_Sequential_Statement_Chain(processNode), "process", label) + 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) @@ -372,10 +376,14 @@ class RangedGenerateChoice(VHDLModel_RangedGenerateChoice, DOMMixin): @export class GenerateCase(VHDLModel_GenerateCase, DOMMixin): - def __init__(self, node: Iir, choices: Iterable[ConcurrentChoice], + def __init__( + self, + node: Iir, + choices: Iterable[ConcurrentChoice], declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, - alternativeLabel: str = None,): + alternativeLabel: str = None, + ): super().__init__(choices) DOMMixin.__init__(self, node) @@ -447,7 +455,11 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): @export class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): def __init__( - self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[ConcurrentCase] + self, + generateNode: Iir, + label: str, + expression: Expression, + cases: Iterable[ConcurrentCase], ): super().__init__(label, expression, cases) DOMMixin.__init__(self, generateNode) diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py index 3b871f7dd..e8488b590 100644 --- a/pyGHDL/dom/Expression.py +++ b/pyGHDL/dom/Expression.py @@ -597,8 +597,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/NonStandard.py b/pyGHDL/dom/NonStandard.py index 41f58732f..fe199d58e 100644 --- a/pyGHDL/dom/NonStandard.py +++ b/pyGHDL/dom/NonStandard.py @@ -213,9 +213,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/Sequential.py b/pyGHDL/dom/Sequential.py index cc5a58d15..47caf3c3b 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -198,7 +198,12 @@ class RangedChoice(VHDLModel_RangedChoice, DOMMixin): @export class Case(VHDLModel_Case, DOMMixin): - def __init__(self, node: Iir, choices: Iterable[SequentialChoice], statements: Iterable[SequentialStatement]): + def __init__( + self, + node: Iir, + choices: Iterable[SequentialChoice], + statements: Iterable[SequentialStatement], + ): super().__init__(choices, statements) DOMMixin.__init__(self, node) @@ -251,7 +256,11 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): @export class CaseStatement(VHDLModel_CaseStatement, DOMMixin): def __init__( - self, generateNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase] + self, + generateNode: Iir, + label: str, + expression: Expression, + cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) DOMMixin.__init__(self, generateNode) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 6e3a95ea7..a6ad1ca42 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -200,8 +200,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 ) ) @@ -526,9 +526,8 @@ def GetGenericsFromChainedNodes( 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, + "Unknown generic kind '{kind}' in generic '{generic}' at {file}:{line}:{column}.".format( + kind=kind.name, generic=generic, file=position.Filename, line=position.Line, @@ -577,9 +576,8 @@ def GetPortsFromChainedNodes( 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, @@ -615,9 +613,8 @@ def GetParameterFromChainedNodes( 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, -- cgit v1.2.3 From 16c7b04b252428ebf131ecd4956e099f766d118e Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 22:39:13 +0200 Subject: Preparations for sequential statements. --- pyGHDL/dom/_Translate.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index a6ad1ca42..a4be6a792 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -892,6 +892,45 @@ def GetSequentialStatementsFromChainedNodes( label=label, line=pos.Line ) ) + elif kind == nodes.Iir_Kind.Simple_Signal_Assignment_Statement: + print( + "[NOT IMPLEMENTED] (Simple) signal assignment (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind in ( + nodes.Iir_Kind.Variable_Assignment_Statement, + nodes.Iir_Kind.Conditional_Variable_Assignment_Statement, + ): + print( + "[NOT IMPLEMENTED] Variable assignment (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Wait_Statement: + print( + "[NOT IMPLEMENTED] For-loop statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Procedure_Call_Statement: + print( + "[NOT IMPLEMENTED] Procedure call (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Report_Statement: + print( + "[NOT IMPLEMENTED] Report statement (label: '{label}') at line {line}".format( + label=label, line=pos.Line + ) + ) + elif kind == nodes.Iir_Kind.Assertion_Statement: + print( + "[NOT IMPLEMENTED] Report statement (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( -- cgit v1.2.3 From 05b01cb126a3a18b2e067ea240a271f6de134311 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 23:02:55 +0200 Subject: Some naming cleanups. --- pyGHDL/dom/Sequential.py | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 47caf3c3b..64a87e878 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -75,21 +75,21 @@ class IfBranch(VHDLModel_IfBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "IfBranch": + def parse(cls, branchNode: Iir, label: str) -> "IfBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetExpressionFromNode, ) - condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) - body = nodes.Get_Generate_Statement_Body(generateNode) + condition = GetExpressionFromNode(nodes.Get_Condition(branchNode)) + body = nodes.Get_Generate_Statement_Body(branchNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "if branch", label ) - return cls(generateNode, condition, statements) + return cls(branchNode, condition, statements) @export @@ -104,21 +104,21 @@ class ElsifBranch(VHDLModel_ElsifBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, condition: Iir, label: str) -> "ElsifBranch": + def parse(cls, branchNode: Iir, condition: Iir, label: str) -> "ElsifBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, GetExpressionFromNode, ) condition = GetExpressionFromNode(condition) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(branchNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "elsif branch", label ) - return cls(generateNode, condition, statements) + return cls(branchNode, condition, statements) @export @@ -132,43 +132,43 @@ class ElseBranch(VHDLModel_ElseBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "ElseBranch": + def parse(cls, elseNode: Iir, label: str) -> "ElseBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(elseNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label ) - return cls(generateNode, statements) + return cls(elseNode, statements) @export class IfStatement(VHDLModel_IfStatement, DOMMixin): def __init__( self, - generateNode: Iir, + ifNode: Iir, ifBranch: IfBranch, elsifBranches: Iterable[ElsifBranch] = None, elseBranch: ElseBranch = None, label: str = None, ): super().__init__(ifBranch, elsifBranches, elseBranch, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, ifNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "IfStatement": - ifBranch = IfBranch.parse(generateNode, label) + 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_Generate_Else_Clause(generateNode) + elseClause = nodes.Get_Generate_Else_Clause(ifNode) while elseClause != nodes.Null_Iir: condition = nodes.Get_Condition(elseClause) if condition != nodes.Null_Iir: @@ -179,7 +179,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): elseClause = nodes.Get_Generate_Else_Clause(elseClause) - return cls(generateNode, ifBranch, elsifBranches, elseBranch, label) + return cls(ifNode, ifBranch, elsifBranches, elseBranch, label) @export @@ -257,16 +257,16 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): class CaseStatement(VHDLModel_CaseStatement, DOMMixin): def __init__( self, - generateNode: Iir, + caseNode: Iir, label: str, expression: Expression, cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, caseNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "CaseStatement": + def parse(cls, caseNode: Iir, label: str) -> "CaseStatement": from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetExpressionFromNode, @@ -276,11 +276,11 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): # TODO: get choices - expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) + expression = GetExpressionFromNode(nodes.Get_Expression(caseNode)) cases = [] choices = [] - alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + alternatives = nodes.Get_Case_Statement_Alternative_Chain(caseNode) for alternative in utils.chain_iter(alternatives): choiceKind = GetIirKindOfNode(alternative) @@ -305,7 +305,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ): rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(generateNode) + pos = Position.parse(caseNode) raise DOMException( "Unknown choice range kind '{kind}' in case statement at line {line}.".format( kind=choiceRangeKind.name, line=pos.Line @@ -320,24 +320,24 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): else: print(choiceKind) - return cls(generateNode, label, expression, cases) + return cls(caseNode, label, expression, cases) @export class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): def __init__( self, - generateNode: Iir, + loopNode: Iir, loopIndex: str, range: Range, statements: Iterable[SequentialStatement] = None, label: str = None, ): super().__init__(loopIndex, range, statements, label) - DOMMixin.__init__(self, generateNode) + DOMMixin.__init__(self, loopNode) @classmethod - def parse(cls, generateNode: Iir, label: str) -> "ForLoopStatement": + def parse(cls, loopNode: Iir, label: str) -> "ForLoopStatement": from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, @@ -345,7 +345,7 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): GetNameFromNode, ) - spec = nodes.Get_Parameter_Specification(generateNode) + spec = nodes.Get_Parameter_Specification(loopNode) loopIndex = GetNameOfNode(spec) discreteRange = nodes.Get_Discrete_Range(spec) @@ -358,21 +358,21 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): ): rng = GetNameFromNode(discreteRange) else: - pos = Position.parse(generateNode) + 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 ) ) - body = nodes.Get_Generate_Statement_Body(generateNode) + body = nodes.Get_Generate_Statement_Body(loopNode) statementChain = nodes.Get_Sequential_Statement_Chain(body) statements = GetSequentialStatementsFromChainedNodes( statementChain, "for", label ) - return cls(generateNode, loopIndex, rng, statements, label) + return cls(loopNode, loopIndex, rng, statements, label) @export -- cgit v1.2.3 From 6bd13c9f82e2b06bebdea8fc82a83604d5d500d1 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Fri, 13 Aug 2021 23:12:20 +0200 Subject: Fixed missed adjustments to range in expressions. --- pyGHDL/dom/Expression.py | 15 +++++++-------- pyGHDL/dom/_Translate.py | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py index e8488b590..3769b9fb6 100644 --- a/pyGHDL/dom/Expression.py +++ b/pyGHDL/dom/Expression.py @@ -92,7 +92,7 @@ from pyVHDLModel.SyntaxModel 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 import DOMMixin, DOMException, Position from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom.Symbol import SimpleSubtypeSymbol from pyGHDL.dom.Aggregates import ( @@ -570,25 +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)) - - rangeKind = GetIirKindOfNode(discreteRange) + choiceRange = nodes.Get_Choice_Range(item) + rangeKind = GetIirKindOfNode(choiceRange) if rangeKind == nodes.Iir_Kind.Range_Expression: - rng = GetRangeFromNode(discreteRange) + rng = GetRangeFromNode(choiceRange) elif rangeKind in ( nodes.Iir_Kind.Attribute_Name, nodes.Iir_Kind.Parenthesis_Name, ): - rng = GetNameFromNode(discreteRange) + rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(generateNode) + 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, r, value)) + 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) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index a4be6a792..f5f2eda3e 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -872,8 +872,8 @@ def GetSequentialStatementsFromChainedNodes( pos = Position.parse(statement) kind = GetIirKindOfNode(statement) -# if kind == nodes.Iir_Kind.Sensitized_Process_Statement: -# yield ProcessStatement.parse(statement, label, True) + # if kind == nodes.Iir_Kind.Sensitized_Process_Statement: + # yield ProcessStatement.parse(statement, label, True) if kind == nodes.Iir_Kind.If_Statement: print( "[NOT IMPLEMENTED] If statement (label: '{label}') at line {line}".format( -- cgit v1.2.3 From 9d3e58db06faa9e204606b8ea6e7fc6cca6dbbab Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 14 Aug 2021 21:40:38 +0200 Subject: Handle multiple choices per case. --- pyGHDL/dom/Concurrent.py | 52 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 11 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 685d02287..3b1f22829 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -478,10 +478,13 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) cases = [] - choices = [] - alternatives = nodes.Get_Case_Statement_Alternative_Chain(generateNode) - for alternative in utils.chain_iter(alternatives): + choices = None + alternative = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + + while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) + sameAlternative = nodes.Get_Same_Alternative_Flag(alternative) + print("sameAlternative: ", sameAlternative) if choiceKind in ( nodes.Iir_Kind.Choice_By_Name, @@ -490,9 +493,12 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): choiceExpression = GetExpressionFromNode( nodes.Get_Choice_Expression(alternative) ) - choices.append(IndexedGenerateChoice(alternative, choiceExpression)) - cases.append(GenerateCase(alternative, choices)) - choices = [] + + 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) @@ -504,20 +510,44 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): ): rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(generateNode) + 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 ) ) - choices.append(RangedGenerateChoice(alternative, rng)) - cases.append(GenerateCase(alternative, choices)) - choices = [] + 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(alternative, choices)) + choices = None cases.append(OthersGenerateCase.parse(alternative)) + alternative = nodes.Get_Chain(alternative) + continue else: - print(choiceKind) + 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(alternative, choices)) + + choices = [ + choice, + ] + + alternative = nodes.Get_Chain(alternative) + + if choices is not None: + cases.append(GenerateCase(alternative, choices)) return cls(generateNode, label, expression, cases) -- cgit v1.2.3 From 0562c182aba6e99cbdeb302f6efa584d6642267f Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sat, 14 Aug 2021 21:58:48 +0200 Subject: Handle bodies in case generate statements. --- pyGHDL/dom/Concurrent.py | 52 +++++++++++++++++++----------------- pyGHDL/dom/formatting/prettyprint.py | 3 +++ 2 files changed, 30 insertions(+), 25 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 3b1f22829..b411553c5 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -384,23 +384,23 @@ class GenerateCase(VHDLModel_GenerateCase, DOMMixin): statements: Iterable[ConcurrentStatement] = None, alternativeLabel: str = None, ): - super().__init__(choices) + super().__init__(choices, declaredItems, statements, alternativeLabel) DOMMixin.__init__(self, node) @classmethod - def parse(cls, caseNode: Iir) -> "GenerateCase": + def parse( + cls, caseNode: Iir, choices: Iterable[ConcurrentChoice] + ) -> "GenerateCase": from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetConcurrentStatementsFromChainedNodes, ) - body = nodes.Get_Generate_Statement_Body(caseNode) + body = nodes.Get_Associated_Block(caseNode) alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" - choices = [] - declarationChain = nodes.Get_Declaration_Chain(body) declaredItems = GetDeclaredItemsFromChainedNodes( declarationChain, "generate case", alternativeLabel @@ -433,23 +433,22 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): GetConcurrentStatementsFromChainedNodes, ) - # body = nodes.Get_Generate_Statement_Body(caseNode) - # - # 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 = GetStatementsFromChainedNodes( - # statementChain, "else-generate branch", alternativeLabel - # ) - - # return cls(caseNode, declaredItems, statements, alternativeLabel) - return cls(caseNode, [], [], "") + body = nodes.Get_Associated_Block(caseNode) + + 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 @@ -480,6 +479,7 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): cases = [] choices = None alternative = nodes.Get_Case_Statement_Alternative_Chain(generateNode) + caseNode = alternative while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) @@ -524,10 +524,11 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): continue elif choiceKind is nodes.Iir_Kind.Choice_By_Others: if choices is not None: - cases.append(GenerateCase(alternative, choices)) + cases.append(GenerateCase.parse(caseNode, choices)) choices = None cases.append(OthersGenerateCase.parse(alternative)) alternative = nodes.Get_Chain(alternative) + caseNode = alternative continue else: pos = Position.parse(alternative) @@ -538,8 +539,9 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): ) if choices is not None: - cases.append(GenerateCase(alternative, choices)) + cases.append(GenerateCase.parse(caseNode, choices)) + caseNode = alternative choices = [ choice, ] @@ -547,7 +549,7 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): alternative = nodes.Get_Chain(alternative) if choices is not None: - cases.append(GenerateCase(alternative, choices)) + cases.append(GenerateCase.parse(caseNode, choices)) return cls(generateNode, label, expression, cases) diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 7fa49389d..2f582a5f8 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -730,6 +730,9 @@ class PrettyPrint: 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( -- cgit v1.2.3 From c74c26bbb6b58e0cf7fba78e382f0949240b7721 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 17:43:29 +0200 Subject: Handle if-statements. --- pyGHDL/dom/Sequential.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 64a87e878..6e04b9a04 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -82,9 +82,7 @@ class IfBranch(VHDLModel_IfBranch): ) condition = GetExpressionFromNode(nodes.Get_Condition(branchNode)) - body = nodes.Get_Generate_Statement_Body(branchNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "if branch", label ) @@ -111,9 +109,7 @@ class ElsifBranch(VHDLModel_ElsifBranch): ) condition = GetExpressionFromNode(condition) - body = nodes.Get_Generate_Statement_Body(branchNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "elsif branch", label ) @@ -132,19 +128,16 @@ class ElseBranch(VHDLModel_ElseBranch): DOMMixin.__init__(self, branchNode) @classmethod - def parse(cls, elseNode: Iir, label: str) -> "ElseBranch": + def parse(cls, branchNode: Iir, label: str) -> "ElseBranch": from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) - - body = nodes.Get_Generate_Statement_Body(elseNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label ) - return cls(elseNode, statements) + return cls(branchNode, statements) @export @@ -168,7 +161,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): # WORKAROUND: Python 3.8 syntax # elseClause = generateNode # while (elseClause := nodes.Get_Generate_Else_Clause(elseClause)) != nodes.Null_Iir: - elseClause = nodes.Get_Generate_Else_Clause(ifNode) + elseClause = nodes.Get_Else_Clause(ifNode) while elseClause != nodes.Null_Iir: condition = nodes.Get_Condition(elseClause) if condition != nodes.Null_Iir: @@ -177,7 +170,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): elseBranch = ElseBranch.parse(elseClause, label) break - elseClause = nodes.Get_Generate_Else_Clause(elseClause) + elseClause = nodes.Get_Else_Clause(elseClause) return cls(ifNode, ifBranch, elsifBranches, elseBranch, label) -- cgit v1.2.3 From db48ba4042769646676f7ffb981149cbb5e52740 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 18:06:59 +0200 Subject: Implemented if, case and for-loop statements. --- pyGHDL/dom/Concurrent.py | 9 ++-- pyGHDL/dom/DesignUnit.py | 15 +++++-- pyGHDL/dom/Sequential.py | 106 ++++++++++++++++++++++++++++++----------------- pyGHDL/dom/_Translate.py | 21 ++-------- 4 files changed, 88 insertions(+), 63 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index b411553c5..953d4d6e3 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -232,6 +232,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): condition = GetExpressionFromNode(nodes.Get_Condition(generateNode)) body = nodes.Get_Generate_Statement_Body(generateNode) + # TODO: alternative label alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" @@ -272,6 +273,7 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): condition = GetExpressionFromNode(condition) body = nodes.Get_Generate_Statement_Body(generateNode) + # TODO: alternative label alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" @@ -309,6 +311,7 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): body = nodes.Get_Generate_Statement_Body(generateNode) + # TODO: alternative label alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" @@ -398,6 +401,7 @@ class GenerateCase(VHDLModel_GenerateCase, DOMMixin): body = nodes.Get_Associated_Block(caseNode) + # TODO: alternative label alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" @@ -435,6 +439,7 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): body = nodes.Get_Associated_Block(caseNode) + # TODO: alternative label alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" @@ -472,8 +477,6 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): GetNameFromNode, ) - # TODO: get choices - expression = GetExpressionFromNode(nodes.Get_Expression(generateNode)) cases = [] @@ -524,7 +527,7 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): continue elif choiceKind is nodes.Iir_Kind.Choice_By_Others: if choices is not None: - cases.append(GenerateCase.parse(caseNode, choices)) + cases.append(GenerateCase.parse(alternative, choices)) choices = None cases.append(OthersGenerateCase.parse(alternative)) alternative = nodes.Get_Chain(alternative) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index b7d8ec339..e8dfccbd7 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -119,6 +119,8 @@ class Entity(VHDLModel_Entity, DOMMixin): nodes.Get_Concurrent_Statement_Chain(entityNode), "entity", name ) + # FIXME: read use clauses + return cls(entityNode, name, generics, ports, declaredItems, statements) @@ -148,10 +150,9 @@ class Architecture(VHDLModel_Architecture, DOMMixin): nodes.Get_Concurrent_Statement_Chain(architectureNode), "architecture", name ) - return cls(architectureNode, name, entity, declaredItems, statements) + # FIXME: read use clauses - def resolve(self): - pass + return cls(architectureNode, name, entity, declaredItems, statements) @export @@ -203,6 +204,8 @@ class Package(VHDLModel_Package, DOMMixin): nodes.Get_Declaration_Chain(packageNode), "package", name ) + # FIXME: read use clauses + return cls(packageNode, name, generics, declaredItems) @@ -224,6 +227,8 @@ class PackageBody(VHDLModel_PackageBody, DOMMixin): nodes.Get_Declaration_Chain(packageBodyNode), "package", name ) + # FIXME: read use clauses + return cls(packageBodyNode, name, declaredItems) @@ -244,6 +249,7 @@ 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 @@ -283,6 +289,7 @@ class Configuration(VHDLModel_Configuration, DOMMixin): def parse(cls, configurationNode: Iir): name = GetNameOfNode(configurationNode) - # FIXME: needs an implementation + # FIXME: read use clauses + # FIXME: read specifications return cls(configurationNode, name) diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 6e04b9a04..0503eca25 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -132,6 +132,7 @@ class ElseBranch(VHDLModel_ElseBranch): from pyGHDL.dom._Translate import ( GetSequentialStatementsFromChainedNodes, ) + statementChain = nodes.Get_Sequential_Statement_Chain(branchNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "else branch", label @@ -195,26 +196,26 @@ class Case(VHDLModel_Case, DOMMixin): self, node: Iir, choices: Iterable[SequentialChoice], - statements: Iterable[SequentialStatement], + statements: Iterable[SequentialStatement] = None, ): super().__init__(choices, statements) DOMMixin.__init__(self, node) @classmethod - def parse(cls, caseNode: Iir, label: str) -> "Case": - from pyGHDL.dom._Translate import ( - GetSequentialStatementsFromChainedNodes, - ) + def parse( + cls, caseNode: Iir, choices: Iterable[SequentialChoice], label: str + ) -> "Case": + from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - body = nodes.Get_Generate_Statement_Body(caseNode) + block = nodes.Get_Associated_Block(caseNode) + if block is nodes.Null_Iir: + return cls(caseNode, choices) - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(block) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) - choices = [] - return cls(caseNode, choices, statements) @@ -229,21 +230,19 @@ class OthersCase(VHDLModel_OthersCase, DOMMixin): DOMMixin.__init__(self, caseNode) @classmethod - def parse(cls, caseNode: Iir) -> "OthersCase": - from pyGHDL.dom._Translate import ( - GetDeclaredItemsFromChainedNodes, - GetSequentialStatementsFromChainedNodes, - ) + def parse(cls, caseNode: Iir, label: str = None) -> "OthersCase": + from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - # body = nodes.Get_Generate_Statement_Body(caseNode) - # - # statementChain = nodes.Get_Sequential_Statement_Chain(body) - # statements = GetStatementsFromChainedNodes( - # statementChain, "else branch", alternativeLabel - # ) + body = nodes.Get_Associated_Block(caseNode) + if body is nodes.Null_Iir: + return cls(caseNode) - # return cls(caseNode, declaredItems, statements, alternativeLabel) - return cls(caseNode, [], [], "") + statementChain = nodes.Get_Concurrent_Statement_Chain(body) + statements = GetSequentialStatementsFromChainedNodes( + statementChain, "case others", label + ) + + return cls(caseNode, statements) @export @@ -267,15 +266,17 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): GetNameFromNode, ) - # TODO: get choices - expression = GetExpressionFromNode(nodes.Get_Expression(caseNode)) cases = [] - choices = [] - alternatives = nodes.Get_Case_Statement_Alternative_Chain(caseNode) - for alternative in utils.chain_iter(alternatives): + choices = None + alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode) + caseNode = alternative + + while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) + sameAlternative = nodes.Get_Same_Alternative_Flag(alternative) + print("sameAlternative: ", sameAlternative) if choiceKind in ( nodes.Iir_Kind.Choice_By_Name, @@ -284,9 +285,12 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): choiceExpression = GetExpressionFromNode( nodes.Get_Choice_Expression(alternative) ) - choices.append(IndexedChoice(alternative, choiceExpression)) - cases.append(Case(alternative, choices)) - choices = [] + + 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) @@ -298,20 +302,46 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ): rng = GetNameFromNode(choiceRange) else: - pos = Position.parse(caseNode) + pos = Position.parse(alternative) raise DOMException( "Unknown choice range kind '{kind}' in case statement at line {line}.".format( kind=choiceRangeKind.name, line=pos.Line ) ) - choices.append(RangedChoice(alternative, rng)) - cases.append(Case(alternative, choices)) - choices = [] + choice = RangedChoice(alternative, rng) + if sameAlternative: + choices.append(choice) + alternative = nodes.Get_Chain(alternative) + continue elif choiceKind is nodes.Iir_Kind.Choice_By_Others: - cases.append(OthersCase.parse(alternative)) + 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) + caseNode = alternative + continue else: - print(choiceKind) + 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(alternative, choices, label)) + + caseNode = alternative + choices = [ + choice, + ] + + alternative = nodes.Get_Chain(alternative) + + if choices is not None: + cases.append(Case.parse(alternative, choices, label)) return cls(caseNode, label, expression, cases) @@ -358,9 +388,7 @@ class ForLoopStatement(VHDLModel_ForLoopStatement, DOMMixin): ) ) - body = nodes.Get_Generate_Statement_Body(loopNode) - - statementChain = nodes.Get_Sequential_Statement_Chain(body) + statementChain = nodes.Get_Sequential_Statement_Chain(loopNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "for", label ) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index f5f2eda3e..18a4d9fda 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -34,6 +34,7 @@ from typing import List, Generator from pydecor import export +from pyGHDL.dom.Sequential import IfStatement, ForLoopStatement, CaseStatement from pyVHDLModel.SyntaxModel import ( Constraint, Direction, @@ -872,26 +873,12 @@ def GetSequentialStatementsFromChainedNodes( pos = Position.parse(statement) kind = GetIirKindOfNode(statement) - # if kind == nodes.Iir_Kind.Sensitized_Process_Statement: - # yield ProcessStatement.parse(statement, label, True) if kind == nodes.Iir_Kind.If_Statement: - print( - "[NOT IMPLEMENTED] If statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield IfStatement.parse(statement, label) elif kind == nodes.Iir_Kind.For_Loop_Statement: - print( - "[NOT IMPLEMENTED] For-loop statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield ForLoopStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Case_Statement: - print( - "[NOT IMPLEMENTED] For-loop statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield CaseStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Simple_Signal_Assignment_Statement: print( "[NOT IMPLEMENTED] (Simple) signal assignment (label: '{label}') at line {line}".format( -- cgit v1.2.3 From 3f0308a5f807269aa5691fa1c704c0e9147d45f1 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 16 Aug 2021 23:47:04 +0200 Subject: Handle contexts. --- pyGHDL/dom/Concurrent.py | 1 - pyGHDL/dom/DesignUnit.py | 95 ++++++++++++++++++++++++++---------- pyGHDL/dom/NonStandard.py | 40 ++++++++++++--- pyGHDL/dom/Sequential.py | 1 - pyGHDL/dom/_Translate.py | 2 +- pyGHDL/dom/formatting/prettyprint.py | 8 +-- 6 files changed, 108 insertions(+), 39 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 953d4d6e3..f4ded4e80 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -487,7 +487,6 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) sameAlternative = nodes.Get_Same_Alternative_Flag(alternative) - print("sameAlternative: ", sameAlternative) if choiceKind in ( nodes.Iir_Kind.Choice_By_Name, diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index e8dfccbd7..c905a439d 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -41,9 +41,11 @@ This module contains all DOM classes for VHDL's design units (:class:`context Date: Mon, 16 Aug 2021 23:56:16 +0200 Subject: Handle context references. --- pyGHDL/dom/DesignUnit.py | 26 ++++++++++++++++++++++---- pyGHDL/dom/NonStandard.py | 3 +++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index c905a439d..7f4d8e964 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -47,6 +47,7 @@ from pydecor import export 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, @@ -82,16 +83,16 @@ __all__ = [] @export class LibraryClause(VHDLModel_LibraryClause, DOMMixin): - def __init__(self, node: Iir, names: Iterable[Name]): + def __init__(self, libraryNode: Iir, names: Iterable[Name]): super().__init__(names) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, libraryNode) @export class UseClause(VHDLModel_UseClause, DOMMixin): - def __init__(self, node: Iir, names: Iterable[Name]): + def __init__(self, useNode: Iir, names: Iterable[Name]): super().__init__(names) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, useNode) @classmethod def parse(cls, useNode: Iir): @@ -104,6 +105,23 @@ class UseClause(VHDLModel_UseClause, DOMMixin): 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 class Entity(VHDLModel_Entity, DOMMixin): def __init__( diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py index b59efeacb..1cd98b4fa 100644 --- a/pyGHDL/dom/NonStandard.py +++ b/pyGHDL/dom/NonStandard.py @@ -74,6 +74,7 @@ from pyGHDL.dom.DesignUnit import ( PackageInstantiation, LibraryClause, UseClause, + ContextReference, ) from pyGHDL.dom.PSL import VerificationUnit, VerificationProperty, VerificationMode @@ -189,6 +190,8 @@ class Document(VHDLModel_Document): 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( -- cgit v1.2.3 From ad58c297680fe0256eacd12249d2131b00ff9b66 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 00:51:37 +0200 Subject: Fixed pretty printer after model fix. --- pyGHDL/dom/formatting/prettyprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index bfb91f3da..9917394da 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -566,7 +566,7 @@ 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( -- cgit v1.2.3 From c34b020a8c1b6aa5083a637e3e9062c7a71b309a Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 10:16:59 +0200 Subject: Some updates. --- pyGHDL/dom/Sequential.py | 68 +++++++++++++++++++++++++++++++----- pyGHDL/dom/_Translate.py | 20 +++++------ pyGHDL/dom/formatting/prettyprint.py | 4 ++- 3 files changed, 71 insertions(+), 21 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 7fe94fad5..cb6fa5a8f 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -49,6 +49,8 @@ from pyVHDLModel.SyntaxModel import ( ForLoopStatement as VHDLModel_ForLoopStatement, SequentialSimpleSignalAssignment as VHDLModel_SequentialSimpleSignalAssignment, SequentialProcedureCall as VHDLModel_SequentialProcedureCall, + SequentialAssertStatement as VHDLModel_SequentialAssertStatement, + SequentialReportStatement as VHDLModel_SequentialReportStatement, Name, SequentialStatement, Expression, @@ -211,7 +213,7 @@ class Case(VHDLModel_Case, DOMMixin): if block is nodes.Null_Iir: return cls(caseNode, choices) - statementChain = nodes.Get_Sequential_Statement_Chain(block) + statementChain = nodes.Get_Sequential_Statement_Chain(caseNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) @@ -271,7 +273,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): cases = [] choices = None alternative = nodes.Get_Case_Statement_Alternative_Chain(caseNode) - caseNode = alternative + cNode = alternative while alternative != nodes.Null_Iir: choiceKind = GetIirKindOfNode(alternative) @@ -319,7 +321,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): choices = None cases.append(OthersCase.parse(alternative, label)) alternative = nodes.Get_Chain(alternative) - caseNode = alternative + cNode = alternative continue else: pos = Position.parse(alternative) @@ -330,9 +332,9 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): ) if choices is not None: - cases.append(Case.parse(alternative, choices, label)) + cases.append(Case.parse(cNode, choices, label)) - caseNode = alternative + cNode = alternative choices = [ choice, ] @@ -340,7 +342,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): alternative = nodes.Get_Chain(alternative) if choices is not None: - cases.append(Case.parse(alternative, choices, label)) + cases.append(Case.parse(cNode, choices, label)) return cls(caseNode, label, expression, cases) @@ -431,11 +433,11 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): def __init__( self, callNode: Iir, - label: str, procedureName: Name, parameterMappings: Iterable, + label: str = None, ): - super().__init__(label, procedureName, parameterMappings) + super().__init__(procedureName, parameterMappings, label) DOMMixin.__init__(self, callNode) @classmethod @@ -451,4 +453,52 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): # TODO: parameter mappings parameterMappings = [] - return cls(callNode, label, procedureName, parameterMappings) + return cls(callNode, procedureName, parameterMappings, label) + + +@export +class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): + def __init__( + self, + assertNode: Iir, + condition: Expression, + message: Expression, + severity: Expression = None, + label: str = None, + ): + super().__init__(label, condition, message, severity, label) + DOMMixin.__init__(self, assertNode) + + @classmethod + def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetExpressionFromNode + + condition = "" + message = "" + severity = "" + + return cls(assertNode, condition, message, severity, label) + + +@export +class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): + def __init__( + self, + reportNode: Iir, + message: Expression, + severity: Expression = None, + label: str = None, + ): + super().__init__(label, message, severity, label) + DOMMixin.__init__(self, reportNode) + + @classmethod + def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": + from pyGHDL.dom._Utils import GetIirKindOfNode + from pyGHDL.dom._Translate import GetExpressionFromNode + + message = "" + severity = "" + + return cls(reportNode, message, severity, label) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 00194cb09..06afa960b 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -34,7 +34,13 @@ from typing import List, Generator from pydecor import export -from pyGHDL.dom.Sequential import IfStatement, ForLoopStatement, CaseStatement +from pyGHDL.dom.Sequential import ( + IfStatement, + ForLoopStatement, + CaseStatement, + SequentialReportStatement, + SequentialAssertStatement, +) from pyVHDLModel.SyntaxModel import ( Constraint, Direction, @@ -907,17 +913,9 @@ def GetSequentialStatementsFromChainedNodes( ) ) elif kind == nodes.Iir_Kind.Report_Statement: - print( - "[NOT IMPLEMENTED] Report statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield SequentialReportStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Assertion_Statement: - print( - "[NOT IMPLEMENTED] Report statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield SequentialAssertStatement.parse(statement, label) else: raise DOMException( "Unknown statement of kind '{kind}' in {entity} '{name}' at {file}:{line}:{column}.".format( diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 9917394da..6314d37f2 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -566,7 +566,9 @@ class PrettyPrint: ) elif isinstance(item, UseClause): buffer.append( - "{prefix}- use {names}".format(prefix=prefix, names=", ".join([str(n) for n in item.Names])) + "{prefix}- use {names}".format( + prefix=prefix, names=", ".join([str(n) for n in item.Names]) + ) ) elif isinstance(item, Package): buffer.append( -- cgit v1.2.3 From 2488e55caba1c369785a93ab2578c4a1e0c40c65 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 10:44:34 +0200 Subject: Read condition, message and severity from asserts and reports. --- pyGHDL/dom/Sequential.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index cb6fa5a8f..b0f1d2e97 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -466,19 +466,19 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): severity: Expression = None, label: str = None, ): - super().__init__(label, condition, message, severity, label) + super().__init__(condition, message, severity, label) DOMMixin.__init__(self, assertNode) - @classmethod - def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetExpressionFromNode + @classmethod + def parse(cls, assertNode: Iir, label: str) -> "SequentialAssertStatement": + from pyGHDL.dom._Translate import GetExpressionFromNode - condition = "" - message = "" - severity = "" + condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) + message = GetExpressionFromNode(nodes.Get_Report_Expression(assertNode)) + severityNode = nodes.Get_Severity_Expression(assertNode) + severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) - return cls(assertNode, condition, message, severity, label) + return cls(assertNode, condition, message, severity, label) @export @@ -490,15 +490,15 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): severity: Expression = None, label: str = None, ): - super().__init__(label, message, severity, label) + super().__init__(message, severity, label) DOMMixin.__init__(self, reportNode) - @classmethod - def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetExpressionFromNode + @classmethod + def parse(cls, reportNode: Iir, label: str) -> "SequentialReportStatement": + from pyGHDL.dom._Translate import GetExpressionFromNode - message = "" - severity = "" + 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) + return cls(reportNode, message, severity, label) -- cgit v1.2.3 From d0dc820554320ad076854481f5cb0957edd3cda5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 12:17:51 +0200 Subject: Implemented handling of wait statements. --- pyGHDL/dom/Sequential.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++-- pyGHDL/dom/_Translate.py | 8 ++------ 2 files changed, 53 insertions(+), 8 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index b0f1d2e97..d2efef8eb 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -51,6 +51,7 @@ from pyVHDLModel.SyntaxModel import ( SequentialProcedureCall as VHDLModel_SequentialProcedureCall, SequentialAssertStatement as VHDLModel_SequentialAssertStatement, SequentialReportStatement as VHDLModel_SequentialReportStatement, + WaitStatement as VHDLModel_WaitStatement, Name, SequentialStatement, Expression, @@ -476,7 +477,11 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) message = GetExpressionFromNode(nodes.Get_Report_Expression(assertNode)) severityNode = nodes.Get_Severity_Expression(assertNode) - severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) + severity = ( + None + if severityNode is nodes.Null_Iir + else GetExpressionFromNode(severityNode) + ) return cls(assertNode, condition, message, severity, label) @@ -499,6 +504,50 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): message = GetExpressionFromNode(nodes.Get_Report_Expression(reportNode)) severityNode = nodes.Get_Severity_Expression(reportNode) - severity = None if severityNode is nodes.Null_Iir else GetExpressionFromNode(severityNode) + 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: Expression = None, + timeout: Expression = 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/_Translate.py b/pyGHDL/dom/_Translate.py index 06afa960b..dfc919504 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -40,6 +40,7 @@ from pyGHDL.dom.Sequential import ( CaseStatement, SequentialReportStatement, SequentialAssertStatement, + WaitStatement, ) from pyVHDLModel.SyntaxModel import ( Constraint, @@ -877,7 +878,6 @@ def GetSequentialStatementsFromChainedNodes( 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) @@ -901,11 +901,7 @@ def GetSequentialStatementsFromChainedNodes( ) ) elif kind == nodes.Iir_Kind.Wait_Statement: - print( - "[NOT IMPLEMENTED] For-loop statement (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield WaitStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Procedure_Call_Statement: print( "[NOT IMPLEMENTED] Procedure call (label: '{label}') at line {line}".format( -- cgit v1.2.3 From f8d7ac62564e4bdefb35e58178c4df1b4feae844 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 13:30:49 +0200 Subject: Handle simple sequential signal assignments and it's waveforms. --- pyGHDL/dom/Concurrent.py | 27 ++++++++++++++++++++------- pyGHDL/dom/Sequential.py | 9 ++++----- pyGHDL/dom/_Translate.py | 7 ++----- 3 files changed, 26 insertions(+), 17 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index f4ded4e80..f4681dbf9 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -616,9 +616,23 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @export class WaveformElement(VHDLModel_WaveformElement, DOMMixin): - def __init__(self, waveformNode: Iir, expression: Expression, after: Expression): + def __init__(self, waveNode: Iir, expression: Expression, after: Expression): super().__init__(expression, after) - DOMMixin.__init__(self, waveformNode) + 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 @@ -644,12 +658,11 @@ class ConcurrentSimpleSignalAssignment( target = nodes.Get_Target(assignmentNode) targetName = GetNameFromNode(target) - waveform = nodes.Get_Waveform_Chain(assignmentNode) - - # TODO: translate waveforms to series of "expressions". - expression = [None] + waveform = [] + for wave in utils.chain_iter(nodes.Get_Waveform_Chain(assignmentNode)): + waveform.append(WaveformElement.parse(wave)) - return cls(assignmentNode, label, targetName, expression) + return cls(assignmentNode, label, targetName, waveform) @export diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index d2efef8eb..28b6f2b98 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -421,12 +421,11 @@ class SequentialSimpleSignalAssignment( target = nodes.Get_Target(assignmentNode) targetName = GetNameFromNode(target) - waveform = nodes.Get_Waveform_Chain(assignmentNode) + waveform = [] + for wave in utils.chain_iter(nodes.Get_Waveform_Chain(assignmentNode)): + waveform.append(WaveformElement.parse(wave)) - # TODO: translate waveforms to series of "expressions". - expression = [None] - - return cls(assignmentNode, targetName, expression, label) + return cls(assignmentNode, targetName, waveform, label) @export diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index dfc919504..133d9386f 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -41,6 +41,7 @@ from pyGHDL.dom.Sequential import ( SequentialReportStatement, SequentialAssertStatement, WaitStatement, + SequentialSimpleSignalAssignment, ) from pyVHDLModel.SyntaxModel import ( Constraint, @@ -886,11 +887,7 @@ def GetSequentialStatementsFromChainedNodes( elif kind == nodes.Iir_Kind.Case_Statement: yield CaseStatement.parse(statement, label) elif kind == nodes.Iir_Kind.Simple_Signal_Assignment_Statement: - print( - "[NOT IMPLEMENTED] (Simple) signal assignment (label: '{label}') at line {line}".format( - label=label, line=pos.Line - ) - ) + yield SequentialSimpleSignalAssignment.parse(statement, label) elif kind in ( nodes.Iir_Kind.Variable_Assignment_Statement, nodes.Iir_Kind.Conditional_Variable_Assignment_Statement, -- cgit v1.2.3 From 8c0f8e0ad95c53beac983546550222117c6a639c Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 20:14:13 +0200 Subject: Handle associations. --- pyGHDL/dom/Concurrent.py | 142 ++++++++++++++++++++++++++++++++++++++--------- pyGHDL/dom/DesignUnit.py | 1 + pyGHDL/dom/_Translate.py | 46 ++++++++++++++- 3 files changed, 162 insertions(+), 27 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index f4681dbf9..2910e596c 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -36,6 +36,9 @@ 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, @@ -60,6 +63,7 @@ from pyVHDLModel.SyntaxModel import ( Expression, ConcurrentChoice, ConcurrentCase, + AssociationItem, ) from pyGHDL.libghdl import Iir, utils @@ -68,24 +72,65 @@ 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: Expression, formal: Name = None): + super().__init__(actual, formal) + DOMMixin.__init__(self, associationNode) + + +@export +class PortAssociationItem(VHDLModel_PortAssociationItem, DOMMixin): + def __init__(self, associationNode: Iir, actual: Expression, formal: Name = None): + super().__init__(actual, formal) + DOMMixin.__init__(self, associationNode) + + +@export +class ParameterAssociationItem(VHDLModel_ParameterAssociationItem, DOMMixin): + def __init__(self, associationNode: Iir, actual: Expression, 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): - super().__init__(label, componentName) + 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 + 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) + ) - # TODO: get mapped generics - # TODO: get mapped ports - - return cls(instantiationNode, label, componentName) + return cls( + instantiationNode, + label, + componentName, + genericAssociations, + portAssociations, + ) @export @@ -96,15 +141,23 @@ class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): label: str, entityName: Name, architectureName: Name = None, + genericAssociations: Iterable[AssociationItem] = None, + portAssociations: Iterable[AssociationItem] = None, ): - super().__init__(label, entityName, architectureName) + 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 + from pyGHDL.dom._Translate import ( + GetNameFromNode, + GetGenericMapAspect, + GetPortMapAspect, + ) entityId = nodes.Get_Entity_Name(instantiatedUnit) entityName = GetNameFromNode(entityId) @@ -114,31 +167,65 @@ class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): if architectureId != nodes.Null_Iir: architectureName = GetNameOfNode(architectureId) - # TODO: get mapped generics - # TODO: get mapped ports + genericAssociations = GetGenericMapAspect( + nodes.Get_Generic_Map_Aspect_Chain(instantiationNode) + ) + portAssociations = GetPortMapAspect( + nodes.Get_Port_Map_Aspect_Chain(instantiationNode) + ) - return cls(instantiationNode, label, entityName, architectureName) + return cls( + instantiationNode, + label, + entityName, + architectureName, + genericAssociations, + portAssociations, + ) @export class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin): - def __init__(self, instantiationNode: Iir, label: str, configurationName: Name): - super().__init__(label, configurationName) + 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 + from pyGHDL.dom._Translate import ( + GetNameFromNode, + GetGenericMapAspect, + GetPortMapAspect, + ) configurationId = nodes.Get_Configuration_Name(instantiatedUnit) configurationName = GetNameFromNode(configurationId) - # TODO: get mapped generics - # TODO: get mapped ports + genericAssociations = GetGenericMapAspect( + nodes.Get_Generic_Map_Aspect_Chain(instantiationNode) + ) + portAssociations = GetPortMapAspect( + nodes.Get_Port_Map_Aspect_Chain(instantiationNode) + ) - return cls(instantiationNode, label, configurationName) + return cls( + instantiationNode, + label, + configurationName, + genericAssociations, + portAssociations, + ) @export @@ -160,6 +247,9 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): 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 ) @@ -678,15 +768,15 @@ class ConcurrentProcedureCall(VHDLModel_ConcurrentProcedureCall, DOMMixin): DOMMixin.__init__(self, callNode) @classmethod - def parse(cls, callNode: Iir, label: str) -> "ConcurrentProcedureCall": - from pyGHDL.dom._Translate import GetNameFromNode + def parse(cls, concurrentCallNode: Iir, label: str) -> "ConcurrentProcedureCall": + from pyGHDL.dom._Translate import GetNameFromNode, GetParameterMapAspect - call = nodes.Get_Procedure_Call(callNode) - prefix = nodes.Get_Prefix(call) + callNode = nodes.Get_Procedure_Call(concurrentCallNode) + prefix = nodes.Get_Prefix(callNode) procedureName = GetNameFromNode(prefix) + parameterAssociations = GetParameterMapAspect( + nodes.Get_Parameter_Association_Chain(callNode) + ) - # TODO: parameter mappings - parameterMappings = [] - - return cls(callNode, label, procedureName, parameterMappings) + return cls(concurrentCallNode, label, procedureName, parameterAssociations) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index 7f4d8e964..5db6c1613 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -291,6 +291,7 @@ class PackageInstantiation(VHDLModel_PackageInstantiation, DOMMixin): # 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) diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index 133d9386f..e7e862039 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -30,7 +30,7 @@ # # SPDX-License-Identifier: GPL-2.0-or-later # ============================================================================ -from typing import List, Generator +from typing import List, Generator, Type from pydecor import export @@ -56,6 +56,7 @@ from pyVHDLModel.SyntaxModel import ( Name, ConcurrentStatement, SequentialStatement, + AssociationItem, ) from pyGHDL.libghdl import utils, name_table @@ -159,6 +160,9 @@ from pyGHDL.dom.Concurrent import ( CaseGenerateStatement, ConcurrentSimpleSignalAssignment, ConcurrentProcedureCall, + GenericAssociationItem, + PortAssociationItem, + ParameterAssociationItem, ) from pyGHDL.dom.Subprogram import Function, Procedure from pyGHDL.dom.Misc import Alias @@ -654,6 +658,46 @@ def GetParameterFromChainedNodes( 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) + 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[AssociationItem, None, None]: + return GetMapAspect(genericMapAspect, GenericAssociationItem, "generic") + + +def GetPortMapAspect(portMapAspect: Iir) -> Generator[AssociationItem, None, None]: + return GetMapAspect(portMapAspect, PortAssociationItem, "port") + + +def GetParameterMapAspect( + parameterMapAspect: Iir, +) -> Generator[AssociationItem, None, None]: + return GetMapAspect(parameterMapAspect, ParameterAssociationItem, "parameter") + + def GetDeclaredItemsFromChainedNodes( nodeChain: Iir, entity: str, name: str ) -> Generator[ModelEntity, None, None]: -- cgit v1.2.3 From 94a3027f9108f0d81a84f7d52a3e4afe93c1eb66 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Tue, 17 Aug 2021 20:19:59 +0200 Subject: Also handle parameters for sequential procedure calls. --- pyGHDL/dom/Sequential.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 28b6f2b98..f752b432d 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -442,18 +442,17 @@ class SequentialProcedureCall(VHDLModel_SequentialProcedureCall, DOMMixin): @classmethod def parse(cls, callNode: Iir, label: str) -> "SequentialProcedureCall": - from pyGHDL.dom._Utils import GetIirKindOfNode - from pyGHDL.dom._Translate import GetNameFromNode + from pyGHDL.dom._Translate import GetNameFromNode, GetParameterMapAspect call = nodes.Get_Procedure_Call(callNode) - prefix = nodes.Get_Prefix(call) + prefix = nodes.Get_Prefix(call) procedureName = GetNameFromNode(prefix) + parameterAssociations = GetParameterMapAspect( + nodes.Get_Parameter_Association_Chain(callNode) + ) - # TODO: parameter mappings - parameterMappings = [] - - return cls(callNode, procedureName, parameterMappings, label) + return cls(callNode, procedureName, parameterAssociations, label) @export -- cgit v1.2.3 From 32cb30ea5f674acd7ad7d5923fbd462be38d2046 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 18 Aug 2021 00:47:31 +0200 Subject: Assertion messages are optional in assert statements. --- pyGHDL/dom/Sequential.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index f752b432d..a4eae8767 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -461,7 +461,7 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): self, assertNode: Iir, condition: Expression, - message: Expression, + message: Expression = None, severity: Expression = None, label: str = None, ): @@ -473,7 +473,12 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): from pyGHDL.dom._Translate import GetExpressionFromNode condition = GetExpressionFromNode(nodes.Get_Assertion_Condition(assertNode)) - message = GetExpressionFromNode(nodes.Get_Report_Expression(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 -- cgit v1.2.3 From 324d56b5ab4b1cdd1c43f412d4139a38dcb90eb9 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 18 Aug 2021 08:19:44 +0200 Subject: Handle open in map aspects. --- pyGHDL/dom/Names.py | 8 ++++++++ pyGHDL/dom/_Translate.py | 10 ++++++++++ 2 files changed, 18 insertions(+) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Names.py b/pyGHDL/dom/Names.py index f98555681..acb9cd1d6 100644 --- a/pyGHDL/dom/Names.py +++ b/pyGHDL/dom/Names.py @@ -42,6 +42,7 @@ from pyVHDLModel.SyntaxModel import ( SelectedName as VHDLModel_SelectedName, AttributeName as VHDLModel_AttributeName, AllName as VHDLModel_AllName, + OpenName as VHDLModel_OpenName, Name, ) from pyGHDL.libghdl._types import Iir @@ -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/_Translate.py b/pyGHDL/dom/_Translate.py index e7e862039..ed2e32ce3 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -73,6 +73,7 @@ from pyGHDL.dom.Names import ( AttributeName, ParenthesisName, AllName, + OpenName, ) from pyGHDL.dom.Symbol import ( SimpleObjectOrFunctionCallSymbol, @@ -673,6 +674,15 @@ def GetMapAspect( 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) + + open = OpenName(generic) + yield cls(generic, open, formal) else: pos = Position.parse(generic) raise DOMException( -- cgit v1.2.3 From 89aee29e92c09f9bfa7b01f39233636bbc938915 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Wed, 18 Aug 2021 08:20:17 +0200 Subject: Handle subprogram vs. subprogram body. --- pyGHDL/dom/_Translate.py | 52 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index ed2e32ce3..6231d93dd 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -712,6 +712,7 @@ def GetDeclaredItemsFromChainedNodes( nodeChain: Iir, entity: str, name: str ) -> Generator[ModelEntity, None, None]: item = nodeChain + lastKind = None while item != nodes.Null_Iir: kind = GetIirKindOfNode(item) if kind == nodes.Iir_Kind.Constant_Declaration: @@ -726,7 +727,6 @@ def GetDeclaredItemsFromChainedNodes( obj = SharedVariable.parse(item) else: obj = Variable.parse(item) - # raise DOMException("Found non-shared variable.") elif kind == nodes.Iir_Kind.Signal_Declaration: from pyGHDL.dom.Object import Signal @@ -746,16 +746,53 @@ def GetDeclaredItemsFromChainedNodes( yield GetSubtypeFromNode(item) elif kind == nodes.Iir_Kind.Function_Declaration: - yield Function.parse(item) + 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: - # procedureName = NodeToName(item) - print("found function body '{name}'".format(name="????")) + 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: - yield Procedure.parse(item) + 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: - # procedureName = NodeToName(item) - print("found procedure body '{name}'".format(name="????")) + 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: @@ -819,6 +856,7 @@ def GetDeclaredItemsFromChainedNodes( ) ) + lastKind = None item = nodes.Get_Chain(item) continue -- cgit v1.2.3 From 07d8c06b4562e2e0d7390b98732ce1b6d30320d4 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Sun, 22 Aug 2021 23:32:21 +0200 Subject: Fixed case statement. --- pyGHDL/dom/Sequential.py | 6 +----- pyGHDL/dom/requirements.txt | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index a4eae8767..fe7c83614 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -210,11 +210,7 @@ class Case(VHDLModel_Case, DOMMixin): ) -> "Case": from pyGHDL.dom._Translate import GetSequentialStatementsFromChainedNodes - block = nodes.Get_Associated_Block(caseNode) - if block is nodes.Null_Iir: - return cls(caseNode, choices) - - statementChain = nodes.Get_Sequential_Statement_Chain(caseNode) + statementChain = nodes.Get_Associated_Chain(caseNode) statements = GetSequentialStatementsFromChainedNodes( statementChain, "case", label ) diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt index ca2a796ac..ea7731edc 100644 --- a/pyGHDL/dom/requirements.txt +++ b/pyGHDL/dom/requirements.txt @@ -1,4 +1,4 @@ -r ../libghdl/requirements.txt -#pyVHDLModel==0.11.2 -https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel +pyVHDLModel==0.11.4 +#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel -- cgit v1.2.3 From 8fb4da723067b2ff99050f9ef9fc0bbd3c835ef4 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 23 Aug 2021 00:13:43 +0200 Subject: Some fixes. --- pyGHDL/dom/Concurrent.py | 16 ++++++++-------- pyGHDL/dom/DesignUnit.py | 3 +-- pyGHDL/dom/Sequential.py | 11 +++++++---- pyGHDL/dom/_Translate.py | 9 ++++----- pyGHDL/dom/formatting/prettyprint.py | 3 +-- 5 files changed, 21 insertions(+), 21 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 2910e596c..a1949c86b 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -277,7 +277,6 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): def parse( cls, processNode: Iir, label: str, hasSensitivityList: bool ) -> "ProcessStatement": - from pyGHDL.dom._Utils import GetIirKindOfNode from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetSequentialStatementsFromChainedNodes, @@ -285,6 +284,7 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): sensitivityList = None if hasSensitivityList: + # FIXME: sensitity list sensitivityListNode = nodes.Get_Sensitivity_List(processNode) # print("sensi", GetIirKindOfNode(sensitivityListNode)) @@ -323,7 +323,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): body = nodes.Get_Generate_Statement_Body(generateNode) # TODO: alternative label - alternativeLabelId = nodes.Get_Alternative_Label(body) + # alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" declarationChain = nodes.Get_Declaration_Chain(body) @@ -364,7 +364,7 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): body = nodes.Get_Generate_Statement_Body(generateNode) # TODO: alternative label - alternativeLabelId = nodes.Get_Alternative_Label(body) + # alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" declarationChain = nodes.Get_Declaration_Chain(body) @@ -402,7 +402,7 @@ class ElseGenerateBranch(VHDLModel_ElseGenerateBranch): body = nodes.Get_Generate_Statement_Body(generateNode) # TODO: alternative label - alternativeLabelId = nodes.Get_Alternative_Label(body) + # alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" declarationChain = nodes.Get_Declaration_Chain(body) @@ -492,7 +492,7 @@ class GenerateCase(VHDLModel_GenerateCase, DOMMixin): body = nodes.Get_Associated_Block(caseNode) # TODO: alternative label - alternativeLabelId = nodes.Get_Alternative_Label(body) + # alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" declarationChain = nodes.Get_Declaration_Chain(body) @@ -530,7 +530,7 @@ class OthersGenerateCase(VHDLModel_OthersGenerateCase, DOMMixin): body = nodes.Get_Associated_Block(caseNode) # TODO: alternative label - alternativeLabelId = nodes.Get_Alternative_Label(body) + # alternativeLabelId = nodes.Get_Alternative_Label(body) alternativeLabel = "" declarationChain = nodes.Get_Declaration_Chain(body) @@ -653,11 +653,11 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): generateNode: Iir, label: str, loopIndex: str, - range: Range, + rng: Range, declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, ): - super().__init__(label, loopIndex, range, declaredItems, statements) + super().__init__(label, loopIndex, rng, declaredItems, statements) DOMMixin.__init__(self, generateNode) @classmethod diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index 5db6c1613..ff738e7dc 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -41,7 +41,6 @@ This module contains all DOM classes for VHDL's design units (:class:`context Generator[AssociationItem, None, None]: +) -> Generator[GenericAssociationItem, None, None]: return GetMapAspect(genericMapAspect, GenericAssociationItem, "generic") -def GetPortMapAspect(portMapAspect: Iir) -> Generator[AssociationItem, None, None]: +def GetPortMapAspect(portMapAspect: Iir) -> Generator[PortAssociationItem, None, None]: return GetMapAspect(portMapAspect, PortAssociationItem, "port") def GetParameterMapAspect( parameterMapAspect: Iir, -) -> Generator[AssociationItem, None, None]: +) -> Generator[ParameterAssociationItem, None, None]: return GetMapAspect(parameterMapAspect, ParameterAssociationItem, "parameter") diff --git a/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py index 6314d37f2..6c0f06061 100644 --- a/pyGHDL/dom/formatting/prettyprint.py +++ b/pyGHDL/dom/formatting/prettyprint.py @@ -43,7 +43,6 @@ from pyGHDL.dom.Concurrent import ( ComponentInstantiation, ConfigurationInstantiation, EntityInstantiation, - OthersGenerateCase, ConcurrentProcedureCall, ) from pyVHDLModel.SyntaxModel import ( @@ -93,7 +92,7 @@ from pyGHDL.dom.InterfaceItem import ( PortSignalInterfaceItem, GenericTypeInterfaceItem, ) -from pyGHDL.dom.Object import Constant, Signal, SharedVariable, File, DeferredConstant +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 -- cgit v1.2.3 From 8b98e2883b40b00922c9944c2470211ee055a9a5 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 23 Aug 2021 09:02:47 +0200 Subject: Fixes due to a bug in pyVHDLModel. Name Context was used twice. --- pyGHDL/dom/Aggregates.py | 12 +++---- pyGHDL/dom/Concurrent.py | 26 +++++++++----- pyGHDL/dom/DesignUnit.py | 18 +++++----- pyGHDL/dom/Expression.py | 86 ++++++++++++++++++++++----------------------- pyGHDL/dom/InterfaceItem.py | 12 +++---- pyGHDL/dom/Object.py | 8 ++--- pyGHDL/dom/Sequential.py | 24 ++++++------- pyGHDL/dom/Symbol.py | 4 +-- pyGHDL/dom/_Translate.py | 8 ++--- pyGHDL/dom/requirements.txt | 2 +- 10 files changed, 104 insertions(+), 96 deletions(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Aggregates.py b/pyGHDL/dom/Aggregates.py index 6ca0734e7..dfaee9a2d 100644 --- a/pyGHDL/dom/Aggregates.py +++ b/pyGHDL/dom/Aggregates.py @@ -47,7 +47,7 @@ from pyVHDLModel.SyntaxModel import ( 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/Concurrent.py b/pyGHDL/dom/Concurrent.py index a1949c86b..740802d18 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -60,7 +60,7 @@ from pyVHDLModel.SyntaxModel import ( Name, ConcurrentStatement, SequentialStatement, - Expression, + ExpressionUnion, ConcurrentChoice, ConcurrentCase, AssociationItem, @@ -74,21 +74,27 @@ from pyGHDL.dom._Utils import GetNameOfNode @export class GenericAssociationItem(VHDLModel_GenericAssociationItem, DOMMixin): - def __init__(self, associationNode: Iir, actual: Expression, formal: Name = None): + 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: Expression, formal: Name = None): + 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: Expression, formal: Name = None): + def __init__( + self, associationNode: Iir, actual: ExpressionUnion, formal: Name = None + ): super().__init__(actual, formal) DOMMixin.__init__(self, associationNode) @@ -303,7 +309,7 @@ class IfGenerateBranch(VHDLModel_IfGenerateBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, alternativeLabel: str = None, @@ -344,7 +350,7 @@ class ElsifGenerateBranch(VHDLModel_ElsifGenerateBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, declaredItems: Iterable = None, statements: Iterable[ConcurrentStatement] = None, alternativeLabel: str = None, @@ -455,7 +461,7 @@ class IfGenerateStatement(VHDLModel_IfGenerateStatement, DOMMixin): @export class IndexedGenerateChoice(VHDLModel_IndexedGenerateChoice, DOMMixin): - def __init__(self, node: Iir, expression: Expression): + def __init__(self, node: Iir, expression: ExpressionUnion): super().__init__(expression) DOMMixin.__init__(self, node) @@ -552,7 +558,7 @@ class CaseGenerateStatement(VHDLModel_CaseGenerateStatement, DOMMixin): self, generateNode: Iir, label: str, - expression: Expression, + expression: ExpressionUnion, cases: Iterable[ConcurrentCase], ): super().__init__(label, expression, cases) @@ -706,7 +712,9 @@ class ForGenerateStatement(VHDLModel_ForGenerateStatement, DOMMixin): @export class WaveformElement(VHDLModel_WaveformElement, DOMMixin): - def __init__(self, waveNode: Iir, expression: Expression, after: Expression): + def __init__( + self, waveNode: Iir, expression: ExpressionUnion, after: ExpressionUnion + ): super().__init__(expression, after) DOMMixin.__init__(self, waveNode) diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index ff738e7dc..3fe8f74bf 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -43,6 +43,7 @@ from typing import Iterable from pydecor import export +from pyVHDLModel import ContextUnion, EntityOrSymbol from pyVHDLModel.SyntaxModel import ( LibraryClause as VHDLModel_LibraryClause, UseClause as VHDLModel_UseClause, @@ -57,7 +58,6 @@ from pyVHDLModel.SyntaxModel import ( Component as VHDLModel_Component, GenericInterfaceItem, PortInterfaceItem, - EntityOrSymbol, Name, ConcurrentStatement, ) @@ -127,7 +127,7 @@ class Entity(VHDLModel_Entity, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[Context] = None, + contextItems: Iterable[ContextUnion] = None, genericItems: Iterable[GenericInterfaceItem] = None, portItems: Iterable[PortInterfaceItem] = None, declaredItems: Iterable = None, @@ -139,7 +139,7 @@ class Entity(VHDLModel_Entity, DOMMixin): DOMMixin.__init__(self, node) @classmethod - def parse(cls, entityNode: Iir, contextItems: Iterable[Context]): + 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)) @@ -164,7 +164,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin): node: Iir, identifier: str, entity: EntityOrSymbol, - contextItems: Iterable[Context] = None, + contextItems: Iterable[ContextUnion] = None, declaredItems: Iterable = None, statements: Iterable["ConcurrentStatement"] = None, ): @@ -172,7 +172,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin): DOMMixin.__init__(self, node) @classmethod - def parse(cls, architectureNode: Iir, contextItems: Iterable[Context]): + def parse(cls, architectureNode: Iir, contextItems: Iterable[ContextUnion]): name = GetNameOfNode(architectureNode) entityNameNode = nodes.Get_Entity_Name(architectureNode) entityName = GetNameOfNode(entityNameNode) @@ -218,7 +218,7 @@ class Package(VHDLModel_Package, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[Context] = None, + contextItems: Iterable[ContextUnion] = None, genericItems: Iterable[GenericInterfaceItem] = None, declaredItems: Iterable = None, ): @@ -226,7 +226,7 @@ class Package(VHDLModel_Package, DOMMixin): DOMMixin.__init__(self, node) @classmethod - def parse(cls, packageNode: Iir, contextItems: Iterable[Context]): + def parse(cls, packageNode: Iir, contextItems: Iterable[ContextUnion]): name = GetNameOfNode(packageNode) packageHeader = nodes.Get_Package_Header(packageNode) @@ -252,14 +252,14 @@ class PackageBody(VHDLModel_PackageBody, DOMMixin): self, node: Iir, identifier: str, - contextItems: Iterable[Context] = None, + contextItems: Iterable[ContextUnion] = None, declaredItems: Iterable = None, ): super().__init__(identifier, contextItems, declaredItems) DOMMixin.__init__(self, node) @classmethod - def parse(cls, packageBodyNode: Iir, contextItems: Iterable[Context]): + def parse(cls, packageBodyNode: Iir, contextItems: Iterable[ContextUnion]): name = GetNameOfNode(packageBodyNode) declaredItems = GetDeclaredItemsFromChainedNodes( nodes.Get_Declaration_Chain(packageBodyNode), "package", name diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py index 3769b9fb6..ce5945d46 100644 --- a/pyGHDL/dom/Expression.py +++ b/pyGHDL/dom/Expression.py @@ -83,7 +83,7 @@ from pyVHDLModel.SyntaxModel import ( SubtypeAllocation as VHDLModel_SubtypeAllocation, QualifiedExpressionAllocation as VHDLModel_QualifiedExpressionAllocation, Aggregate as VHDLModel_Aggregate, - Expression, + ExpressionUnion, AggregateElement, SubtypeOrSymbol, Symbol, @@ -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) diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py index 3a9c7238f..af1b681cd 100644 --- a/pyGHDL/dom/InterfaceItem.py +++ b/pyGHDL/dom/InterfaceItem.py @@ -47,7 +47,7 @@ from pyVHDLModel.SyntaxModel import ( ParameterFileInterfaceItem as VHDLModel_ParameterFileInterfaceItem, Mode, SubtypeOrSymbol, - Expression, + ExpressionUnion, ) from pyGHDL.libghdl._types import Iir @@ -68,7 +68,7 @@ class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMi identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, - defaultExpression: Expression, + defaultExpression: ExpressionUnion, ): super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -168,7 +168,7 @@ class PortSignalInterfaceItem(VHDLModel_PortSignalInterfaceItem, DOMMixin): identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, - defaultExpression: Expression = None, + defaultExpression: ExpressionUnion = None, ): super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -207,7 +207,7 @@ class ParameterConstantInterfaceItem( identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, - defaultExpression: Expression = None, + defaultExpression: ExpressionUnion = None, ): super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -248,7 +248,7 @@ class ParameterVariableInterfaceItem( identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, - defaultExpression: Expression = None, + defaultExpression: ExpressionUnion = None, ): super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -287,7 +287,7 @@ class ParameterSignalInterfaceItem(VHDLModel_ParameterSignalInterfaceItem, DOMMi identifiers: List[str], mode: Mode, subtype: SubtypeOrSymbol, - defaultExpression: Expression = None, + defaultExpression: ExpressionUnion = None, ): super().__init__(identifiers, mode, subtype, defaultExpression) DOMMixin.__init__(self, node) diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py index b83f352a4..def09d50c 100644 --- a/pyGHDL/dom/Object.py +++ b/pyGHDL/dom/Object.py @@ -41,7 +41,7 @@ from pyVHDLModel.SyntaxModel import ( SharedVariable as VHDLModel_SharedVariable, Signal as VHDLModel_Signal, File as VHDLModel_File, - Expression, + ExpressionUnion, SubtypeOrSymbol, ) @@ -60,7 +60,7 @@ class Constant(VHDLModel_Constant, DOMMixin): node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, - defaultExpression: Expression, + defaultExpression: ExpressionUnion, ): super().__init__(identifiers, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -127,7 +127,7 @@ class Variable(VHDLModel_Variable, DOMMixin): node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, - defaultExpression: Expression, + defaultExpression: ExpressionUnion, ): super().__init__(identifiers, subtype, defaultExpression) DOMMixin.__init__(self, node) @@ -185,7 +185,7 @@ class Signal(VHDLModel_Signal, DOMMixin): node: Iir, identifiers: List[str], subtype: SubtypeOrSymbol, - defaultExpression: Expression, + defaultExpression: ExpressionUnion, ): super().__init__(identifiers, subtype, defaultExpression) DOMMixin.__init__(self, node) diff --git a/pyGHDL/dom/Sequential.py b/pyGHDL/dom/Sequential.py index 4f511c16f..be4793b2a 100644 --- a/pyGHDL/dom/Sequential.py +++ b/pyGHDL/dom/Sequential.py @@ -57,7 +57,7 @@ from pyVHDLModel.SyntaxModel import ( WaitStatement as VHDLModel_WaitStatement, Name, SequentialStatement, - Expression, + ExpressionUnion, SequentialChoice, SequentialCase, ) @@ -74,7 +74,7 @@ class IfBranch(VHDLModel_IfBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, statements: Iterable[SequentialStatement] = None, ): super().__init__(condition, statements) @@ -101,7 +101,7 @@ class ElsifBranch(VHDLModel_ElsifBranch): def __init__( self, branchNode: Iir, - condition: Expression, + condition: ExpressionUnion, statements: Iterable[SequentialStatement] = None, ): super().__init__(condition, statements) @@ -184,7 +184,7 @@ class IfStatement(VHDLModel_IfStatement, DOMMixin): @export class IndexedChoice(VHDLModel_IndexedChoice, DOMMixin): - def __init__(self, node: Iir, expression: Expression): + def __init__(self, node: Iir, expression: ExpressionUnion): super().__init__(expression) DOMMixin.__init__(self, node) @@ -253,7 +253,7 @@ class CaseStatement(VHDLModel_CaseStatement, DOMMixin): self, caseNode: Iir, label: str, - expression: Expression, + expression: ExpressionUnion, cases: Iterable[SequentialCase], ): super().__init__(expression, cases, label) @@ -459,9 +459,9 @@ class SequentialAssertStatement(VHDLModel_SequentialAssertStatement, DOMMixin): def __init__( self, assertNode: Iir, - condition: Expression, - message: Expression = None, - severity: Expression = None, + condition: ExpressionUnion, + message: ExpressionUnion = None, + severity: ExpressionUnion = None, label: str = None, ): super().__init__(condition, message, severity, label) @@ -493,8 +493,8 @@ class SequentialReportStatement(VHDLModel_SequentialReportStatement, DOMMixin): def __init__( self, reportNode: Iir, - message: Expression, - severity: Expression = None, + message: ExpressionUnion, + severity: ExpressionUnion = None, label: str = None, ): super().__init__(message, severity, label) @@ -521,8 +521,8 @@ class WaitStatement(VHDLModel_WaitStatement, DOMMixin): self, waitNode: Iir, sensitivityList: Iterable[Name] = None, - condition: Expression = None, - timeout: Expression = None, + condition: ExpressionUnion = None, + timeout: ExpressionUnion = None, label: str = None, ): super().__init__(sensitivityList, condition, timeout, label) diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py index 931fc82f2..f52afbb18 100644 --- a/pyGHDL/dom/Symbol.py +++ b/pyGHDL/dom/Symbol.py @@ -41,7 +41,7 @@ from pyVHDLModel.SyntaxModel import ( 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/_Translate.py b/pyGHDL/dom/_Translate.py index 626ffd3fa..d64e38d82 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -44,9 +44,9 @@ from pyGHDL.dom.Sequential import ( SequentialSimpleSignalAssignment, ) from pyVHDLModel.SyntaxModel import ( - Constraint, + ConstraintUnion, Direction, - Expression, + ExpressionUnion, SubtypeOrSymbol, BaseType, GenericInterfaceItem, @@ -225,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) @@ -467,7 +467,7 @@ __EXPRESSION_TRANSLATION = { @export -def GetExpressionFromNode(node: Iir) -> Expression: +def GetExpressionFromNode(node: Iir) -> ExpressionUnion: kind = GetIirKindOfNode(node) try: diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt index ea7731edc..d296f0e96 100644 --- a/pyGHDL/dom/requirements.txt +++ b/pyGHDL/dom/requirements.txt @@ -1,4 +1,4 @@ -r ../libghdl/requirements.txt -pyVHDLModel==0.11.4 +pyVHDLModel==0.11.5 #https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel -- cgit v1.2.3 From b229fa55b6485350ced8e31d6a803d08544b6d22 Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Mon, 23 Aug 2021 15:41:10 +0200 Subject: Skip null statement. --- pyGHDL/dom/Concurrent.py | 3 ++- pyGHDL/dom/_Translate.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'pyGHDL') diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index 740802d18..e7162cc81 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -290,8 +290,9 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): sensitivityList = None if hasSensitivityList: + pass # FIXME: sensitity list - sensitivityListNode = nodes.Get_Sensitivity_List(processNode) + # sensitivityListNode = nodes.Get_Sensitivity_List(processNode) # print("sensi", GetIirKindOfNode(sensitivityListNode)) declaredItems = GetDeclaredItemsFromChainedNodes( diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index d64e38d82..43c443cc1 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -1000,6 +1000,12 @@ def GetSequentialStatementsFromChainedNodes( 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] null statement (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( -- cgit v1.2.3