aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortgingold <tgingold@users.noreply.github.com>2022-12-31 13:53:58 +0100
committerGitHub <noreply@github.com>2022-12-31 13:53:58 +0100
commit9521df67d938896f71c2ca284720b131879406d6 (patch)
tree0dfa358d3e7eb78393518395e3b3ebcc066be8e8
parentda0cd6274648094a7ab8876cc59f7ac05b8d56e7 (diff)
parent882563d217d364d38a362d39bc34b7a6f16ce726 (diff)
downloadghdl-9521df67d938896f71c2ca284720b131879406d6.tar.gz
ghdl-9521df67d938896f71c2ca284720b131879406d6.tar.bz2
ghdl-9521df67d938896f71c2ca284720b131879406d6.zip
Merge pull request #2289 from Paebbels/paebbels/pyVHDLModel-updates
Updates due to pyVHDLModel Enhancements
-rwxr-xr-xpyGHDL/cli/dom.py25
-rw-r--r--pyGHDL/dom/Aggregates.py2
-rw-r--r--pyGHDL/dom/Concurrent.py90
-rw-r--r--pyGHDL/dom/DesignUnit.py54
-rw-r--r--pyGHDL/dom/Expression.py3
-rw-r--r--pyGHDL/dom/InterfaceItem.py3
-rw-r--r--pyGHDL/dom/Literal.py2
-rw-r--r--pyGHDL/dom/Misc.py2
-rw-r--r--pyGHDL/dom/Names.py2
-rw-r--r--pyGHDL/dom/NonStandard.py22
-rw-r--r--pyGHDL/dom/Object.py2
-rw-r--r--pyGHDL/dom/PSL.py3
-rw-r--r--pyGHDL/dom/Range.py2
-rw-r--r--pyGHDL/dom/Symbol.py100
-rw-r--r--pyGHDL/dom/_Translate.py4
-rw-r--r--pyGHDL/dom/_Utils.py90
-rw-r--r--pyGHDL/dom/formatting/prettyprint.py86
-rw-r--r--pyGHDL/dom/requirements.txt2
-rw-r--r--testsuite/pyunit/dom/StopWatch.py61
-rw-r--r--testsuite/pyunit/dom/VHDLLibraries.py2
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl2
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl20
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/StopWatch.ctx.vhdl11
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl14
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl4
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/Utilities.ctx.vhdl12
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl20
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl16
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl6
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl8
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl37
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl4
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl5
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl7
-rw-r--r--testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl8
35 files changed, 507 insertions, 224 deletions
diff --git a/pyGHDL/cli/dom.py b/pyGHDL/cli/dom.py
index 68bd33c34..442ad6688 100755
--- a/pyGHDL/cli/dom.py
+++ b/pyGHDL/cli/dom.py
@@ -280,11 +280,11 @@ class Application(LineTerminal, ArgParseMixin):
)
)
elif args.Directory is not None:
- d: Path = args.Directory
+ d: Path = args.Directory.resolve()
if not d.exists():
self.WriteError(f"Directory '{d!s}' does not exist.")
- for file in d.glob("**/*.vhd?"):
+ for file in d.glob("**/*.vhd*"):
self.WriteNormal(f"Parsing file '{file!s}'")
document = self.addFile(file, "pretty")
self.WriteInfo(
@@ -299,16 +299,23 @@ 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)
-
if not self._design.Documents:
self.WriteFatal("No files processed at all.")
+ self._design.LoadDefaultLibraries()
+ self._design.Analyze()
+ self.WriteInfo(
+ dedent(
+ """\
+ default library load time: {:5.3f} us
+ dependency analysis time: {:5.3f} us
+ """
+ ).format(
+ self._design._loadDefaultLibraryTime * 10**6,
+ self._design._analyzeTime * 10**6,
+ )
+ )
+
PP = PrettyPrint()
buffer = []
diff --git a/pyGHDL/dom/Aggregates.py b/pyGHDL/dom/Aggregates.py
index 02e071cb5..a1fe40866 100644
--- a/pyGHDL/dom/Aggregates.py
+++ b/pyGHDL/dom/Aggregates.py
@@ -54,8 +54,6 @@ from pyGHDL.libghdl._types import Iir
from pyGHDL.dom import DOMMixin
from pyGHDL.dom.Range import Range
-__all__ = []
-
@export
class SimpleAggregateElement(VHDLModel_SimpleAggregateElement, DOMMixin):
diff --git a/pyGHDL/dom/Concurrent.py b/pyGHDL/dom/Concurrent.py
index df3e97a2a..8dcec9bdb 100644
--- a/pyGHDL/dom/Concurrent.py
+++ b/pyGHDL/dom/Concurrent.py
@@ -35,6 +35,12 @@ 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 +76,12 @@ 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 +111,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 +135,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 +167,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 +201,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 +229,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 eebf888bc..881a7f2eb 100644
--- a/pyGHDL/dom/DesignUnit.py
+++ b/pyGHDL/dom/DesignUnit.py
@@ -39,17 +39,17 @@ This module contains all DOM classes for VHDL's design units (:class:`context <E
"""
-from typing import Iterable
+from typing import Iterable, Union
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,
Name,
+ ContextUnion,
)
from pyVHDLModel.SyntaxModel import (
Entity as VHDLModel_Entity,
@@ -63,26 +63,20 @@ from pyVHDLModel.SyntaxModel import (
GenericInterfaceItem,
PortInterfaceItem,
ConcurrentStatement,
- PackageReferenceSymbol,
- ContextReferenceSymbol,
)
from pyGHDL.libghdl import utils
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom import DOMMixin, Position, DOMException
-from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode
+from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode, GetPackageMemberSymbol, GetContextSymbol
from pyGHDL.dom._Translate import (
GetGenericsFromChainedNodes,
GetPortsFromChainedNodes,
GetDeclaredItemsFromChainedNodes,
GetConcurrentStatementsFromChainedNodes,
)
-from pyGHDL.dom.Names import SimpleName
-from pyGHDL.dom.Symbol import EntitySymbol
-
-
-__all__ = []
+from pyGHDL.dom.Symbol import EntitySymbol, ContextReferenceSymbol, LibraryReferenceSymbol, PackageSymbol
@export
@@ -100,11 +94,9 @@ class UseClause(VHDLModel_UseClause, DOMMixin):
@classmethod
def parse(cls, useNode: Iir):
- from pyGHDL.dom._Translate import GetNameFromNode
-
- uses = [PackageReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(useNode)))]
+ uses = [GetPackageMemberSymbol(nodes.Get_Selected_Name(useNode))]
for use in utils.chain_iter(nodes.Get_Use_Clause_Chain(useNode)):
- uses.append(PackageReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(use))))
+ uses.append(GetPackageMemberSymbol(nodes.Get_Selected_Name(use)))
return cls(useNode, uses)
@@ -117,11 +109,9 @@ class ContextReference(VHDLModel_ContextReference, DOMMixin):
@classmethod
def parse(cls, contextNode: Iir):
- from pyGHDL.dom._Translate import GetNameFromNode
-
- contexts = [ContextReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(contextNode)))]
+ contexts = [GetContextSymbol(nodes.Get_Selected_Name(contextNode))]
for context in utils.chain_iter(nodes.Get_Context_Reference_Chain(contextNode)):
- contexts.append(ContextReferenceSymbol(GetNameFromNode(nodes.Get_Selected_Name(context))))
+ contexts.append(GetContextSymbol(nodes.Get_Selected_Name(context)))
return cls(contextNode, contexts)
@@ -164,7 +154,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,
@@ -178,8 +168,7 @@ class Architecture(VHDLModel_Architecture, DOMMixin):
name = GetNameOfNode(architectureNode)
documentation = GetDocumentationOfNode(architectureNode)
entityNameNode = nodes.Get_Entity_Name(architectureNode)
- entityName = GetNameOfNode(entityNameNode)
- entitySymbol = EntitySymbol(entityNameNode, SimpleName(entityNameNode, entityName))
+ entitySymbol = EntitySymbol(entityNameNode, GetNameOfNode(entityNameNode))
declaredItems = GetDeclaredItemsFromChainedNodes(
nodes.Get_Declaration_Chain(architectureNode), "architecture", name
)
@@ -252,23 +241,26 @@ class PackageBody(VHDLModel_PackageBody, DOMMixin):
def __init__(
self,
node: Iir,
- identifier: str,
+ packageSymbol: PackageSymbol,
contextItems: Iterable[VHDLModel_ContextUnion] = None,
declaredItems: Iterable = None,
documentation: str = None,
):
- super().__init__(identifier, contextItems, declaredItems, documentation)
+ super().__init__(packageSymbol, contextItems, declaredItems, documentation)
DOMMixin.__init__(self, node)
@classmethod
def parse(cls, packageBodyNode: Iir, contextItems: Iterable[VHDLModel_ContextUnion]):
- name = GetNameOfNode(packageBodyNode)
+ packageName = GetNameOfNode(packageBodyNode)
+ packageSymbol = PackageSymbol(packageBodyNode, packageName)
documentation = GetDocumentationOfNode(packageBodyNode)
- declaredItems = GetDeclaredItemsFromChainedNodes(nodes.Get_Declaration_Chain(packageBodyNode), "package", name)
+ declaredItems = GetDeclaredItemsFromChainedNodes(
+ nodes.Get_Declaration_Chain(packageBodyNode), "package", packageName
+ )
# FIXME: read use clauses
- return cls(packageBodyNode, name, contextItems, declaredItems, documentation)
+ return cls(packageBodyNode, packageSymbol, contextItems, declaredItems, documentation)
@export
@@ -304,11 +296,10 @@ class Context(VHDLModel_Context, DOMMixin):
self,
node: Iir,
identifier: str,
- libraryReferences: Iterable[LibraryClause] = None,
- packageReferences: Iterable[UseClause] = None,
+ references: Iterable[ContextUnion] = None,
documentation: str = None,
):
- super().__init__(identifier, libraryReferences, packageReferences, documentation)
+ super().__init__(identifier, references, documentation)
DOMMixin.__init__(self, node)
@classmethod
@@ -323,7 +314,8 @@ class Context(VHDLModel_Context, DOMMixin):
for item in utils.chain_iter(nodes.Get_Context_Items(contextNode)):
kind = GetIirKindOfNode(item)
if kind is nodes.Iir_Kind.Library_Clause:
- names.append(SimpleName(item, GetNameOfNode(item)))
+ libraryIdentifier = GetNameOfNode(item)
+ names.append(LibraryReferenceSymbol(item, libraryIdentifier))
if nodes.Get_Has_Identifier_List(item):
continue
@@ -331,6 +323,8 @@ class Context(VHDLModel_Context, DOMMixin):
names = []
elif kind is nodes.Iir_Kind.Use_Clause:
items.append(UseClause.parse(item))
+ elif kind is nodes.Iir_Kind.Context_Reference:
+ items.append(ContextReference.parse(item))
else:
pos = Position.parse(item)
raise DOMException(f"Unknown context item kind '{kind.name}' in context at line {pos.Line}.")
diff --git a/pyGHDL/dom/Expression.py b/pyGHDL/dom/Expression.py
index 4a61597e2..81ecfa380 100644
--- a/pyGHDL/dom/Expression.py
+++ b/pyGHDL/dom/Expression.py
@@ -104,9 +104,6 @@ from pyGHDL.dom.Aggregates import (
)
-__all__ = []
-
-
class _ParseUnaryExpressionMixin:
@classmethod
def parse(cls, node: Iir) -> VHDLModel_UnaryExpression:
diff --git a/pyGHDL/dom/InterfaceItem.py b/pyGHDL/dom/InterfaceItem.py
index aa63f3094..44b67a79c 100644
--- a/pyGHDL/dom/InterfaceItem.py
+++ b/pyGHDL/dom/InterfaceItem.py
@@ -57,9 +57,6 @@ from pyGHDL.dom._Utils import GetNameOfNode, GetModeOfNode, GetDocumentationOfNo
from pyGHDL.dom._Translate import GetSubtypeIndicationFromNode, GetExpressionFromNode
-__all__ = []
-
-
@export
class GenericConstantInterfaceItem(VHDLModel_GenericConstantInterfaceItem, DOMMixin):
def __init__(
diff --git a/pyGHDL/dom/Literal.py b/pyGHDL/dom/Literal.py
index c054273c4..e8a87bc19 100644
--- a/pyGHDL/dom/Literal.py
+++ b/pyGHDL/dom/Literal.py
@@ -48,8 +48,6 @@ from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode
-__all__ = []
-
@export
class NullLiteral(VHDLModel_NullLiteral, DOMMixin):
diff --git a/pyGHDL/dom/Misc.py b/pyGHDL/dom/Misc.py
index 8f85db222..71860f676 100644
--- a/pyGHDL/dom/Misc.py
+++ b/pyGHDL/dom/Misc.py
@@ -44,8 +44,6 @@ from pyGHDL.libghdl._types import Iir
from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode
-__all__ = []
-
@export
class Alias(VHDLModel_Alias, DOMMixin):
diff --git a/pyGHDL/dom/Names.py b/pyGHDL/dom/Names.py
index d601739db..c66d20661 100644
--- a/pyGHDL/dom/Names.py
+++ b/pyGHDL/dom/Names.py
@@ -48,8 +48,6 @@ from pyVHDLModel.SyntaxModel import (
from pyGHDL.libghdl._types import Iir
from pyGHDL.dom import DOMMixin
-__all__ = []
-
@export
class SimpleName(VHDLModel_SimpleName, DOMMixin):
diff --git a/pyGHDL/dom/NonStandard.py b/pyGHDL/dom/NonStandard.py
index 0a2ead728..e0b837c57 100644
--- a/pyGHDL/dom/NonStandard.py
+++ b/pyGHDL/dom/NonStandard.py
@@ -48,7 +48,6 @@ from pyVHDLModel.SyntaxModel import (
Design as VHDLModel_Design,
Library as VHDLModel_Library,
Document as VHDLModel_Document,
- LibraryReferenceSymbol,
)
from pyGHDL.libghdl import (
@@ -84,10 +83,9 @@ from pyGHDL.dom.DesignUnit import (
UseClause,
ContextReference,
)
+from pyGHDL.dom.Symbol import LibraryReferenceSymbol
from pyGHDL.dom.PSL import VerificationUnit, VerificationProperty, VerificationMode
-__all__ = []
-
@export
class Design(VHDLModel_Design):
@@ -114,6 +112,21 @@ class Design(VHDLModel_Design):
if libghdl_analyze_init_status() != 0:
raise LibGHDLException("Error initializing 'libghdl'.")
+ def LoadDefaultLibraries(self):
+ t1 = time.perf_counter()
+
+ super().LoadStdLibrary()
+ super().LoadIEEELibrary()
+
+ self._loadDefaultLibraryTime = time.perf_counter() - t1
+
+ def Analyze(self):
+ t1 = time.perf_counter()
+
+ super().Analyze()
+
+ self._analyzeTime = time.perf_counter() - t1
+
@export
class Library(VHDLModel_Library):
@@ -197,7 +210,8 @@ class Document(VHDLModel_Document):
for item in utils.chain_iter(context):
itemKind = GetIirKindOfNode(item)
if itemKind is nodes.Iir_Kind.Library_Clause:
- contextNames.append(LibraryReferenceSymbol(SimpleName(item, GetNameOfNode(item))))
+ libraryIdentifier = GetNameOfNode(item)
+ contextNames.append(LibraryReferenceSymbol(item, libraryIdentifier))
if nodes.Get_Has_Identifier_List(item):
continue
diff --git a/pyGHDL/dom/Object.py b/pyGHDL/dom/Object.py
index 1079eae4a..953fae02a 100644
--- a/pyGHDL/dom/Object.py
+++ b/pyGHDL/dom/Object.py
@@ -50,8 +50,6 @@ from pyGHDL.libghdl.vhdl import nodes
from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode, GetDocumentationOfNode
-__all__ = []
-
@export
class Constant(VHDLModel_Constant, DOMMixin):
diff --git a/pyGHDL/dom/PSL.py b/pyGHDL/dom/PSL.py
index 0217e0639..f935f7849 100644
--- a/pyGHDL/dom/PSL.py
+++ b/pyGHDL/dom/PSL.py
@@ -53,9 +53,6 @@ from pyGHDL.dom import DOMMixin
from pyGHDL.dom._Utils import GetNameOfNode
-__all__ = []
-
-
@export
class VerificationUnit(VHDLModel_VerificationUnit, DOMMixin):
def __init__(
diff --git a/pyGHDL/dom/Range.py b/pyGHDL/dom/Range.py
index c6f783139..2674a43f4 100644
--- a/pyGHDL/dom/Range.py
+++ b/pyGHDL/dom/Range.py
@@ -34,8 +34,6 @@ from pyTooling.Decorators import export
from pyVHDLModel.SyntaxModel import Range as VHDLModel_Range
-__all__ = []
-
@export
class Range(VHDLModel_Range):
diff --git a/pyGHDL/dom/Symbol.py b/pyGHDL/dom/Symbol.py
index 0dd0fefa9..76f794650 100644
--- a/pyGHDL/dom/Symbol.py
+++ b/pyGHDL/dom/Symbol.py
@@ -34,11 +34,7 @@ from typing import List, Iterator
from pyTooling.Decorators import export, InheritDocString
-from pyGHDL.dom.Names import SimpleName
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,
@@ -46,37 +42,113 @@ from pyVHDLModel.SyntaxModel import (
IndexedObjectOrFunctionCallSymbol as VHDLModel_IndexedObjectOrFunctionCallSymbol,
ConstraintUnion,
Name,
+ LibraryReferenceSymbol as VHDLModel_LibraryReferenceSymbol,
+ PackageReferenceSymbol as VHDLModel_PackageReferenceSymbol,
+ 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.Range import Range
-__all__ = []
+@export
+class LibraryReferenceSymbol(VHDLModel_LibraryReferenceSymbol, DOMMixin):
+ @InheritDocString(VHDLModel_LibraryReferenceSymbol)
+ def __init__(self, identifierNode: Iir, identifier: str):
+ super().__init__(identifier)
+ DOMMixin.__init__(self, identifierNode)
+
+
+@export
+class PackageReferenceSymbol(VHDLModel_PackageReferenceSymbol, DOMMixin):
+ @InheritDocString(VHDLModel_PackageReferenceSymbol)
+ def __init__(self, identifierNode: Iir, identifier: str, prefix: LibraryReferenceSymbol):
+ super().__init__(identifier, prefix)
+ DOMMixin.__init__(self, identifierNode)
+
+
+@export
+class PackageMembersReferenceSymbol(VHDLModel_PackageMembersReferenceSymbol, DOMMixin):
+ @InheritDocString(VHDLModel_PackageMembersReferenceSymbol)
+ def __init__(self, identifierNode: Iir, identifier: str, prefix: PackageReferenceSymbol):
+ super().__init__(identifier, prefix)
+ DOMMixin.__init__(self, identifierNode)
+
+
+@export
+class AllPackageMembersReferenceSymbol(VHDLModel_AllPackageMembersReferenceSymbol, DOMMixin):
+ @InheritDocString(VHDLModel_AllPackageMembersReferenceSymbol)
+ def __init__(self, identifierNode: Iir, prefix: PackageReferenceSymbol):
+ super().__init__(prefix)
+ DOMMixin.__init__(self, identifierNode)
+
+
+@export
+class ContextReferenceSymbol(VHDLModel_ContextReferenceSymbol, DOMMixin):
+ @InheritDocString(VHDLModel_ContextReferenceSymbol)
+ def __init__(self, identifierNode: Iir, identifier: str, prefix: LibraryReferenceSymbol):
+ super().__init__(identifier, prefix)
+ 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, entityName: SimpleName):
- super().__init__(entityName)
- DOMMixin.__init__(self, node)
+ def __init__(self, identifierNode: Iir, identifier: str):
+ super().__init__(identifier)
+ DOMMixin.__init__(self, identifierNode)
@export
class ArchitectureSymbol(VHDLModel_ArchitectureSymbol, DOMMixin):
@InheritDocString(VHDLModel_ArchitectureSymbol)
- def __init__(self, node: Iir, architectureName: SimpleName):
- super().__init__(architectureName)
- DOMMixin.__init__(self, node)
+ def __init__(self, identifierNode: Iir, identifier: str, prefix: EntitySymbol):
+ super().__init__(identifier, prefix)
+ DOMMixin.__init__(self, identifierNode)
@export
class PackageSymbol(VHDLModel_PackageSymbol, DOMMixin):
@InheritDocString(VHDLModel_PackageSymbol)
- def __init__(self, node: Iir, packageName: SimpleName):
- super().__init__(packageName)
- DOMMixin.__init__(self, node)
+ def __init__(self, identifierNode: Iir, identifier: str):
+ super().__init__(identifier)
+ DOMMixin.__init__(self, identifierNode)
+
+
+# TODO: |||| ||||
+# TODO: VVVV old symbols VVVV
@export
diff --git a/pyGHDL/dom/_Translate.py b/pyGHDL/dom/_Translate.py
index 20d173710..6d3ced3ef 100644
--- a/pyGHDL/dom/_Translate.py
+++ b/pyGHDL/dom/_Translate.py
@@ -173,9 +173,6 @@ from pyGHDL.dom.Misc import Alias
from pyGHDL.dom.PSL import DefaultClock
-__all__ = []
-
-
@export
def GetNameFromNode(node: Iir) -> Name:
kind = GetIirKindOfNode(node)
@@ -835,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 83f10eae8..09f336c03 100644
--- a/pyGHDL/dom/_Utils.py
+++ b/pyGHDL/dom/_Utils.py
@@ -30,17 +30,27 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# ============================================================================
+from typing import Union
+
from pyTooling.Decorators import export
+from pyGHDL.dom.Symbol import (
+ LibraryReferenceSymbol,
+ PackageReferenceSymbol,
+ PackageMembersReferenceSymbol,
+ AllPackageMembersReferenceSymbol,
+ ContextReferenceSymbol,
+ EntityInstantiationSymbol,
+ ComponentInstantiationSymbol,
+ ConfigurationInstantiationSymbol,
+)
from pyVHDLModel.SyntaxModel import Mode
from pyGHDL.libghdl import LibGHDLException, name_table, errorout_memory, files_map, file_comments
from pyGHDL.libghdl._types import Iir
from pyGHDL.libghdl.vhdl import nodes, utils
from pyGHDL.libghdl.vhdl.nodes import Null_Iir
-from pyGHDL.dom import DOMException
-
-__all__ = []
+from pyGHDL.dom import DOMException, Position
__MODE_TRANSLATION = {
nodes.Iir_Mode.In_Mode: Mode.In,
@@ -136,3 +146,77 @@ def GetModeOfNode(node: Iir) -> Mode:
return __MODE_TRANSLATION[nodes.Get_Mode(node)]
except KeyError as ex:
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)
+ name = GetNameOfNode(node)
+ if kind == nodes.Iir_Kind.Selected_Name:
+ prefixName = GetLibrarySymbol(nodes.Get_Prefix(node))
+ return PackageReferenceSymbol(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Simple_Name:
+ return PackageReferenceSymbol(node, name, None)
+ else:
+ raise DOMException(f"{kind.name} at {Position.parse(node)}")
+
+
+def GetPackageMemberSymbol(
+ node: Iir,
+) -> Union[PackageReferenceSymbol, PackageMembersReferenceSymbol, AllPackageMembersReferenceSymbol]:
+ kind = GetIirKindOfNode(node)
+ prefixName = GetPackageSymbol(nodes.Get_Prefix(node))
+ if kind == nodes.Iir_Kind.Selected_Name:
+ name = GetNameOfNode(node)
+ return PackageMembersReferenceSymbol(node, name, prefixName)
+ elif kind == nodes.Iir_Kind.Selected_By_All_Name:
+ prefixName = GetPackageSymbol(nodes.Get_Prefix(node))
+ return AllPackageMembersReferenceSymbol(node, prefixName)
+ else:
+ raise DOMException(f"{kind.name} at {Position.parse(node)}")
+
+
+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 ContextReferenceSymbol(node, name, prefixName)
+ else:
+ raise DOMException(f"{kind.name} at {Position.parse(node)}")
+
+
+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 EntityInstantiationSymbol(node, name, prefixName)
+ else:
+ raise DOMException(f"{kind.name} at {Position.parse(node)}")
+
+
+def GetComponentInstantiationSymbol(node: Iir) -> ComponentInstantiationSymbol:
+ kind = GetIirKindOfNode(node)
+ if kind == nodes.Iir_Kind.Simple_Name:
+ name = GetNameOfNode(node)
+ return ComponentInstantiationSymbol(node, name)
+ else:
+ 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/pyGHDL/dom/formatting/prettyprint.py b/pyGHDL/dom/formatting/prettyprint.py
index 0f548210b..da26372c4 100644
--- a/pyGHDL/dom/formatting/prettyprint.py
+++ b/pyGHDL/dom/formatting/prettyprint.py
@@ -114,15 +114,23 @@ class PrettyPrint:
# def __init__(self):
# self._buffer = []
+ def CleanupDocumentationBlocks(self, documentationContent: str, level: int = 0):
+ prefix = " " * level
+ if documentationContent is None:
+ return prefix
+
+ documentationLines = documentationContent.split("\n")
+ return f"{prefix}{documentationLines[0][2:].lstrip()}"
+
def formatDesign(self, design: Design, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
- buffer.append(f"{prefix}Libraries:")
+ buffer.append(f"{prefix}Libraries ({len(design.Libraries)}):")
for library in design.Libraries.values():
buffer.append(f"{prefix} - Name: {library.Identifier}")
for line in self.formatLibrary(library, level + 2):
buffer.append(line)
- buffer.append(f"{prefix}Documents:")
+ buffer.append(f"{prefix}Documents ({len(design.Documents)}):")
for document in design.Documents:
buffer.append(f"{prefix} - Path: '{document.Path}':")
for line in self.formatDocument(document, level + 2):
@@ -133,37 +141,33 @@ class PrettyPrint:
def formatLibrary(self, library: Library, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
- buffer.append(f"{prefix}Entities:")
- for entity in library.Entities:
- buffer.append(f"{prefix} - {entity.Identifier}({', '.join([a.Identifier for a in entity.Architectures])})")
- buffer.append(f"{prefix}Packages:")
- for package in library.Packages:
+ buffer.append(f"{prefix}Contexts ({len(library.Contexts)}):")
+ for context in library.Contexts.values():
+ buffer.append(f"{prefix} - {context.Identifier}")
+ buffer.append(f"{prefix}Packages ({len(library.Packages)}):")
+ for package in library.Packages.values():
if isinstance(package, Package):
buffer.append(f"{prefix} - {package.Identifier}")
elif isinstance(package, PackageInstantiation):
buffer.append(f"{prefix} - {package.Identifier} instantiate from {package.PackageReference}")
- buffer.append(f"{prefix}Configurations:")
- for configuration in library.Configurations:
+ buffer.append(f"{prefix}Entities ({len(library.Entities)}):")
+ for entity in library.Entities.values():
+ buffer.append(f"{prefix} - {entity.Identifier}({', '.join([a.Identifier for a in entity.Architectures])})")
+ buffer.append(f"{prefix}Configurations ({len(library.Configurations)}):")
+ for configuration in library.Configurations.values():
buffer.append(f"{prefix} - {configuration.Identifier}")
- buffer.append(f"{prefix}Contexts:")
- for context in library.Contexts:
- buffer.append(f"{prefix} - {context.Identifier}")
return buffer
def formatDocument(self, document: Document, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
- buffer.append(f"{prefix}Entities:")
- for entity in document.Entities:
- for line in self.formatEntity(entity, level + 1):
- buffer.append(line)
- buffer.append(f"{prefix}Architectures:")
- for architecture in document.Architectures:
- for line in self.formatArchitecture(architecture, level + 1):
+ buffer.append(f"{prefix}Contexts ({len(document.Contexts)}):")
+ for context in document.Contexts.values():
+ for line in self.formatContext(context, level + 1):
buffer.append(line)
- buffer.append(f"{prefix}Packages:")
- for package in document.Packages:
+ buffer.append(f"{prefix}Packages ({len(document.Packages)}):")
+ for package in document.Packages.values():
if isinstance(package, Package):
gen = self.formatPackage
else:
@@ -171,17 +175,22 @@ class PrettyPrint:
for line in gen(package, level + 1):
buffer.append(line)
- buffer.append(f"{prefix}PackageBodies:")
- for packageBodies in document.PackageBodies:
+ buffer.append(f"{prefix}PackageBodies ({len(document.PackageBodies)}):")
+ for packageBodies in document.PackageBodies.values():
for line in self.formatPackageBody(packageBodies, level + 1):
buffer.append(line)
- buffer.append(f"{prefix}Configurations:")
- for configuration in document.Configurations:
- for line in self.formatConfiguration(configuration, level + 1):
+ buffer.append(f"{prefix}Entities ({len(document.Entities)}):")
+ for entity in document.Entities.values():
+ for line in self.formatEntity(entity, level + 1):
buffer.append(line)
- buffer.append(f"{prefix}Contexts:")
- for context in document.Contexts:
- for line in self.formatContext(context, level + 1):
+ buffer.append(f"{prefix}Architectures ({len(document.Architectures)}):")
+ for architectures in document.Architectures.values():
+ for architecture in architectures.values():
+ for line in self.formatArchitecture(architecture, level + 1):
+ buffer.append(line)
+ buffer.append(f"{prefix}Configurations ({len(document.Configurations)}):")
+ for configuration in document.Configurations.values():
+ for line in self.formatConfiguration(configuration, level + 1):
buffer.append(line)
return buffer
@@ -189,10 +198,12 @@ class PrettyPrint:
def formatEntity(self, entity: Entity, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
+ documentationFirstLine = self.CleanupDocumentationBlocks(entity.Documentation)
buffer.append(
f"{prefix}- Name: {entity.Identifier}\n"
f"{prefix} File: {entity.Position.Filename.name}\n"
- f"{prefix} Position: {entity.Position.Line}:{entity.Position.Column}"
+ f"{prefix} Position: {entity.Position.Line}:{entity.Position.Column}\n"
+ f"{prefix} Documentation: {documentationFirstLine}"
)
buffer.append(f"{prefix} Generics:")
for generic in entity.GenericItems:
@@ -218,12 +229,14 @@ class PrettyPrint:
def formatArchitecture(self, architecture: Architecture, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
+ documentationFirstLine = self.CleanupDocumentationBlocks(architecture.Documentation)
buffer.append(
f"{prefix}- Name: {architecture.Identifier}\n"
f"{prefix} File: {architecture.Position.Filename.name}\n"
- f"{prefix} Position: {architecture.Position.Line}:{architecture.Position.Column}"
+ f"{prefix} Position: {architecture.Position.Line}:{architecture.Position.Column}\n"
+ f"{prefix} Documentation: {documentationFirstLine}"
)
- buffer.append(f"{prefix} Entity: {architecture.Entity.SymbolName}")
+ buffer.append(f"{prefix} Entity: {architecture.Entity.Identifier}")
buffer.append(f"{prefix} Declared:")
for item in architecture.DeclaredItems:
for line in self.formatDeclaredItems(item, level + 2):
@@ -243,6 +256,7 @@ class PrettyPrint:
def formatComponent(self, component: Component, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
+ documentationFirstLine = self.CleanupDocumentationBlocks(component.Documentation)
buffer.append(f"{prefix}- Component: {component.Identifier}")
buffer.append(f"{prefix} Generics:")
for generic in component.GenericItems:
@@ -258,10 +272,12 @@ class PrettyPrint:
def formatPackage(self, package: Package, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
+ documentationFirstLine = self.CleanupDocumentationBlocks(package.Documentation)
buffer.append(
f"{prefix}- Name: {package.Identifier}\n"
f"{prefix} File: {package.Position.Filename.name}\n"
- f"{prefix} Position: {package.Position.Line}:{package.Position.Column}"
+ f"{prefix} Position: {package.Position.Line}:{package.Position.Column}\n"
+ f"{prefix} Documentation: {documentationFirstLine}"
)
buffer.append(f"{prefix} Declared:")
for item in package.DeclaredItems:
@@ -273,6 +289,7 @@ class PrettyPrint:
def formatPackageInstance(self, package: PackageInstantiation, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
+ documentationFirstLine = self.CleanupDocumentationBlocks(package.Documentation)
buffer.append(f"{prefix}- Name: {package.Identifier}")
buffer.append(f"{prefix} Package: {package.PackageReference!s}")
buffer.append(f"{prefix} Generic Map: ...")
@@ -285,7 +302,8 @@ class PrettyPrint:
def formatPackageBody(self, packageBody: PackageBody, level: int = 0) -> StringBuffer:
buffer = []
prefix = " " * level
- buffer.append(f"{prefix}- Name: {packageBody.Identifier}")
+ documentationFirstLine = self.CleanupDocumentationBlocks(packageBody.Documentation)
+ buffer.append(f"{prefix}- Name: {packageBody.Identifier}\n{prefix} Documentation: {documentationFirstLine}")
buffer.append(f"{prefix} Declared:")
for item in packageBody.DeclaredItems:
for line in self.formatDeclaredItems(item, level + 1):
diff --git a/pyGHDL/dom/requirements.txt b/pyGHDL/dom/requirements.txt
index 6b540d7b7..90c229354 100644
--- a/pyGHDL/dom/requirements.txt
+++ b/pyGHDL/dom/requirements.txt
@@ -1,4 +1,4 @@
-r ../libghdl/requirements.txt
-pyVHDLModel==0.18.0
+pyVHDLModel==0.20.2
#https://github.com/VHDL/pyVHDLModel/archive/dev.zip#pyVHDLModel
diff --git a/testsuite/pyunit/dom/StopWatch.py b/testsuite/pyunit/dom/StopWatch.py
index 37b8293de..6301eb1df 100644
--- a/testsuite/pyunit/dom/StopWatch.py
+++ b/testsuite/pyunit/dom/StopWatch.py
@@ -34,7 +34,7 @@ from pathlib import Path
from unittest import TestCase
from pyGHDL.dom.NonStandard import Design, Document
-
+from pyGHDL.dom.formatting.prettyprint import PrettyPrint
if __name__ == "__main__":
print("ERROR: you called a testcase declaration file as an executable module.")
@@ -47,51 +47,59 @@ class Designs(TestCase):
_sourceDirectory: Path = _root / "dom/examples/StopWatch"
_packageFiles = (
- Path("Utilities.pkg.vhdl"),
- Path("StopWatch.pkg.vhdl"),
+ ("lib_Utilities", Path("Utilities.pkg.vhdl")),
+ ("lib_Utilities", Path("Utilities.ctx.vhdl")),
+ ("lib_StopWatch", Path("StopWatch.pkg.vhdl")),
+ ("lib_StopWatch", Path("StopWatch.ctx.vhdl")),
)
_encoderFiles = _packageFiles + (
- Path("seg7_Encoder.vhdl"),
- Path("toplevel.Encoder.vhdl"),
+ ("lib_StopWatch", Path("seg7_Encoder.vhdl")),
+ ("lib_StopWatch", Path("toplevel.Encoder.vhdl")),
)
_displayFiles = _packageFiles + (
- Path("Counter.vhdl"),
- Path("seg7_Encoder.vhdl"),
- Path("seg7_Display.vhdl"),
- Path("toplevel.Display.vhdl"),
+ ("lib_StopWatch", Path("Counter.vhdl")),
+ ("lib_StopWatch", Path("seg7_Encoder.vhdl")),
+ ("lib_StopWatch", Path("seg7_Display.vhdl")),
+ ("lib_StopWatch", Path("seg7_Display.cfg.vhdl")),
+ ("lib_StopWatch", Path("toplevel.Display.vhdl")),
)
_stopwatchFiles = _packageFiles + (
- Path("Counter.vhdl"),
- Path("seg7_Encoder.vhdl"),
- Path("seg7_Display.vhdl"),
- Path("StopWatch.vhdl"),
- Path("Debouncer.vhdl"),
- Path("toplevel.StopWatch.vhdl"),
+ ("lib_Utilities", Path("Counter.vhdl")),
+ ("lib_StopWatch", Path("seg7_Encoder.vhdl")),
+ ("lib_StopWatch", Path("seg7_Display.vhdl")),
+ ("lib_StopWatch", Path("seg7_Display.cfg.vhdl")),
+ ("lib_StopWatch", Path("StopWatch.vhdl")),
+ ("lib_Utilities", Path("sync_Bits.vhdl")),
+ ("lib_Utilities", Path("Debouncer.vhdl")),
+ ("lib_StopWatch", Path("toplevel.StopWatch.vhdl")),
)
class Display(Designs):
def test_Encoder(self):
design = Design()
- for file in self._encoderFiles:
+ for lib, file in self._encoderFiles:
+ library = design.GetLibrary(lib)
document = Document(self._sourceDirectory / file)
- design.Documents.append(document)
+ design.AddDocument(document, library)
self.assertEqual(len(self._encoderFiles), len(design.Documents))
def test_Display(self):
design = Design()
- for file in self._displayFiles:
+ for lib, file in self._displayFiles:
+ library = design.GetLibrary(lib)
document = Document(self._sourceDirectory / file)
- design.Documents.append(document)
+ design.AddDocument(document, library)
self.assertEqual(len(self._displayFiles), len(design.Documents))
def test_StopWatch(self):
design = Design()
- for file in self._stopwatchFiles:
+ for lib, file in self._stopwatchFiles:
+ library = design.GetLibrary(lib)
document = Document(self._sourceDirectory / file)
- design.Documents.append(document)
+ design.AddDocument(document, library)
self.assertEqual(len(self._stopwatchFiles), len(design.Documents))
@@ -101,9 +109,16 @@ class CompileOrder(Designs):
design = Design()
design.LoadStdLibrary()
design.LoadIEEELibrary()
- library = design.GetLibrary("lib_StopWatch")
- for file in self._encoderFiles:
+ for lib, file in self._encoderFiles:
+ library = design.GetLibrary(lib)
document = Document(self._sourceDirectory / file)
design.AddDocument(document, library)
design.Analyze()
+
+ PP = PrettyPrint()
+ buffer = []
+ buffer.append("Design:")
+ for line in PP.formatDesign(design, 1):
+ buffer.append(line)
+ print("\n".join(buffer))
diff --git a/testsuite/pyunit/dom/VHDLLibraries.py b/testsuite/pyunit/dom/VHDLLibraries.py
index 9de39b81b..c8a39ed23 100644
--- a/testsuite/pyunit/dom/VHDLLibraries.py
+++ b/testsuite/pyunit/dom/VHDLLibraries.py
@@ -85,7 +85,7 @@ def test_Synopsys(file):
@mark.xfail(reason="Needs further investigations.")
@mark.parametrize("file", [str(f.relative_to(_VITAL_ROOT)) for f in _VITAL_ROOT.glob("*.vhdl")])
-def test_Synopsys(file):
+def test_Vital(file):
filePath = _VITAL_ROOT / file
lib = design.GetLibrary("vital")
diff --git a/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl
index 3ef284b98..b26a0fa09 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/Counter.vhdl
@@ -7,7 +7,7 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+use work.Utilities_pkg.all;
entity Counter is
diff --git a/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl
index 18207c7f1..ef1474164 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/Debouncer.vhdl
@@ -7,7 +7,7 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+use work.Utilities_pkg.all;
entity Debouncer is
@@ -15,7 +15,8 @@ entity Debouncer is
CLOCK_PERIOD : time := 10 ns;
DEBOUNCE_TIME : time := 3 ms;
- BITS : positive
+ BITS : positive;
+ INPUT_SYNC : boolean := true
);
port (
Clock : in std_logic;
@@ -29,12 +30,27 @@ architecture rtl of Debouncer is
constant DEBOUNCE_COUNTER_MAX : positive := DEBOUNCE_TIME / (CLOCK_PERIOD* ite(IS_SIMULATION, 20, 1));
constant DEBOUNCE_COUNTER_BITS : positive := log2(DEBOUNCE_COUNTER_MAX);
+ signal Input_sync : Input'subtype;
begin
assert false report "CLOCK_PERIOD: " & time'image(CLOCK_PERIOD);
assert false report "DEBOUNCE_TIME: " & time'image(DEBOUNCE_TIME);
--assert false report "DEBOUNCE_COUNTER_MAX: " & to_string(10 ns);
--assert false report "INTEGER'high: " & integer'image(integer'high);
+ genSync: if INPUT_SYNC generate
+ sync: entity work.sync_Bits
+ generic map (
+ BITS => BITS
+ )
+ port map (
+ Clock => Clock,
+ Input => Input,
+ Output => Input_sync
+ );
+ else generate
+ Input_sync <= Input;
+ end generate;
+
genBits: for i in Input'range generate
signal DebounceCounter : signed(DEBOUNCE_COUNTER_BITS downto 0) := to_signed(DEBOUNCE_COUNTER_MAX - 3, DEBOUNCE_COUNTER_BITS + 1);
begin
diff --git a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.ctx.vhdl b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.ctx.vhdl
new file mode 100644
index 000000000..dc89d5b3b
--- /dev/null
+++ b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.ctx.vhdl
@@ -0,0 +1,11 @@
+-- Author: Patrick Lehmann
+-- License: MIT
+--
+-- undocumented
+--
+context StopWatch_ctx is
+ library lib_Utilities;
+ context lib_Utilities.Utilities_ctx;
+
+ use work.StopWatch_pkg.all;
+end context;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl
index 3bcafdd6d..f67f99c72 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.pkg.vhdl
@@ -7,7 +7,7 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-
+-- Package with stop watch specific types.
package StopWatch_pkg is
subtype T_BCD is unsigned(3 downto 0);
type T_BCD_Vector is array(natural range <>) of T_BCD;
@@ -18,4 +18,16 @@ package StopWatch_pkg is
end record;
type T_STOPWATCH_CONFIGURATION is array(natural range <>) of T_DIGIT_CONFIGURATION;
+
+ -- Encoder that translates from 4-bit binary (BCD) to 7-segment code.
+ --
+ -- In addition, an optional dot input is supported.
+ component seg7_Encoder is
+ port (
+ BCDValue : in T_BCD;
+ Dot : in std_logic := '0';
+
+ Seg7Code : out std_logic_vector(7 downto 0)
+ );
+ end component;
end package;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl
index c7c9068ab..3d73fa0fa 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/StopWatch.vhdl
@@ -7,7 +7,9 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
use work.StopWatch_pkg.all;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/Utilities.ctx.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Utilities.ctx.vhdl
new file mode 100644
index 000000000..050682098
--- /dev/null
+++ b/testsuite/pyunit/dom/examples/StopWatch/Utilities.ctx.vhdl
@@ -0,0 +1,12 @@
+-- Author: Patrick Lehmann
+-- License: MIT
+--
+-- undocumented
+--
+context Utilities_ctx is
+ library IEEE;
+ use IEEE.std_logic_1164.all,
+ IEEE.numeric_std.all;
+
+ use work.Utilities_pkg.all;
+end context;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl b/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl
index 8daf39614..6231261c0 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/Utilities.pkg.vhdl
@@ -8,7 +8,8 @@ use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-package Utilities is
+-- Useful utility functions and types.
+package Utilities_pkg is
type freq is range integer'low to integer'high units
Hz;
kHz = 1000 Hz;
@@ -29,10 +30,25 @@ package Utilities is
function to_index(value : unsigned; max : positive) return natural;
function to_index(value : natural; max : positive) return natural;
+
+ component Debouncer is
+ generic (
+ CLOCK_PERIOD : time := 10 ns;
+ DEBOUNCE_TIME : time := 3 ms;
+
+ BITS : positive
+ );
+ port (
+ Clock : in std_logic;
+
+ Input : in std_logic_vector(BITS - 1 downto 0);
+ Output : out std_logic_vector(BITS - 1 downto 0) := (others => '0')
+ );
+ end component;
end package;
-package body Utilities is
+package body Utilities_pkg is
function simulation return boolean is
variable result : boolean := FALSE;
begin
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..63d0c5e60
--- /dev/null
+++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.cfg.vhdl
@@ -0,0 +1,16 @@
+-- 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.
+configuration seg7_Display_cfg of seg7_Display is
+ for rtl
+ for enc : seg7_Encoder
+ use entity work.seg7_Encoder(rtl);
+ end for;
+ end for;
+end configuration;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl
index c3771ba68..da21075cf 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Display.vhdl
@@ -7,7 +7,9 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
use work.StopWatch_pkg.all;
@@ -77,7 +79,7 @@ begin
Dot <= DotValues(to_index(Digit_Select, DotValues'high));
-- 7-segment encoder
- enc: entity work.seg7_Encoder
+ enc: configuration seg7_Encoder
port map (
BCDValue => Digit,
Dot => Dot,
diff --git a/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl b/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl
index e4c731ff9..88074c884 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/seg7_Encoder.vhdl
@@ -3,14 +3,10 @@
--
-- A generic counter module used in the StopWatch example.
--
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.numeric_std.all;
-
-use work.Utilities.all;
-use work.StopWatch_pkg.all;
+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;
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..499305ec7
--- /dev/null
+++ b/testsuite/pyunit/dom/examples/StopWatch/sync_Bits.vhdl
@@ -0,0 +1,37 @@
+-- Author: Patrick Lehmann
+-- License: MIT
+--
+-- A generic multi-FF synchronizer.
+--
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+-- Multi-stage FF synchronizer
+entity sync_Bits is
+ generic (
+ BITS : positive := 1;
+ STAGES : positive range 2 to 5 := 3
+ );
+ port (
+ Clock : in std_logic;
+
+ Input : in std_logic_vector(BITS - 1 downto 0);
+ output : in std_logic_vector(BITS - 1 downto 0)
+ );
+end entity;
+
+
+architecture rtl of sync_Bits is
+
+begin
+ gen : for i in Input'range generate
+ signal meta : std_logic := '0';
+ signal ffs : std_logic_vector(STAGES - 1 downto 1) := (others => '0');
+ begin
+ meta <= Input(i) when rising_edge(Clock);
+ ffs <= (ffs(ffs'left downto 1) & meta) when rising_edge(Clock);
+
+ Output(i) <= ffs(ffs'left);
+ end generate;
+end architecture;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl
index 67228a5ac..648ab81e4 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Display.vhdl
@@ -7,7 +7,9 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
use work.StopWatch_pkg.all;
diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl
index 7775a6eb6..17f7c6b19 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.Encoder.vhdl
@@ -7,10 +7,13 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
use work.StopWatch_pkg.all;
+-- Toplevel module to demonstrate the translation of 4 slide-switches to 1 digit 7-segment display.
entity toplevel is
port (
NexysA7_GPIO_Switch : in std_logic_vector(3 downto 0);
diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl
index a334475c4..87cd75829 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.tb.vhdl
@@ -7,9 +7,10 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-library lib_StopWatch;
-use lib_StopWatch.Utilities.all;
-use lib_StopWatch.StopWatch_pkg.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
+use work.StopWatch_pkg.all;
entity toplevel_tb is
diff --git a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl
index 1c8547446..08046e2cc 100644
--- a/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl
+++ b/testsuite/pyunit/dom/examples/StopWatch/toplevel.StopWatch.vhdl
@@ -7,7 +7,9 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.Utilities.all;
+library lib_Utilities;
+use lib_Utilities.Utilities_pkg.all;
+
use work.StopWatch_pkg.all;
@@ -57,7 +59,7 @@ begin
Board_Reset <= not NexysA7_GPIO_Button_Reset_n;
-- Debounce input signals
- deb: entity work.Debouncer
+ deb: component Debouncer
generic map (
CLOCK_PERIOD => CLOCK_PERIOD,
BITS => 2
@@ -98,7 +100,7 @@ begin
);
-- 7-segment display
- display: entity work.seg7_Display
+ display: configuration seg7_Display_cfg
generic map (
CLOCK_PERIOD => CLOCK_PERIOD,
DIGITS => Digits'length