From 9cf69f324186932e4308e1ca0b19f563dab90e5e Mon Sep 17 00:00:00 2001 From: Patrick Lehmann Date: Thu, 29 Dec 2022 23:16:27 +0100 Subject: Added Get***Symbol functions. Improved Symbol handling. --- pyGHDL/dom/Concurrent.py | 80 ++++++---------------- pyGHDL/dom/DesignUnit.py | 4 +- pyGHDL/dom/Symbol.py | 68 ++++++++++++------ pyGHDL/dom/_Translate.py | 1 + pyGHDL/dom/_Utils.py | 44 +++++++++--- .../dom/examples/StopWatch/seg7_Display.cfg.vhdl | 42 ++++++++++++ .../pyunit/dom/examples/StopWatch/sync_Bits.vhdl | 42 ++++++++++++ 7 files changed, 192 insertions(+), 89 deletions(-) create mode 100644 testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl create mode 100644 testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py index df3e97a2a..0435792ef 100644 --- a/pyGHDL/dom/Concurrent.py +++ b/pyGHDL/dom/Concurrent.py @@ -35,6 +35,7 @@ from typing import Iterable from pyTooling.Decorators import export from pyGHDL.dom.Range import Range +from pyGHDL.dom.Symbol import ArchitectureSymbol, EntityInstantiationSymbol, ComponentInstantiationSymbol, ConfigurationInstantiationSymbol from pyVHDLModel.SyntaxModel import ( GenericAssociationItem as VHDLModel_GenericAssociationItem, PortAssociationItem as VHDLModel_PortAssociationItem, @@ -70,7 +71,7 @@ from pyVHDLModel.SyntaxModel import ( from pyGHDL.libghdl import Iir, utils from pyGHDL.libghdl.vhdl import nodes from pyGHDL.dom import DOMMixin, DOMException, Position -from pyGHDL.dom._Utils import GetNameOfNode +from pyGHDL.dom._Utils import GetNameOfNode, GetEntityInstantiationSymbol, GetComponentInstantiationSymbol, GetConfigurationInstantiationSymbol @export @@ -100,32 +101,22 @@ class ComponentInstantiation(VHDLModel_ComponentInstantiation, DOMMixin): self, instantiationNode: Iir, label: str, - componentName: Name, + componentSymbol: ComponentInstantiationSymbol, genericAssociations: Iterable[AssociationItem] = None, portAssociations: Iterable[AssociationItem] = None, ): - super().__init__(label, componentName, genericAssociations, portAssociations) + super().__init__(label, componentSymbol, genericAssociations, portAssociations) DOMMixin.__init__(self, instantiationNode) @classmethod def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ComponentInstantiation": - from pyGHDL.dom._Translate import ( - GetNameFromNode, - GetGenericMapAspect, - GetPortMapAspect, - ) + from pyGHDL.dom._Translate import GetGenericMapAspect, GetPortMapAspect - componentName = GetNameFromNode(instantiatedUnit) + componentSymbol = GetComponentInstantiationSymbol(instantiatedUnit) genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)) portAssociations = GetPortMapAspect(nodes.Get_Port_Map_Aspect_Chain(instantiationNode)) - return cls( - instantiationNode, - label, - componentName, - genericAssociations, - portAssociations, - ) + return cls(instantiationNode, label, componentSymbol, genericAssociations, portAssociations) @export @@ -134,41 +125,30 @@ class EntityInstantiation(VHDLModel_EntityInstantiation, DOMMixin): self, instantiationNode: Iir, label: str, - entityName: Name, - architectureName: Name = None, + entitySymbol: EntityInstantiationSymbol, + architectureSymbol: ArchitectureSymbol = None, # TODO: merge both symbols ? genericAssociations: Iterable[AssociationItem] = None, portAssociations: Iterable[AssociationItem] = None, ): - super().__init__(label, entityName, architectureName, genericAssociations, portAssociations) + super().__init__(label, entitySymbol, architectureSymbol, genericAssociations, portAssociations) DOMMixin.__init__(self, instantiationNode) @classmethod def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "EntityInstantiation": - from pyGHDL.dom._Translate import ( - GetNameFromNode, - GetGenericMapAspect, - GetPortMapAspect, - ) + from pyGHDL.dom._Translate import GetGenericMapAspect, GetPortMapAspect entityId = nodes.Get_Entity_Name(instantiatedUnit) - entityName = GetNameFromNode(entityId) + entitySymbol = GetEntityInstantiationSymbol(entityId) - architectureName = None + architectureSymbol = None architectureId = nodes.Get_Architecture(instantiatedUnit) if architectureId != nodes.Null_Iir: - architectureName = GetNameOfNode(architectureId) + architectureSymbol = ArchitectureSymbol(GetNameOfNode(architectureId), entitySymbol) genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)) portAssociations = GetPortMapAspect(nodes.Get_Port_Map_Aspect_Chain(instantiationNode)) - return cls( - instantiationNode, - label, - entityName, - architectureName, - genericAssociations, - portAssociations, - ) + return cls(instantiationNode, label, entitySymbol, architectureSymbol, genericAssociations, portAssociations) @export @@ -177,34 +157,24 @@ class ConfigurationInstantiation(VHDLModel_ConfigurationInstantiation, DOMMixin) self, instantiationNode: Iir, label: str, - configurationName: Name, + configurationSymbol: ConfigurationInstantiationSymbol, genericAssociations: Iterable[AssociationItem] = None, portAssociations: Iterable[AssociationItem] = None, ): - super().__init__(label, configurationName, genericAssociations, portAssociations) + super().__init__(label, configurationSymbol, genericAssociations, portAssociations) DOMMixin.__init__(self, instantiationNode) @classmethod def parse(cls, instantiationNode: Iir, instantiatedUnit: Iir, label: str) -> "ConfigurationInstantiation": - from pyGHDL.dom._Translate import ( - GetNameFromNode, - GetGenericMapAspect, - GetPortMapAspect, - ) + from pyGHDL.dom._Translate import GetGenericMapAspect, GetPortMapAspect configurationId = nodes.Get_Configuration_Name(instantiatedUnit) - configurationName = GetNameFromNode(configurationId) + configurationSymbol = GetConfigurationInstantiationSymbol(configurationId) genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)) portAssociations = GetPortMapAspect(nodes.Get_Port_Map_Aspect_Chain(instantiationNode)) - return cls( - instantiationNode, - label, - configurationName, - genericAssociations, - portAssociations, - ) + return cls(instantiationNode, label, configurationSymbol, genericAssociations, portAssociations) @export @@ -221,10 +191,7 @@ class ConcurrentBlockStatement(VHDLModel_ConcurrentBlockStatement, DOMMixin): @classmethod def parse(cls, blockNode: Iir, label: str) -> "ConcurrentBlockStatement": - from pyGHDL.dom._Translate import ( - GetDeclaredItemsFromChainedNodes, - GetConcurrentStatementsFromChainedNodes, - ) + from pyGHDL.dom._Translate import GetDeclaredItemsFromChainedNodes, GetConcurrentStatementsFromChainedNodes # genericAssociations = GetGenericMapAspect(nodes.Get_Generic_Map_Aspect_Chain(instantiationNode)) # portAssociations = GetPortMapAspect(nodes.Get_Port_Map_Aspect_Chain(instantiationNode)) @@ -252,10 +219,7 @@ class ProcessStatement(VHDLModel_ProcessStatement, DOMMixin): @classmethod def parse(cls, processNode: Iir, label: str, hasSensitivityList: bool) -> "ProcessStatement": - from pyGHDL.dom._Translate import ( - GetDeclaredItemsFromChainedNodes, - GetSequentialStatementsFromChainedNodes, - ) + from pyGHDL.dom._Translate import GetDeclaredItemsFromChainedNodes, GetSequentialStatementsFromChainedNodes sensitivityList = None if hasSensitivityList: diff --git a/pyGHDL/dom/DesignUnit.py b/pyGHDL/dom/DesignUnit.py index 8d9c677ad..59b04a947 100644 --- a/pyGHDL/dom/DesignUnit.py +++ b/pyGHDL/dom/DesignUnit.py @@ -45,7 +45,6 @@ from pyTooling.Decorators import export from pyVHDLModel import ( ContextUnion as VHDLModel_ContextUnion, - EntityOrSymbol as VHDLModel_EntityOrSymbol, LibraryClause as VHDLModel_LibraryClause, UseClause as VHDLModel_UseClause, ContextReference as VHDLModel_ContextReference, @@ -76,7 +75,6 @@ from pyGHDL.dom._Translate import ( GetDeclaredItemsFromChainedNodes, GetConcurrentStatementsFromChainedNodes, ) -from pyGHDL.dom.Names import SimpleName from pyGHDL.dom.Symbol import EntitySymbol, ContextReferenceSymbol, LibraryReferenceSymbol, PackageSymbol @@ -155,7 +153,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin): self, node: Iir, identifier: str, - entity: VHDLModel_EntityOrSymbol, + entity: EntitySymbol, contextItems: Iterable[VHDLModel_ContextUnion] = None, declaredItems: Iterable = None, statements: Iterable["ConcurrentStatement"] = None, diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py index 40d877c3f..a9b919ccb 100644 --- a/pyGHDL/dom/Symbol.py +++ b/pyGHDL/dom/Symbol.py @@ -35,9 +35,6 @@ from typing import List, Iterator from pyTooling.Decorators import export, InheritDocString from pyVHDLModel.SyntaxModel import ( - EntitySymbol as VHDLModel_EntitySymbol, - ArchitectureSymbol as VHDLModel_ArchitectureSymbol, - PackageSymbol as VHDLModel_PackageSymbol, SimpleSubtypeSymbol as VHDLModel_SimpleSubtypeSymbol, ConstrainedScalarSubtypeSymbol as VHDLModel_ConstrainedScalarSubtypeSymbol, ConstrainedCompositeSubtypeSymbol as VHDLModel_ConstrainedCompositeSubtypeSymbol, @@ -50,76 +47,107 @@ from pyVHDLModel.SyntaxModel import ( PackageMembersReferenceSymbol as VHDLModel_PackageMembersReferenceSymbol, AllPackageMembersReferenceSymbol as VHDLModel_AllPackageMembersReferenceSymbol, ContextReferenceSymbol as VHDLModel_ContextReferenceSymbol, + EntityInstantiationSymbol as VHDLModel_EntityInstantiationSymbol, + ComponentInstantiationSymbol as VHDLModel_ComponentInstantiationSymbol, + ConfigurationInstantiationSymbol as VHDLModel_ConfigurationInstantiationSymbol, + EntitySymbol as VHDLModel_EntitySymbol, + ArchitectureSymbol as VHDLModel_ArchitectureSymbol, + PackageSymbol as VHDLModel_PackageSymbol, ) from pyGHDL.libghdl._types import Iir from pyGHDL.dom import DOMMixin -from pyGHDL.dom.Names import SimpleName from pyGHDL.dom.Range import Range @export class LibraryReferenceSymbol(VHDLModel_LibraryReferenceSymbol, DOMMixin): @InheritDocString(VHDLModel_LibraryReferenceSymbol) - def __init__(self, libraryNode: Iir, identifier: str): + def __init__(self, identifierNode: Iir, identifier: str): super().__init__(identifier) - DOMMixin.__init__(self, libraryNode) + DOMMixin.__init__(self, identifierNode) @export class PackageReferenceSymbol(VHDLModel_PackageReferenceSymbol, DOMMixin): @InheritDocString(VHDLModel_PackageReferenceSymbol) - def __init__(self, libraryNode: Iir, identifier: str, prefix: LibraryReferenceSymbol): + def __init__(self, identifierNode: Iir, identifier: str, prefix: LibraryReferenceSymbol): super().__init__(identifier, prefix) - DOMMixin.__init__(self, libraryNode) + DOMMixin.__init__(self, identifierNode) @export class PackageMembersReferenceSymbol(VHDLModel_PackageMembersReferenceSymbol, DOMMixin): @InheritDocString(VHDLModel_PackageMembersReferenceSymbol) - def __init__(self, libraryNode: Iir, identifier: str, prefix: PackageReferenceSymbol): + def __init__(self, identifierNode: Iir, identifier: str, prefix: PackageReferenceSymbol): super().__init__(identifier, prefix) - DOMMixin.__init__(self, libraryNode) + DOMMixin.__init__(self, identifierNode) @export class AllPackageMembersReferenceSymbol(VHDLModel_AllPackageMembersReferenceSymbol, DOMMixin): @InheritDocString(VHDLModel_AllPackageMembersReferenceSymbol) - def __init__(self, libraryNode: Iir, prefix: PackageReferenceSymbol): + def __init__(self, identifierNode: Iir, prefix: PackageReferenceSymbol): super().__init__(prefix) - DOMMixin.__init__(self, libraryNode) + DOMMixin.__init__(self, identifierNode) @export class ContextReferenceSymbol(VHDLModel_ContextReferenceSymbol, DOMMixin): @InheritDocString(VHDLModel_ContextReferenceSymbol) - def __init__(self, libraryNode: Iir, identifier: str, prefix: LibraryReferenceSymbol): + def __init__(self, identifierNode: Iir, identifier: str, prefix: LibraryReferenceSymbol): super().__init__(identifier, prefix) - DOMMixin.__init__(self, libraryNode) + DOMMixin.__init__(self, identifierNode) + + +@export +class EntityInstantiationSymbol(VHDLModel_EntityInstantiationSymbol, DOMMixin): + @InheritDocString(VHDLModel_EntityInstantiationSymbol) + def __init__(self, identifierNode: Iir, identifier: str, prefix: LibraryReferenceSymbol): + super().__init__(identifier, prefix) + DOMMixin.__init__(self, identifierNode) + + +@export +class ComponentInstantiationSymbol(VHDLModel_ComponentInstantiationSymbol, DOMMixin): + @InheritDocString(VHDLModel_ComponentInstantiationSymbol) + def __init__(self, identifierNode: Iir, identifier: str): + super().__init__(identifier) + DOMMixin.__init__(self, identifierNode) + + +@export +class ConfigurationInstantiationSymbol(VHDLModel_ConfigurationInstantiationSymbol, DOMMixin): + @InheritDocString(VHDLModel_ConfigurationInstantiationSymbol) + def __init__(self, identifierNode: Iir, identifier: str): + super().__init__(identifier) + DOMMixin.__init__(self, identifierNode) @export class EntitySymbol(VHDLModel_EntitySymbol, DOMMixin): @InheritDocString(VHDLModel_EntitySymbol) - def __init__(self, node: Iir, identifier: str): + def __init__(self, identifierNode: Iir, identifier: str): super().__init__(identifier) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, identifierNode) @export class ArchitectureSymbol(VHDLModel_ArchitectureSymbol, DOMMixin): @InheritDocString(VHDLModel_ArchitectureSymbol) - def __init__(self, node: Iir, identifier: str, prefix: EntitySymbol): + def __init__(self, identifierNode: Iir, identifier: str, prefix: EntitySymbol): super().__init__(identifier, prefix) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, identifierNode) @export class PackageSymbol(VHDLModel_PackageSymbol, DOMMixin): @InheritDocString(VHDLModel_PackageSymbol) - def __init__(self, node: Iir, identifier: str): + def __init__(self, identifierNode: Iir, identifier: str): super().__init__(identifier) - DOMMixin.__init__(self, node) + DOMMixin.__init__(self, identifierNode) +# TODO: |||| |||| +# TODO: VVVV old symbols VVVV @export class SimpleSubtypeSymbol(VHDLModel_SimpleSubtypeSymbol, DOMMixin): diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py index f471824d3..6d3ced3ef 100644 --- a/pyGHDL/dom/_Translate.py +++ b/pyGHDL/dom/_Translate.py @@ -832,6 +832,7 @@ def GetConcurrentStatementsFromChainedNodes( elif kind == nodes.Iir_Kind.Component_Instantiation_Statement: instantiatedUnit = nodes.Get_Instantiated_Unit(statement) instantiatedUnitKind = GetIirKindOfNode(instantiatedUnit) + if instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Entity: yield EntityInstantiation.parse(statement, instantiatedUnit, label) elif instantiatedUnitKind == nodes.Iir_Kind.Entity_Aspect_Configuration: diff --git a/pyGHDL/dom/_Utils.py b/pyGHDL/dom/_Utils.py index 3803374f3..20171b45c 100644 --- a/pyGHDL/dom/_Utils.py +++ b/pyGHDL/dom/_Utils.py @@ -39,7 +39,7 @@ from pyGHDL.dom.Symbol import ( PackageReferenceSymbol, PackageMembersReferenceSymbol, AllPackageMembersReferenceSymbol, - ContextReferenceSymbol, + ContextReferenceSymbol, EntityInstantiationSymbol, ComponentInstantiationSymbol, ConfigurationInstantiationSymbol, ) from pyVHDLModel.SyntaxModel import Mode @@ -145,6 +145,25 @@ def GetModeOfNode(node: Iir) -> Mode: raise DOMException(f"Unknown mode '{ex.args[0]}'.") from ex +def GetLibrarySymbol(node: Iir) -> LibraryReferenceSymbol: + kind = GetIirKindOfNode(node) + if kind == nodes.Iir_Kind.Simple_Name: + name = GetNameOfNode(node) + return LibraryReferenceSymbol(node, name) + else: + raise DOMException(f"{kind} at {Position.parse(node)}") + + +def GetPackageSymbol(node: Iir) -> PackageReferenceSymbol: + kind = GetIirKindOfNode(node) + if kind == nodes.Iir_Kind.Selected_Name: + name = GetNameOfNode(node) + prefixName = GetLibrarySymbol(nodes.Get_Prefix(node)) + return PackageReferenceSymbol(node, name, prefixName) + else: + raise DOMException(f"{kind.name} at {Position.parse(node)}") + + def GetPackageMemberSymbol(node: Iir) -> Union[PackageMembersReferenceSymbol, AllPackageMembersReferenceSymbol]: kind = GetIirKindOfNode(node) prefixName = GetPackageSymbol(nodes.Get_Prefix(node)) @@ -157,30 +176,39 @@ def GetPackageMemberSymbol(node: Iir) -> Union[PackageMembersReferenceSymbol, Al raise DOMException(f"{kind.name} at {Position.parse(node)}") -def GetPackageSymbol(node: Iir) -> PackageReferenceSymbol: +def GetContextSymbol(node: Iir) -> ContextReferenceSymbol: kind = GetIirKindOfNode(node) if kind == nodes.Iir_Kind.Selected_Name: name = GetNameOfNode(node) prefixName = GetLibrarySymbol(nodes.Get_Prefix(node)) - return PackageReferenceSymbol(node, name, prefixName) + return ContextReferenceSymbol(node, name, prefixName) else: raise DOMException(f"{kind.name} at {Position.parse(node)}") -def GetContextSymbol(node: Iir) -> ContextReferenceSymbol: +def GetEntityInstantiationSymbol(node: Iir) -> EntityInstantiationSymbol: kind = GetIirKindOfNode(node) if kind == nodes.Iir_Kind.Selected_Name: name = GetNameOfNode(node) prefixName = GetLibrarySymbol(nodes.Get_Prefix(node)) - return ContextReferenceSymbol(node, name, prefixName) + return EntityInstantiationSymbol(node, name, prefixName) else: raise DOMException(f"{kind.name} at {Position.parse(node)}") -def GetLibrarySymbol(node: Iir) -> LibraryReferenceSymbol: +def GetComponentInstantiationSymbol(node: Iir) -> ComponentInstantiationSymbol: kind = GetIirKindOfNode(node) if kind == nodes.Iir_Kind.Simple_Name: name = GetNameOfNode(node) - return LibraryReferenceSymbol(node, name) + return ComponentInstantiationSymbol(node, name) else: - raise DOMException(f"{kind} at {Position.parse(node)}") + raise DOMException(f"{kind.name} at {Position.parse(node)}") + + +def GetConfigurationInstantiationSymbol(node: Iir) -> ConfigurationInstantiationSymbol: + kind = GetIirKindOfNode(node) + if kind == nodes.Iir_Kind.Simple_Name: + name = GetNameOfNode(node) + return ConfigurationInstantiationSymbol(node, name) + else: + raise DOMException(f"{kind.name} at {Position.parse(node)}") diff --git a/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl new file mode 100644 index 000000000..88074c884 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl @@ -0,0 +1,42 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +context work.StopWatch_ctx; + + +-- Encoder that translates from 4-bit binary (BCD) to 7-segment code. +entity seg7_Encoder is + port ( + BCDValue : in T_BCD; + Dot : in std_logic := '0'; + + Seg7Code : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of seg7_Encoder is + +begin + process(BCDValue, Dot) + variable temp : std_logic_vector(6 downto 0); + begin + case BCDValue is -- segments: GFEDCBA -- Segment Pos. Index Pos. + when x"0" => temp := "0111111"; -- + when x"1" => temp := "0000110"; -- + when x"2" => temp := "1011011"; -- AAA 000 + when x"3" => temp := "1001111"; -- F B 5 1 + when x"4" => temp := "1100110"; -- F B 5 1 + when x"5" => temp := "1101101"; -- GGG 666 + when x"6" => temp := "1111101"; -- E C 4 2 + when x"7" => temp := "0000111"; -- E C 4 2 + when x"8" => temp := "1111111"; -- DDD DOT 333 7 + when x"9" => temp := "1101111"; -- + when others => temp := "XXXXXXX"; -- + end case; + + Seg7Code <= Dot & temp; + end process; +end architecture; diff --git a/testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl b/testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl new file mode 100644 index 000000000..88074c884 --- /dev/null +++ b/testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl @@ -0,0 +1,42 @@ +-- Author: Patrick Lehmann +-- License: MIT +-- +-- A generic counter module used in the StopWatch example. +-- +context work.StopWatch_ctx; + + +-- Encoder that translates from 4-bit binary (BCD) to 7-segment code. +entity seg7_Encoder is + port ( + BCDValue : in T_BCD; + Dot : in std_logic := '0'; + + Seg7Code : out std_logic_vector(7 downto 0) + ); +end entity; + + +architecture rtl of seg7_Encoder is + +begin + process(BCDValue, Dot) + variable temp : std_logic_vector(6 downto 0); + begin + case BCDValue is -- segments: GFEDCBA -- Segment Pos. Index Pos. + when x"0" => temp := "0111111"; -- + when x"1" => temp := "0000110"; -- + when x"2" => temp := "1011011"; -- AAA 000 + when x"3" => temp := "1001111"; -- F B 5 1 + when x"4" => temp := "1100110"; -- F B 5 1 + when x"5" => temp := "1101101"; -- GGG 666 + when x"6" => temp := "1111101"; -- E C 4 2 + when x"7" => temp := "0000111"; -- E C 4 2 + when x"8" => temp := "1111111"; -- DDD DOT 333 7 + when x"9" => temp := "1101111"; -- + when others => temp := "XXXXXXX"; -- + end case; + + Seg7Code <= Dot & temp; + end process; +end architecture; -- cgit v1.2.3