diff options
author | Patrick Lehmann <Patrick.Lehmann@plc2.de> | 2021-08-17 20:14:13 +0200 |
---|---|---|
committer | umarcor <unai.martinezcorral@ehu.eus> | 2021-08-23 16:35:36 +0200 |
commit | 8c0f8e0ad95c53beac983546550222117c6a639c (patch) | |
tree | 650acf22884b74848bce6eb63f98d64eea442de0 /pyGHDL/dom | |
parent | f8d7ac62564e4bdefb35e58178c4df1b4feae844 (diff) | |
download | ghdl-8c0f8e0ad95c53beac983546550222117c6a639c.tar.gz ghdl-8c0f8e0ad95c53beac983546550222117c6a639c.tar.bz2 ghdl-8c0f8e0ad95c53beac983546550222117c6a639c.zip |
Handle associations.
Diffstat (limited to 'pyGHDL/dom')
-rw-r--r-- | pyGHDL/dom/Concurrent.py | 142 | ||||
-rw-r--r-- | pyGHDL/dom/DesignUnit.py | 1 | ||||
-rw-r--r-- | pyGHDL/dom/_Translate.py | 46 |
3 files changed, 162 insertions, 27 deletions
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 @@ -69,23 +73,64 @@ 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]: |