aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Lehmann <Patrick.Lehmann@plc2.de>2021-08-17 20:14:13 +0200
committerumarcor <unai.martinezcorral@ehu.eus>2021-08-23 16:35:36 +0200
commit8c0f8e0ad95c53beac983546550222117c6a639c (patch)
tree650acf22884b74848bce6eb63f98d64eea442de0
parentf8d7ac62564e4bdefb35e58178c4df1b4feae844 (diff)
downloadghdl-8c0f8e0ad95c53beac983546550222117c6a639c.tar.gz
ghdl-8c0f8e0ad95c53beac983546550222117c6a639c.tar.bz2
ghdl-8c0f8e0ad95c53beac983546550222117c6a639c.zip
Handle associations.
-rw-r--r--pyGHDL/dom/Concurrent.py142
-rw-r--r--pyGHDL/dom/DesignUnit.py1
-rw-r--r--pyGHDL/dom/_Translate.py46
-rw-r--r--testsuite/pyunit/Current.vhdl20
4 files changed, 177 insertions, 32 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]:
diff --git a/testsuite/pyunit/Current.vhdl b/testsuite/pyunit/Current.vhdl
index 1f802af47..81887ae7f 100644
--- a/testsuite/pyunit/Current.vhdl
+++ b/testsuite/pyunit/Current.vhdl
@@ -136,20 +136,29 @@ begin
inst1: entity work.counter1(rtl)
generic map (
- BITS => 8
+ BITS1 => 8
)
port map (
- clk => Clock
+ clk1 => Clock
);
inst2: component counter2
+ generic map (
+ BITS2 => 8,
+ value2
+ )
port map (
- clk => Clock
+ clk2 => Clock,
+ enable2
);
inst3: configuration counter3
+ generic map (
+ BITS3 => 8
+ )
port map (
- clk => Clock
+ clk3 => Clock,
+ control(0) => battery and emergency
);
blk: block
@@ -215,7 +224,8 @@ begin
end block;
end generate;
- call: OtherDummy;
+ call: CallDummy;
+ called: CalledDummy(25);
ende: std.env.stop;
end architecture behav;